Rift.IO OSM R1 Initial Submission 87/287/1
authorJeremy Mordkoff <jeremy.mordkoff@riftio.com>
Wed, 7 Sep 2016 22:59:17 +0000 (18:59 -0400)
committerJeremy Mordkoff <jeremy.mordkoff@riftio.com>
Wed, 7 Sep 2016 22:59:17 +0000 (18:59 -0400)
Signed-off-by: Jeremy Mordkoff <jeremy.mordkoff@riftio.com>
828 files changed:
.gitignore [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
Makefile [new file with mode: 0644]
foss.txt [new file with mode: 0644]
manifest/LICENSE [new file with mode: 0644]
skyquake/.babelrc [new file with mode: 0644]
skyquake/.gitignore [new file with mode: 0644]
skyquake/.storybook/config.js [new file with mode: 0644]
skyquake/.storybook/webpack.config.js [new file with mode: 0644]
skyquake/CMakeLists.txt [new file with mode: 0644]
skyquake/__tests__/skyquakeRouter_test.js [new file with mode: 0644]
skyquake/framework/core/api_utils/constants.js [new file with mode: 0644]
skyquake/framework/core/api_utils/sockets.js [new file with mode: 0644]
skyquake/framework/core/api_utils/utils.js [new file with mode: 0644]
skyquake/framework/core/modules/api/configuration.js [new file with mode: 0644]
skyquake/framework/core/modules/api/descriptorModelMetaAPI.js [new file with mode: 0644]
skyquake/framework/core/modules/api/navigation.js [new file with mode: 0644]
skyquake/framework/core/modules/api/restconf.js [new file with mode: 0644]
skyquake/framework/core/modules/navigation_manager.js [new file with mode: 0644]
skyquake/framework/core/modules/plugin_discoverer.js [new file with mode: 0644]
skyquake/framework/core/modules/routes/configuration.js [new file with mode: 0644]
skyquake/framework/core/modules/routes/descriptorModel.js [new file with mode: 0644]
skyquake/framework/core/modules/routes/inactivity.js [new file with mode: 0644]
skyquake/framework/core/modules/routes/navigation.js [new file with mode: 0644]
skyquake/framework/core/modules/routes/restconf.js [new file with mode: 0644]
skyquake/framework/core/modules/routes/sockets.js [new file with mode: 0644]
skyquake/framework/core/modules/skyquakeEmitter.js [new file with mode: 0644]
skyquake/framework/js/gauge-modified.js [new file with mode: 0644]
skyquake/framework/js/n3-line-chart.js [new file with mode: 0644]
skyquake/framework/style/_colors.scss [new file with mode: 0644]
skyquake/framework/style/base.scss [new file with mode: 0644]
skyquake/framework/style/common.scss [new file with mode: 0644]
skyquake/framework/style/core.css [new file with mode: 0644]
skyquake/framework/style/fonts/Roboto-Light-webfont.ttf [new file with mode: 0755]
skyquake/framework/style/fonts/Roboto-Regular-webfont.eot [new file with mode: 0755]
skyquake/framework/style/fonts/Roboto-Regular-webfont.svg [new file with mode: 0755]
skyquake/framework/style/fonts/Roboto-Regular-webfont.ttf [new file with mode: 0755]
skyquake/framework/style/fonts/Roboto-Regular-webfont.woff [new file with mode: 0755]
skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.eot [new file with mode: 0755]
skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.svg [new file with mode: 0755]
skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.ttf [new file with mode: 0755]
skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-Black.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-BlackIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-Bold.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-BoldIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-ExtraLight.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-ExtraLightIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-It.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-Light.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-LightIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-Medium.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-MediumIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-Regular.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-Semibold.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceCodePro-SemiboldIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-Black.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-BlackIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-Bold.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-BoldIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-ExtraLight.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-ExtraLightIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-It.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-Light.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-LightIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-Regular.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-Semibold.otf.woff [new file with mode: 0755]
skyquake/framework/style/fonts/SourceSansPro-SemiboldIt.otf.woff [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-action-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-alert-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-av-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-communication-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-content-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-device.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-editor-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-file-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-hardware-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-image-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-maps-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-navigation-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-notification-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-places-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-social-symbol.svg [new file with mode: 0755]
skyquake/framework/style/icons/svg-sprite-toggle-symbol.svg [new file with mode: 0755]
skyquake/framework/style/img/avatar.png [new file with mode: 0644]
skyquake/framework/style/img/bargraph.png [new file with mode: 0644]
skyquake/framework/style/img/bearer-plane-diagram.png [new file with mode: 0644]
skyquake/framework/style/img/bg-tile-cross-small.png [new file with mode: 0644]
skyquake/framework/style/img/catalog-default.svg [new file with mode: 0644]
skyquake/framework/style/img/catalog-nsd-default.svg [new file with mode: 0644]
skyquake/framework/style/img/catalog-vnfd-default.svg [new file with mode: 0644]
skyquake/framework/style/img/create-account.png [new file with mode: 0644]
skyquake/framework/style/img/create-fleet-params-temp.png [new file with mode: 0644]
skyquake/framework/style/img/create-fleet-pool-temp.png [new file with mode: 0644]
skyquake/framework/style/img/create-fleet-services-temp.png [new file with mode: 0644]
skyquake/framework/style/img/diameter-openflow-lte-icon.png [new file with mode: 0644]
skyquake/framework/style/img/firewall-icon.png [new file with mode: 0644]
skyquake/framework/style/img/gbps-10.png [new file with mode: 0644]
skyquake/framework/style/img/gbps-50.png [new file with mode: 0644]
skyquake/framework/style/img/green-page-icon.png [new file with mode: 0644]
skyquake/framework/style/img/header-logo.png [new file with mode: 0644]
skyquake/framework/style/img/host-icon.png [new file with mode: 0644]
skyquake/framework/style/img/icon-host-sm.png [new file with mode: 0644]
skyquake/framework/style/img/icon-host.png [new file with mode: 0644]
skyquake/framework/style/img/icon-open-viewport.png [new file with mode: 0644]
skyquake/framework/style/img/icon-switch.png [new file with mode: 0644]
skyquake/framework/style/img/iot-industry-icon.png [new file with mode: 0644]
skyquake/framework/style/img/iot-medical-icon.png [new file with mode: 0644]
skyquake/framework/style/img/iot-transportation-icon-active.png [new file with mode: 0644]
skyquake/framework/style/img/ip-lte-icon.png [new file with mode: 0644]
skyquake/framework/style/img/ip-softgre-icon.png [new file with mode: 0644]
skyquake/framework/style/img/latency.png [new file with mode: 0644]
skyquake/framework/style/img/latency_graph.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-add-fleet-icon.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graph-temp.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/10.09.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/17.23.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/20.05.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/23.08.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/25.03.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/30.56.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/7.08.png [new file with mode: 0644]
skyquake/framework/style/img/launchpad-graphs-temp/9.24.png [new file with mode: 0644]
skyquake/framework/style/img/link.png [new file with mode: 0644]
skyquake/framework/style/img/loadbalance-icon.png [new file with mode: 0644]
skyquake/framework/style/img/lte-mme-icon.png [new file with mode: 0644]
skyquake/framework/style/img/osm_header.png [new file with mode: 0644]
skyquake/framework/style/img/osm_header_253x50.png [new file with mode: 0644]
skyquake/framework/style/img/osm_header_506x100.png [new file with mode: 0644]
skyquake/framework/style/img/page_loader.gif [new file with mode: 0644]
skyquake/framework/style/img/platform-nav-temp.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-resources.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-traffic.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-resources.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-traffic.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-resources.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-traffic.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-resources.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-traffic.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-resources.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-traffic.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-resources.png [new file with mode: 0644]
skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-traffic.png [new file with mode: 0644]
skyquake/framework/style/img/router-icon.png [new file with mode: 0644]
skyquake/framework/style/img/so-pages-temp/ipTrafTemp.png [new file with mode: 0644]
skyquake/framework/style/img/so-pages-temp/securityTemp.png [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-icn-close.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-icn-edit.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-network-01-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-01-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-02-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-02-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-03-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-03-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-04-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-04-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-05-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-05-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-06-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-06-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-07-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-07-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-08-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-08-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-09-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-09-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-10-active.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-10-inactive.svg [new file with mode: 0755]
skyquake/framework/style/img/svg/launch-fleet-network-11-active.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-network-11-inactive.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-pool-01-active.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-pool-01-inactive.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-pool-02-active.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launch-fleet-pool-02-inactive.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launchpad-icn-create-environment-large.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launchpad-icn-newTab.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launchpad-icn-play.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/launchpad-icn-sliders.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/riftio_logo.svg [new file with mode: 0644]
skyquake/framework/style/img/svg/riftio_logo_white.svg [new file with mode: 0644]
skyquake/framework/style/img/switch-icon.png [new file with mode: 0644]
skyquake/framework/style/img/table-cell-bg.png [new file with mode: 0644]
skyquake/framework/style/img/traffic-sim-diagram.png [new file with mode: 0644]
skyquake/framework/style/img/tunnels.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-dash-temp.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-dash-v2-temp.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-dash-v3-temp.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-nav-bottom.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-nav-center.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-nav-left.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-nav-right.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-nav-top.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-platform-temp.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-sla-graph.svg [new file with mode: 0644]
skyquake/framework/style/img/viewport-vim-temp.png [new file with mode: 0644]
skyquake/framework/style/img/viewport-vnf-10.svg [new file with mode: 0644]
skyquake/framework/style/img/viewport-vnf-50.svg [new file with mode: 0644]
skyquake/framework/style/img/viewport-vnf-temp.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-corners.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-diamond.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-halfcircle-bottom.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-halfcircle-top.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-plus.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-soliddiamond.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-solidsquare.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-solidstar.png [new file with mode: 0644]
skyquake/framework/style/img/vim-icon-triangle.png [new file with mode: 0644]
skyquake/framework/style/layout.scss [new file with mode: 0644]
skyquake/framework/style/variables.scss [new file with mode: 0644]
skyquake/framework/style/vendor/css-reset-2.0/css-reset.css [new file with mode: 0644]
skyquake/framework/utils/guid.js [new file with mode: 0644]
skyquake/framework/utils/rw.js [new file with mode: 0644]
skyquake/framework/utils/utils.js [new file with mode: 0644]
skyquake/framework/widgets/JSONViewer/JSONViewer.js [new file with mode: 0644]
skyquake/framework/widgets/JSONViewer/JSONViewer.scss [new file with mode: 0644]
skyquake/framework/widgets/bullet/bullet.js [new file with mode: 0644]
skyquake/framework/widgets/button/button.scss [new file with mode: 0644]
skyquake/framework/widgets/button/rw.button.js [new file with mode: 0644]
skyquake/framework/widgets/button/sq-button.jsx [new file with mode: 0644]
skyquake/framework/widgets/components.js [new file with mode: 0644]
skyquake/framework/widgets/dashboard_card/dashboardCardHeader.jsx [new file with mode: 0644]
skyquake/framework/widgets/dashboard_card/dashboard_card.jsx [new file with mode: 0644]
skyquake/framework/widgets/dashboard_card/dashboard_card.scss [new file with mode: 0644]
skyquake/framework/widgets/filter/filter.jsx [new file with mode: 0644]
skyquake/framework/widgets/form_controls/formControls.scss [new file with mode: 0644]
skyquake/framework/widgets/form_controls/selectOption.jsx [new file with mode: 0644]
skyquake/framework/widgets/form_controls/textInput.jsx [new file with mode: 0644]
skyquake/framework/widgets/gauge/gauge.js [new file with mode: 0644]
skyquake/framework/widgets/header/header.jsx [new file with mode: 0644]
skyquake/framework/widgets/header/header.scss [new file with mode: 0644]
skyquake/framework/widgets/header/headerActions.js [new file with mode: 0644]
skyquake/framework/widgets/header/headerStore.js [new file with mode: 0644]
skyquake/framework/widgets/input-range-slider/input-range-slider.jsx [new file with mode: 0644]
skyquake/framework/widgets/input-range-slider/input-range-slider.scss [new file with mode: 0644]
skyquake/framework/widgets/input-range-slider/react-rangeslider.jsx [new file with mode: 0644]
skyquake/framework/widgets/listy/listy.js [new file with mode: 0644]
skyquake/framework/widgets/loading-indicator/loading-indicator-animations.scss [new file with mode: 0644]
skyquake/framework/widgets/loading-indicator/loadingIndicator.jsx [new file with mode: 0644]
skyquake/framework/widgets/login/login.js [new file with mode: 0644]
skyquake/framework/widgets/login/login.jsx [new file with mode: 0644]
skyquake/framework/widgets/login/login.scss [new file with mode: 0644]
skyquake/framework/widgets/login/loginAuthActions.js [new file with mode: 0644]
skyquake/framework/widgets/login/main.js [new file with mode: 0644]
skyquake/framework/widgets/metric-bars/metricBarGroup.jsx [new file with mode: 0644]
skyquake/framework/widgets/metric-bars/metricBarGroup.scss [new file with mode: 0644]
skyquake/framework/widgets/mixins/ButtonEventListener.js [new file with mode: 0644]
skyquake/framework/widgets/multicomponent/multicomponent.js [new file with mode: 0644]
skyquake/framework/widgets/nfvi-metric-bars/nfviMetricBars.jsx [new file with mode: 0644]
skyquake/framework/widgets/nfvi-metric-bars/nfviMetricBars.scss [new file with mode: 0644]
skyquake/framework/widgets/operational-status/launchpadOperationalStatus.jsx [new file with mode: 0644]
skyquake/framework/widgets/panel/panel.jsx [new file with mode: 0644]
skyquake/framework/widgets/panel/panel.scss [new file with mode: 0644]
skyquake/framework/widgets/radio-button/rw.radio-button.js [new file with mode: 0644]
skyquake/framework/widgets/screen-loader/screenLoader.jsx [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/eventCenter.jsx [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/eventCenter.scss [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeAltInstance.js [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeApp.scss [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeComponent.jsx [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx [new file with mode: 0644]
skyquake/framework/widgets/skyquake_container/skyquakeRouter.jsx [new file with mode: 0644]
skyquake/framework/widgets/sq-input-range-slider/sq-input-range-slider.jsx [new file with mode: 0644]
skyquake/framework/widgets/sq-input-range-slider/sq-input-range-slider.scss [new file with mode: 0644]
skyquake/framework/widgets/text-area/rw.text-area.js [new file with mode: 0644]
skyquake/framework/widgets/text-input/check-box/rw.check-box.js [new file with mode: 0644]
skyquake/framework/widgets/text-input/check-box/rw.check-box2.js [new file with mode: 0644]
skyquake/framework/widgets/text-input/rw.text-input.js [new file with mode: 0644]
skyquake/framework/widgets/topology/topologyL2Graph.jsx [new file with mode: 0644]
skyquake/framework/widgets/topology/topologyTree.jsx [new file with mode: 0644]
skyquake/framework/widgets/topology/topologyTree.scss [new file with mode: 0644]
skyquake/framework/widgets/transmit-receive/transmit-receive.js [new file with mode: 0644]
skyquake/framework/widgets/transmit-receive/transmit-receive.jsx [new file with mode: 0644]
skyquake/framework/widgets/transmit-receive/transmit-receive.scss [new file with mode: 0644]
skyquake/framework/widgets/uptime/uptime.jsx [new file with mode: 0644]
skyquake/installed_plugins.txt [new file with mode: 0644]
skyquake/package.json [new file with mode: 0644]
skyquake/plugins/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/about/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/about/api/about.js [new file with mode: 0644]
skyquake/plugins/about/config.json [new file with mode: 0644]
skyquake/plugins/about/package.json [new file with mode: 0644]
skyquake/plugins/about/routes.js [new file with mode: 0644]
skyquake/plugins/about/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/about/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/about/server.js [new file with mode: 0644]
skyquake/plugins/about/src/about.jsx [new file with mode: 0644]
skyquake/plugins/about/src/about.scss [new file with mode: 0644]
skyquake/plugins/about/src/aboutActions.js [new file with mode: 0644]
skyquake/plugins/about/src/aboutSource.js [new file with mode: 0644]
skyquake/plugins/about/src/aboutStore.js [new file with mode: 0644]
skyquake/plugins/about/src/main.js [new file with mode: 0644]
skyquake/plugins/about/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/accounts/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/accounts/api/accounts.js [new file with mode: 0644]
skyquake/plugins/accounts/api/cloud_account/cloudAccount.js [new file with mode: 0644]
skyquake/plugins/accounts/api/config_agent/configAgent.js [new file with mode: 0644]
skyquake/plugins/accounts/api/sdn_account/sdnAccount.js [new file with mode: 0644]
skyquake/plugins/accounts/config.json [new file with mode: 0644]
skyquake/plugins/accounts/images/OpenDaylight_logo.png [new file with mode: 0644]
skyquake/plugins/accounts/images/aws.png [new file with mode: 0644]
skyquake/plugins/accounts/images/juju.svg [new file with mode: 0644]
skyquake/plugins/accounts/images/openmano.png [new file with mode: 0644]
skyquake/plugins/accounts/images/openstack-horizontal.png [new file with mode: 0644]
skyquake/plugins/accounts/images/openstack.png [new file with mode: 0644]
skyquake/plugins/accounts/images/riftio.png [new file with mode: 0644]
skyquake/plugins/accounts/package.json [new file with mode: 0644]
skyquake/plugins/accounts/routes.js [new file with mode: 0644]
skyquake/plugins/accounts/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/accounts/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/accounts/server.js [new file with mode: 0644]
skyquake/plugins/accounts/src/account/account.jsx [new file with mode: 0644]
skyquake/plugins/accounts/src/account/account.scss [new file with mode: 0644]
skyquake/plugins/accounts/src/account/accountActions.js [new file with mode: 0644]
skyquake/plugins/accounts/src/account/accountSource.js [new file with mode: 0644]
skyquake/plugins/accounts/src/account/accountStore.js [new file with mode: 0644]
skyquake/plugins/accounts/src/account/accountsDashboard.jsx [new file with mode: 0644]
skyquake/plugins/accounts/src/account_sidebar/accountSidebar.jsx [new file with mode: 0644]
skyquake/plugins/accounts/src/account_sidebar/accountSidebar.scss [new file with mode: 0644]
skyquake/plugins/accounts/src/main.js [new file with mode: 0644]
skyquake/plugins/accounts/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/composer/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/composer/Gruntfile.js [new file with mode: 0644]
skyquake/plugins/composer/README.md [new file with mode: 0644]
skyquake/plugins/composer/api/composer.js [new file with mode: 0644]
skyquake/plugins/composer/codeStyleSettings.xml [new file with mode: 0644]
skyquake/plugins/composer/config.json [new file with mode: 0644]
skyquake/plugins/composer/karma.conf.js [new file with mode: 0644]
skyquake/plugins/composer/license-flat-icon.pdf [new file with mode: 0755]
skyquake/plugins/composer/license-info.txt [new file with mode: 0644]
skyquake/plugins/composer/main.js.map [new file with mode: 0644]
skyquake/plugins/composer/package.json [new file with mode: 0644]
skyquake/plugins/composer/routes.js [new file with mode: 0644]
skyquake/plugins/composer/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/composer/scripts/build.sh.old [new file with mode: 0755]
skyquake/plugins/composer/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/composer/scripts/launch_composer.sh [new file with mode: 0755]
skyquake/plugins/composer/scripts/server_composer_ui.py [new file with mode: 0755]
skyquake/plugins/composer/scripts/update-node-modules.sh [new file with mode: 0755]
skyquake/plugins/composer/src/index.js [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/README.md [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/confd2model.js [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/generate-model-meta-json.sh [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/ietf-inet-types.yang.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/ietf-inet-types.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/json-nsd.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/json-vnfd.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/mano-base.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/mano-types.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/model-meta.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/nsd.yang.src [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/nsr.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/pnfd.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-nsd.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-nsr.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-pb-ext.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-topology.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-vld.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-vlr.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-vnfd.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-vnfr.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw-yang-types.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/rw.nsd-yang.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/rw.vld-yang.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/rw.vnfd-yang.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/rw.vnffgd-yang.json [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/rwvcs-types.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/src-append.sh [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/src-remove.sh [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/vld.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/vlr.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/vnfd.yang.src [new file with mode: 0644]
skyquake/plugins/composer/src/schemas/yang/vnffgd.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/vnfr.yang.src [new file with mode: 0755]
skyquake/plugins/composer/src/schemas/yang/yang2json.sh [new file with mode: 0755]
skyquake/plugins/composer/src/src/README.md [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CanvasEditorActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CanvasPanelTrayActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CatalogDataSourceActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CatalogFilterActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CatalogItemsActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CatalogPackageManagerActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/CatalogPanelTrayActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/ComposerAppActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/ModalOverlayActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/PanelResizeAction.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/actions/RiftHeaderActions.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/alt.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/Roboto-Black-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-BlackItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-Bold-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-BoldItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-Italic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-Light-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-LightItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-Medium-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-MediumItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-Regular-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-Thin-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/Roboto-ThinItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/RobotoCondensed-Bold-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/RobotoCondensed-BoldItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/RobotoCondensed-Italic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/RobotoCondensed-Light-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/RobotoCondensed-LightItalic-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/RobotoCondensed-Regular-webfont.woff [new file with mode: 0755]
skyquake/plugins/composer/src/src/assets/big-honking-catalog.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/empty-nsd-catalog.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/android-chrome-144x144.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/android-chrome-192x192.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/android-chrome-36x36.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/android-chrome-48x48.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/android-chrome-72x72.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/android-chrome-96x96.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-114x114.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-120x120.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-144x144.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-152x152.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-180x180.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-57x57.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-60x60.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-72x72.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-76x76.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-precomposed.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/browserconfig.xml [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/favicon-16x16.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/favicon-194x194.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/favicon-32x32.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/favicon-96x96.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/favicon.ico [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/manifest.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/mstile-144x144.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/mstile-150x150.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/mstile-310x150.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/mstile-310x310.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/mstile-70x70.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/favicons/safari-pinned-tab.svg [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/juju-catalog.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/onvelocity-color-theme.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/ping-pong-catalog.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/ping-vrouter-pong-catalog.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/assets/rift.ware-color-theme.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/Button.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CanvasPanel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CanvasPanelTray.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CanvasZoom.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogFilter.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogItemCanvasEditor.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogItemDetailsEditor.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogItems.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogPackageManager.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogPanel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogPanelToolbar.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/CatalogPanelTray.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/ComposerApp.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/ComposerAppToolbar.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/ContentEditableDiv.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/DetailsPanel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/DropTarget.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/DropZonePanel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/ConnectionPointSelector.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/EditForwardingGraphPaths.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/EditableProperty.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapClassifier.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapRecordServicePath.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onClickSelectAndShowInDetailsPanel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onCutDelegateToRemove.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onFormInputChangedModifyContainerAndNotify.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onHoverHighlightConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/ExportSelectorDialog.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/LayoutRow.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/LoadingIndicator.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/ModalOverlay.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/PopupWindow.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/Range.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/RiftHeader.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/components/messages.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/favicon.ico [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/default-catalog-icon.svg [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/default-icon-white.svg [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/default-icon.svg [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/header-logo.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/logos/riftio.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/osm_header_253x50.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/osm_header_506x100.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/riftio_website_logo_002_03.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/sample-catalog.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/images/vendor-riftio.png [new file with mode: 0644]
skyquake/plugins/composer/src/src/index.html [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/CatalogPackageManagerUploadDropZone.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/ColorGroups.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/DeletionManager.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/InstanceCounter.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/ResizableManager.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/SelectionManager.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/ToggleElementHandler.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/TooltipManager.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/UniqueId.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/getEventPath.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraph.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphGrid.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphPathBuilder.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphSelection.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphConnectionPointNumber.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphConstituentVnfd.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphDescriptorModel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphForwardingGraph.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphInternalVirtualLink.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphInternalVirtualLinkPaths.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphNetworkService.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphRecordServicePath.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualDeploymentUnit.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualLink.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualLinkPaths.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualNetworkFunction.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/HighlightRecordServicePaths.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/PathBuilder.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/Position.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/layouts/RelationsAndNetworksLayout.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/graph/math.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/guid.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/isFullScreen.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModel.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFactory.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFields.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMeta.json [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaFactory.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaProperty.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplateFactory.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/IconFactory.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/Classifier.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/ClassifierConnectionPointRef.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/ClassifierMatchAttributes.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/ConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/ConstituentVnfd.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/ConstituentVnfdConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/ForwardingGraph.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalConnectionPointRef.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalVirtualLink.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/NetworkService.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/NetworkServiceConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/PhysicalNetworkFunction.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/RecordServicePath.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/RspConnectionPointRef.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualDeploymentUnit.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualDeploymentUnitInternalConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualLink.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunction.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunctionConnectionPoint.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunctionReadOnlyWrapper.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/model/descriptors/VnfdConnectionPointRef.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/utils.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/libraries/zoomFactor.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/sources/CatalogDataSource.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/sources/CatalogPackageManagerSource.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/sources/RiftHeaderSource.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/stores/CatalogDataStore.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/stores/CatalogPackageManagerStore.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/stores/CatalogPanelStore.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/stores/ComposerAppStore.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/stores/ModalOverlayStore.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/stores/RiftHeaderStore.js [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/Animations.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/AppRoot.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/Button.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CanvasPanel.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CanvasZoom.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogFilter.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogItemCanvasEditor.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogItems.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogPackageManager.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogPanel.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogPanelToolbar.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/CatalogPanelTray.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/ComposerAppToolbar.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/ConnectionPointSelector.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/DataOpenCloseIcon.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/DescriptorGraph.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/DetailsPanel.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/DropZonePanel.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/EditDescriptorModelProperties.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/EditForwardingGraphPaths.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/EditableProperty.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/FileUploadsList.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/FileUploadsToolbar.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/FullScreen.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/GraphDescriptorModel.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/GraphRecordServicePaths.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/GraphVirtualLink.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/LayoutRow.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/LoadingIndicator.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/ModalOverlay.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/ResizableManager.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/RiftHeader.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/ToggleElement.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/TooltipManager.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/_ColorGroups.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/_main.scss [new file with mode: 0644]
skyquake/plugins/composer/src/src/styles/_variables.scss [new file with mode: 0644]
skyquake/plugins/composer/test/helpers/pack/phantomjs-shims.js [new file with mode: 0644]
skyquake/plugins/composer/test/helpers/test-clean-input-output-model.json [new file with mode: 0644]
skyquake/plugins/composer/test/spec/components/ButtonSpec.js [new file with mode: 0644]
skyquake/plugins/composer/test/spec/libraries/DescriptorModelFactorySpec.js [new file with mode: 0644]
skyquake/plugins/composer/test/spec/libraries/DescriptorModelSpec.js [new file with mode: 0644]
skyquake/plugins/composer/test/spec/libraries/SelectionManagerSpec.js [new file with mode: 0644]
skyquake/plugins/composer/test/uploadServer/package.json [new file with mode: 0644]
skyquake/plugins/composer/test/uploadServer/server.js [new file with mode: 0644]
skyquake/plugins/composer/webpack.config.js [new file with mode: 0644]
skyquake/plugins/composer/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/debug/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/debug/api/debug.js [new file with mode: 0644]
skyquake/plugins/debug/config.json [new file with mode: 0644]
skyquake/plugins/debug/package.json [new file with mode: 0644]
skyquake/plugins/debug/routes.js [new file with mode: 0644]
skyquake/plugins/debug/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/debug/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/debug/server.js [new file with mode: 0644]
skyquake/plugins/debug/src/crash.jsx [new file with mode: 0644]
skyquake/plugins/debug/src/crash.scss [new file with mode: 0644]
skyquake/plugins/debug/src/crashActions.js [new file with mode: 0644]
skyquake/plugins/debug/src/crashSource.js [new file with mode: 0644]
skyquake/plugins/debug/src/crashStore.js [new file with mode: 0644]
skyquake/plugins/debug/src/main.js [new file with mode: 0644]
skyquake/plugins/debug/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/goodbyeworld/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/goodbyeworld/config.json [new file with mode: 0644]
skyquake/plugins/goodbyeworld/package.json [new file with mode: 0644]
skyquake/plugins/goodbyeworld/routes.js [new file with mode: 0644]
skyquake/plugins/goodbyeworld/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/goodbyeworld/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/goodbyeworld/server.js [new file with mode: 0644]
skyquake/plugins/goodbyeworld/server/bundle.js [new file with mode: 0644]
skyquake/plugins/goodbyeworld/src/components/goodbyeWorldOne.jsx [new file with mode: 0644]
skyquake/plugins/goodbyeworld/src/components/goodbyeWorldTwo.jsx [new file with mode: 0644]
skyquake/plugins/goodbyeworld/src/index.html [new file with mode: 0644]
skyquake/plugins/goodbyeworld/src/main.js [new file with mode: 0644]
skyquake/plugins/goodbyeworld/webpack.config.js [new file with mode: 0644]
skyquake/plugins/goodbyeworld/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/helloworld/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/helloworld/config.json [new file with mode: 0644]
skyquake/plugins/helloworld/package.json [new file with mode: 0644]
skyquake/plugins/helloworld/routes.js [new file with mode: 0644]
skyquake/plugins/helloworld/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/helloworld/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/helloworld/server.js [new file with mode: 0644]
skyquake/plugins/helloworld/server/bundle.js [new file with mode: 0644]
skyquake/plugins/helloworld/src/helloWorldDashboard.jsx [new file with mode: 0644]
skyquake/plugins/helloworld/src/helloWorldOne.jsx [new file with mode: 0644]
skyquake/plugins/helloworld/src/helloWorldTwo.jsx [new file with mode: 0644]
skyquake/plugins/helloworld/src/index.html [new file with mode: 0644]
skyquake/plugins/helloworld/src/main.js [new file with mode: 0644]
skyquake/plugins/helloworld/webpack.config.js [new file with mode: 0644]
skyquake/plugins/helloworld/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/launchpad/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/launchpad/api/epa_aggregator.js [new file with mode: 0644]
skyquake/plugins/launchpad/api/launchpad.js [new file with mode: 0644]
skyquake/plugins/launchpad/api/launchpad_.js [new file with mode: 0644]
skyquake/plugins/launchpad/api/transforms.js [new file with mode: 0644]
skyquake/plugins/launchpad/config.json [new file with mode: 0644]
skyquake/plugins/launchpad/package.json [new file with mode: 0644]
skyquake/plugins/launchpad/routes.js [new file with mode: 0644]
skyquake/plugins/launchpad/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/launchpad/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/launchpad/server.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/alt.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/default-catalog-icon.svg [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/default-icon-white.svg [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/default-icon.svg [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/header-logo.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/logos/riftio.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/osm_header_253x50.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/osm_header_506x100.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/riftio_website_logo_002_03.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/sample-catalog.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/assets/images/vendor-riftio.png [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/ButtonEventListener.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/carousel-react.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/carousel-react.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/carousel.css [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/components.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/multicomponent.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/skyquakeCarousel.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/skyquakeCarousel.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/carousel/test.html [new file with mode: 0644]
skyquake/plugins/launchpad/src/cloud-account.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/createActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/createSource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/createStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/catalogBrowser.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/catalogCard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/catalogCard.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/catalogDescriptorRaw.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateDashboard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateDashboard.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateDescriptorPanel.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateInputParams.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateInputParams.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateParameters.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateSelectDescriptorPanel.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateSelectDescriptorPanel.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/instantiateStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/launchNetworkServiceActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/instantiate/launchNetworkServiceSource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad-create.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpadBreadcrumbs.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpadFleetActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpadFleetSource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpadFleetStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/jobListCard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/jobListCard.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpad-card.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadCard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadCardActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadCardCloudAccount.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadCardMgmtInterfaces.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadControls.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadHeader.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpadNSInfo.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/launchpad_card.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/nsConfigPrimitives.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/nsrConfigPrimitives.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/nsrScalingGroups.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/nsrScalingGroups.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/vnfrConfigPrimitives.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/launchpad_card/vnfrConfigPrimitives.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/main.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/monitoring-params-filter.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/monitoring_params/monitoringParamsCarousel.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/monitoring_params/monitoring_params.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/nsCardPanel/nsCardPanel.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/nsListPanel/nsListPanel.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/placementGroupsInfo.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordCard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordDetails.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordNavigator.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordNavigator.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordView.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordViewActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordViewSource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordViewStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/recordViewer/recordViewer.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/settings.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/ssh_keys/sshKeyActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/ssh_keys/sshKeySource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/ssh_keys/sshKeyStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/ssh_keys/sshKeys.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyL2View/detailView.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyL2View/topologyL2Actions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyL2View/topologyL2Source.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyL2View/topologyL2Store.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyL2View/topologyL2View.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyL2View/topologyL2View.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyView/topologyActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyView/topologySource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyView/topologyStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyView/topologyView.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/topologyView/topologyView.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreate.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateSource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkDetails.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinks.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinks.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinksActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinksStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrActions.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrCard.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrCard.scss [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrCardNfviMetrics.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrSource.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrStore.js [new file with mode: 0644]
skyquake/plugins/launchpad/src/vnfr/vnfrView.jsx [new file with mode: 0644]
skyquake/plugins/launchpad/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/logging/CMakeLists.txt [new file with mode: 0644]
skyquake/plugins/logging/api/logging.js [new file with mode: 0644]
skyquake/plugins/logging/api/transforms.js [new file with mode: 0644]
skyquake/plugins/logging/config.json [new file with mode: 0644]
skyquake/plugins/logging/package.json [new file with mode: 0644]
skyquake/plugins/logging/routes.js [new file with mode: 0644]
skyquake/plugins/logging/scripts/build.sh [new file with mode: 0755]
skyquake/plugins/logging/scripts/install.sh [new file with mode: 0755]
skyquake/plugins/logging/server.js [new file with mode: 0644]
skyquake/plugins/logging/src/categorySeverityGrid.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/denyEventsEditGroup.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/gridWidgets.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/logging.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/logging.scss [new file with mode: 0644]
skyquake/plugins/logging/src/loggingActions.js [new file with mode: 0644]
skyquake/plugins/logging/src/loggingGeneral.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/loggingNav.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/loggingSource.js [new file with mode: 0644]
skyquake/plugins/logging/src/loggingStore.js [new file with mode: 0644]
skyquake/plugins/logging/src/loggingWidgets.jsx [new file with mode: 0644]
skyquake/plugins/logging/src/main.js [new file with mode: 0644]
skyquake/plugins/logging/src/syslogViewer.jsx [new file with mode: 0644]
skyquake/plugins/logging/webpack.production.config.js [new file with mode: 0644]
skyquake/plugins/plugin_config.json [new file with mode: 0644]
skyquake/scripts/build.sh [new file with mode: 0755]
skyquake/scripts/install_skyquake.sh [new file with mode: 0755]
skyquake/scripts/install_ui.sh [new file with mode: 0755]
skyquake/scripts/launch_ui.sh [new file with mode: 0755]
skyquake/skyquake.js [new file with mode: 0644]
skyquake/tests/intern.js [new file with mode: 0644]
skyquake/tests/react/skyquakeRouter_test.js [new file with mode: 0644]
skyquake/tests/stories/button.js [new file with mode: 0644]
skyquake/tests/stories/catalogCard.js [new file with mode: 0644]
skyquake/tests/stories/sq-input-slider.js [new file with mode: 0644]
skyquake/tests/stories/sshKeyCard.js [new file with mode: 0644]
skyquake/tests/support/babel.js [new file with mode: 0644]
skyquake/tests/unit/plugin_discoverer.js [new file with mode: 0644]
skyquake/tests/unit/router.js [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..40934df
--- /dev/null
@@ -0,0 +1,8 @@
+.DS_Store/
+.DS_Store
+err.log
+out.log
+node_modules/
+npm-debug.log
+fixtures/
+.build
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1c9b576
--- /dev/null
@@ -0,0 +1,59 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# DO NOT add any code before this and DO NOT
+# include this file anywhere else
+##
+include(rift_submodule)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+
+##
+# Include the subdirs
+##
+set(
+  subdirs
+    skyquake
+  )
+rift_add_subdirs(
+  SUBDIR_LIST
+    ${subdirs}
+  )
+
+##
+# This macro adds targets for documentaion, unittests, code coverage and packaging
+##
+rift_add_submodule_targets(SUBMODULE_PACKAGE_NAME "rw.ui")
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..5c9d864
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,60 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Austin Cormier
+# Creation Date: 07/27/2016
+# 
+#
+
+.PHONY : clean
+
+makefile.top := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+TOP_SRC_PATH := $(makefile.top)
+TOP_ROOT_PATH := /usr/rift
+CMAKE_MODULE_PATH := $(TOP_ROOT_PATH)/cmake/modules
+
+RIFT_BUILD = $(TOP_SRC_PATH)/.build
+RIFT_ARTIFACTS = $(TOP_ROOT_PATH)/artifacts
+RIFT_INSTALL = $(TOP_ROOT_PATH)
+RIFT_SHELL_EXE = $(TOP_ROOT_PATH)/rift-shell -b $(RIFT_BUILD) -i $(RIFT_INSTALL) -a $(RIFT_ARTIFACTS) --
+
+CONFD = XML_ONLY
+
+BUILD_TYPE = Debug
+NOT_DEVELOPER_TYPE = FALSE
+COVERAGE_BUILD = FALSE
+RIFT_AGENT_BUILD = $(CONFD)
+PROJECT_TOP_DIR = $(TOP_ROOT_PATH)
+
+all: rw
+
+cmake::
+       mkdir -p $(RIFT_BUILD)
+       mkdir -p $(RIFT_ARTIFACTS)
+       mkdir -p $(RIFT_INSTALL)
+       cd $(RIFT_BUILD) && $(RIFT_SHELL_EXE) cmake $(TOP_SRC_PATH) -DCMAKE_INSTALL_PREFIX=$(TOP_ROOT_PATH) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DNOT_DEVELOPER_BUILD=$(NOT_DEVELOPER_TYPE) -DCOVERAGE_BUILD=$(COVERAGE_TYPE) -DRIFT_AGENT_BUILD=$(RIFT_AGENT_BUILD) -DPROJECT_TOP_DIR=$(PROJECT_TOP_DIR) -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} -DRIFT_SUBMODULE_NAME=$(PROJECT_TOP_DIR)
+
+rw: cmake
+       $(RIFT_SHELL_EXE) $(MAKE) -C $(RIFT_BUILD)
+
+install:
+       $(RIFT_SHELL_EXE) $(MAKE) -C $(RIFT_BUILD) install
+
+unittest:
+       $(RIFT_SHELL_EXE) $(MAKE) -C $(RIFT_BUILD) rw.unittest
+
+clean:
+       @echo "Cleaning up.."
+       -rm -rf .build
diff --git a/foss.txt b/foss.txt
new file mode 100644 (file)
index 0000000..457c99c
--- /dev/null
+++ b/foss.txt
@@ -0,0 +1,63 @@
+#
+# webapp/node_modules
+#
+RIFT.ui, webapp/node_modules/angular, angularjs, MIT, https://github.com/angular/angular.js
+RIFT.ui, webapp/node_modules/angular-ui-router, angular-ui-router, MIT, https://github.com/angular-ui/ui-router
+RIFT.ui, webapp/node_modules/alt, alt, MIT, https://github.com/goatslacker/alt
+RIFT.ui, webapp/node_modules/babel-core, babel-core, MIT, https://www.npmjs.com/package/babel-core
+RIFT.ui, webapp/node_modules/babel-loader, babel-loader, MIT, https://github.com/babel/babel-loader
+RIFT.ui, webapp/node_modules/babel-preset-es2015, babel-preset-es2015, MIT, https://github.com/babel/babel/tree/master/packages/babel-preset-es2015
+RIFT.ui, webapp/node_modules/babel-runtime, babel-runtime, MIT, https://www.npmjs.com/package/babel-runtime
+RIFT.ui, webapp/node_modules/baggage-loader, baggage-loader, MIT, https://github.com/deepsweet/baggage-loader
+#RIFT.ui, canv-gauge, canv-gauge, MIT, https://github.com/Mikhus/canv-gauge
+RIFT.ui, webapp/node_modules/css-loader, css-loader, MIT, https://github.com/webpack/css-loader
+RIFT.ui, webapp/node_modules/express, express, MIT, https://github.com/strongloop/express
+RIFT.ui, webapp/node_modules/file-loader, file-loader, MIT, https://github.com/webpack/file-loader
+RIFT.ui, webapp/node_modules/foundation-apps, foundation-apps, MIT, https://github.com/zurb/foundation-apps
+RIFT.ui, webapp/node_modules/html-loader, html-loader, MIT, https://github.com/webpack/html-loader
+RIFT.ui, webapp/node_modules/http-proxy, http-proxy, MIT, https://github.com/nodejitsu/node-http-proxy
+RIFT.ui, webapp/node_modules/jquery, jquery, MIT-like, https://github.com/jquery/jquery
+RIFT.ui, webapp/node_modules/loader-utils, loader-utils, MIT, https://github.com/webpack/loader-utils
+RIFT.ui, webapp/node_modules/loaders.css, loaders.css, MIT, https://github.com/ConnorAtherton/loaders.css/tree/master
+RIFT.ui, webapp/node_modules/minimist, minimist, MIT, https://github.com/substack/minimist
+RIFT.ui, webapp/node_modules/ngtemplate-loader, ngtemplate-loader, MIT, https://github.com/WearyMonkey/ngtemplate-loader
+RIFT.ui, webapp/node_modules/node-sass, node-sass, MIT-like, https://github.com/sass/node-sass
+RIFT.ui, webapp/node_modules/open-iconic, open-iconic, MIT and SIL, https://github.com/iconic/open-iconic
+RIFT.ui, webapp/node_modules/prismjs, prismjs, MIT, https://github.com/PrismJS/prism
+RIFT.ui, webapp/node_modules/react, react, BSD, https://github.com/facebook/react
+RIFT.ui, webapp/node_modules/react-d3-histogram, react-d3-histogram, ISC, https://github.com/english/react-d3-histogram
+RIFT.ui, webapp/node_modules/react-slick, react-slick, MIT, https://github.com/akiran/react-slick
+RIFT.ui, webapp/node_modules/react-tabs, react-tabs, MIT, https://github.com/rackt/react-tabs/blob/master/LICENSE
+RIFT.ui, webapp/node_modules/react-treeview, react-treeview, MIT, https://www.npmjs.com/package/react-treeview
+RIFT.ui, webapp/node_modules/sass-loader, sass-loader, MIT, https://github.com/jtangelder/sass-loader
+RIFT.ui, webapp/node_modules/source-map, source-map, BSD, https://github.com/mozilla/source-map
+RIFT.ui, webapp/node_modules/style-loader, style-loader, MIT, https://github.com/webpack/style-loader
+RIFT.ui, webapp/node_modules/underscore, underscore, MIT-like, https://github.com/webpack/style-loader
+RIFT.ui, webapp/node_modules/webpack, webpack, MIT, https://github.com/webpack/webpack
+RIFT.ui, webapp/node_modules/webpack-dev-server, webpack-dev-server, MIT, https://github.com/webpack/webpack-dev-server
+#
+# api/node_modules
+#
+RIFT.ui, api/node_modules/bluebird, bluebird, MIT, https://github.com/petkaantonov/bluebird
+RIFT.ui, api/node_modules/body-parser, body-parser, MIT, https://github.com/expressjs/body-parser
+RIFT.ui, api/node_modules/cors, cors, MIT, https://github.com/expressjs/cors
+RIFT.ui, api/node_modules/express, express, MIT, https://github.com/strongloop/express
+RIFT.ui, api/node_modules/hawk, hawk, BSD-3-Clause, https://github.com/hueniverse/hawk
+RIFT.ui, api/node_modules/minimist, minimist, MIT, https://github.com/substack/minimist
+RIFT.ui, api/node_modules/promise, promise, MIT, https://github.com/then/promise
+RIFT.ui, api/node_modules/qs, qs, BSD-3-Clause, https://github.com/hapijs/qs
+RIFT.ui, api/node_modules/request, request, Apache-2.0, https://github.com/request/request
+RIFT.ui, api/node_modules/request-promise, request-promise, MIT, https://github.com/request/request-promise
+RIFT.ui, api/node_modules/underscore, underscore, MIT, https://github.com/jashkenas/underscore
+RIFT.ui, api/node_modules/ws, ws, MIT, https://github.com/websockets/ws
+RIFT.ui, api/node_modules/jasmine-node, jasmine-node, MIT, https://github.com/mhevery/jasmine-node
+RIFT.ui, api/node_modules/nock, Nock is an HTTP mocking and expectations library for Node.js, MIT, https://github.com/pgte/nock
+RIFT.ui, api/node_modules/replay, Node Replay, MIT, https://github.com/assaf/node-replay
+RIFT.ui, api/node_modules/express-session, express-session, MIT, https://github.com/expressjs/session
+#
+# webapp/public
+#
+#RIFT.ui, webapp/public/vendor/css-reset-2.0, CSS Reset, NONE, http://meyerweb.com/eric/tools/css/reset/
+
+RIFT.ui, skyquake/plugins/composer/node_modules/json2yaml, json2yaml, Apache-2.0, https://github.com/coolaj86/json2yaml
+RIFT.ui, skyquake/plugins/composer/node_modules/react-inlinesvg, react-inlinesvg, MIT, https://github.com/matthewwithanm/react-inlinesvg
diff --git a/manifest/LICENSE b/manifest/LICENSE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/skyquake/.babelrc b/skyquake/.babelrc
new file mode 100644 (file)
index 0000000..f68f024
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "presets": [
+    "es2015", "stage-0", "react"
+  ]
+}
diff --git a/skyquake/.gitignore b/skyquake/.gitignore
new file mode 100644 (file)
index 0000000..111d0cd
--- /dev/null
@@ -0,0 +1,5 @@
+npm-debug.log
+*.swp
+node_modules
+public
+dist
diff --git a/skyquake/.storybook/config.js b/skyquake/.storybook/config.js
new file mode 100644 (file)
index 0000000..42edf3c
--- /dev/null
@@ -0,0 +1,13 @@
+import { configure } from '@kadira/storybook';
+
+function loadStories() {
+  // require('../tests/stories/button');
+  // require('../tests/stories/sq-input-slider');
+  // require('../tests/stories/sshKeyCard');
+  // require('../tests/stories/button');
+  // require('../tests/stories/sq-input-slider');
+  require('../tests/stories/catalogCard');
+  // require as many stories as you need.
+}
+
+configure(loadStories, module);
diff --git a/skyquake/.storybook/webpack.config.js b/skyquake/.storybook/webpack.config.js
new file mode 100644 (file)
index 0000000..4feae7f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var frameworkPath = '../skyquake/framework/';
+var CommonsPlugin = new require("webpack/lib/optimize/CommonsChunkPlugin")
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass?includePaths[]='+ path.resolve(frameworkPath)
+            }
+        ]
+    }
+};
+module.exports = config;
diff --git a/skyquake/CMakeLists.txt b/skyquake/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ac3637f
--- /dev/null
@@ -0,0 +1,63 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  skyquake
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    npm install
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install_skyquake.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/skyquake/skyquake-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
+
+##
+# Include the subdirs
+##
+set(
+  subdirs
+    plugins
+  )
+rift_add_subdirs(
+  SUBDIR_LIST 
+    ${subdirs}
+  )
diff --git a/skyquake/__tests__/skyquakeRouter_test.js b/skyquake/__tests__/skyquakeRouter_test.js
new file mode 100644 (file)
index 0000000..c451c34
--- /dev/null
@@ -0,0 +1,50 @@
+jest.dontMock('../framework/widgets/skyquake_container/skyquakeNav.jsx');
+// /skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx
+import React from 'react';
+import ReactDOM from 'react-dom';
+import TestUtils from 'react-addons-test-utils';
+
+// import {returnLinkItem} from '../framework/widgets/skyquake_container/skyquakeNav.jsx';
+
+const SkyquakeNav = require('../framework/widgets/skyquake_container/skyquakeNav.jsx')
+
+describe('SkyquakeNav', () => {
+
+    let exampleRoutes;
+    let node;
+    beforeEach(function() {
+            node = document.createElement('div');
+            exampleRoutes = [{
+                "label": "Hello World Component 1",
+                "route": "/helloworld/#hello",
+                "component": "./helloWorldOne.jsx",
+                "path": "",
+                "type": "internal",
+                "isExternal": true
+            },{
+
+                "label": "Hello World Component 1",
+                "route": "hello",
+                "component": "./helloWorldOne.jsx",
+                "path": "",
+                "type": "internal",
+                "isExternal": false
+            }];
+    });
+    describe('returnLinkItem', () => {
+        it('Returns an <a> tag when external', () => {
+            let element = SkyquakeNav.returnLinkItem(exampleRoutes[0]);
+            let Tag = TestUtils.renderIntoDocument(element);
+            let TagNode = ReactDOM.findDOMNode(Tag);
+            expect(Tag.constructor.displayName).toEqual("A");
+            expect(TagNode.attributes.href).not.toEqual(undefined);
+        });
+        it('Returns a <Link> tag when internal', () => {
+            let element = SkyquakeNav.returnLinkItem(exampleRoutes[1]);
+            let Tag = TestUtils.renderIntoDocument(element);
+            let TagNode = ReactDOM.findDOMNode(Tag);
+            expect(TagNode.constructor.displayName).toEqual("Link");
+            expect(TagNode.attributes.href).not.toEqual(undefined);
+        })
+    })
+})
diff --git a/skyquake/framework/core/api_utils/constants.js b/skyquake/framework/core/api_utils/constants.js
new file mode 100644 (file)
index 0000000..dccadb7
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+ /**
+  * constants module. Provides constants for use within the skyquake instance
+  * @module api_utils/constants
+  */
+
+var constants = {};
+
+constants.FOREVER_ON = true;
+constants.HTTP_HEADERS = {
+    accept: {
+        data: {
+            'Accept': 'application/vnd.yang.data+json'
+        },
+        collection: {
+            'Accept': 'application/vnd.yang.collection+json'
+        }
+    },
+    content_type: {
+        data: {
+            'Content-Type': 'application/vnd.yang.data+json'
+        },
+        collection: {
+            'Content-Type': 'application/vnd.yang.collection+json'
+        }
+    }
+};
+
+// (Incomplete) set of expected HTTP response codes
+constants.HTTP_RESPONSE_CODES = {
+    SUCCESS: {
+        OK:                         200,
+        CREATED:                    201,
+        ACCEPTED:                   202,
+        NO_CONTENT:                 204,
+        MOVED_PERMANENTLY:          301,
+        NOT_MODIFIED:               304
+    },
+    ERROR: {
+        BAD_REQUEST:                400,
+        UNAUTHORIZED:               401,
+        FORBIDDEN:                  403,
+        NOT_FOUND:                  404,
+        METHOD_NOT_ALLOWED:         405,
+        NOT_ACCEPTABLE:             406,
+        CONFLICT:                   409,
+        INTERNAL_SERVER_ERROR:      500,
+        NOT_IMPLEMENTED:            501,
+        BAD_GATEWAY:                502,
+        SERVICE_UNAVAILABLE:        504,
+        HTTP_VERSION_UNSUPPORTED:   505
+
+    }
+}
+constants.SOCKET_BASE_PORT = 3500;
+constants.SOCKET_POOL_LENGTH = 20;
+constants.SERVER_PORT = process.env.SERVER_PORT || 8000;
+constants.SECURE_SERVER_PORT = process.env.SECURE_SERVER_PORT || 8443;
+
+module.exports = constants;
\ No newline at end of file
diff --git a/skyquake/framework/core/api_utils/sockets.js b/skyquake/framework/core/api_utils/sockets.js
new file mode 100644 (file)
index 0000000..6076594
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+//SOCKET MANAGER
+// test
+//Supports localhost node polling subscriptions and pass through subscriptions to other websockets
+//
+//TODO REFACTOR: this needs to happen. there's too much boilerplate code in here.
+//TODO Document after refactoring
+//TODO Improved logging for debugging
+//TODO List of URLS
+
+var WebSocket = require('ws');
+var Request = require('request');
+var _ = require('lodash');
+var constants = require('./constants.js');
+var Promise = require('promise');
+var url = require('url');
+var sockjs = require('sockjs');
+var websocket_multiplex = require('websocket-multiplex');
+
+
+function getPortForProtocol (protocol) {
+  switch (protocol) {
+    case 'http':
+      return 8000;
+    case 'https':
+      return 8443;
+  }
+}
+
+var Subscriptions = function() {
+  this.ID = 0;
+  this.socketServers = {};
+};
+
+Subscriptions.prototype.configure = function(config) {
+  this.config = config;
+  this.ready = true;
+  // 1. Setup SockJS server
+  var sockjs_opts = {};
+  this.service = sockjs.createServer(sockjs_opts);
+  // 2. Setup multiplexing
+  this.multiplexer = new websocket_multiplex.MultiplexServer(this.service);
+
+  this.service.installHandlers(this.config.httpServer, {prefix:'/multiplex'});
+}
+
+/**
+ * [subscribe description]
+ * @param  {Object}   req
+ * @param  {String}   req.body.url May be http, https, or ws
+ * @param  {Function} req.body.transform A function that will transform
+ *                                      the data before sending it out
+ *                                      through the socket. Receives one
+ *                                      argument, which is the data
+ *                                      returned from the subscription.
+ * @param  {Function} callback Function that will receive the SubscriptionData reference object
+ * @return {Object}   SubscriptionReference  An object containing the subscription information.
+ * @return {Number} SubscriptionReference.id The subscription ID
+ */
+Subscriptions.prototype.subscribe = function(req, callback) {
+  var self = this;
+  var URL = req.body.url;
+  var SubscriptionReference;
+  var sessionId = req.session.id;
+  var protocolTest = /^(.{2,5}):\/\//;
+  var protocol = URL.match(protocolTest);
+
+  if (!protocol) {
+    var origin = '';
+    if (req.query['api_server']) {
+      var api_server_protocol = req.query['api_server'].match(protocolTest)[1];
+      var api_server_origin = req.query['api_server'] + ':' + getPortForProtocol(api_server_protocol);
+      origin = api_server_origin;
+      protocol = api_server_protocol;
+    } else {
+      // TODO: NEED A WAY (URL PARAM) TO TRIGGER THIS PART OF THE CODE
+      // WHICH IS NECESSARY FOR DEVELOPMENT ON MAC
+      // No protocol was passed with the url in the body. Assume req.protocol is protocol and construct URL
+      protocol = req.protocol || 'https';
+      // Converting relative URL to full path.
+      origin = protocol + '://' + req.headers.host
+    }
+    var a = url.resolve(origin, req.baseUrl);
+    var b = url.resolve(a, URL);
+    URL = b;
+    console.log('DEBUG URL IS', URL);
+  } else {
+    protocol = protocol[1]
+  }
+
+  return new Promise(function(resolve, reject) {
+
+    if (!self.ready) {
+      return reject({
+        statusCode: 500,
+        errorMessage: 'SocketManager not configured yet. Cannot proceed'
+      })
+    }
+
+    self.createWebSocketServer().then(function(successData) {
+
+        self.socketServers[sessionId + successData.id] = successData;
+        self.setUpSocketInstance(protocol, URL, req, self.socketServers[sessionId + successData.id].wss, successData.id);
+        return resolve({
+          statusCode: 200,
+          data: {
+            id: self.socketServers[sessionId + successData.id].id
+          }
+        });
+      },
+      function(errorData) {
+        return reject({
+          statusCode: 503,
+          errorMessage: errorData.error
+        });
+      });
+  });
+};
+
+Subscriptions.prototype.setUpSocketInstance = function(protocol, URL, req, wss, channelId) {
+  var self = this;
+  //Need to refactor this to make it more scalable/dynamic
+  switch (protocol) {
+    case 'http':
+      self.socketInstance(URL, req, wss, PollingSocket, channelId);
+      break;
+    case 'https':
+      self.socketInstance(URL, req, wss, PollingSocket, channelId);
+      break;
+    case 'ws':
+      self.socketInstance(URL, req, wss, WebSocket, channelId);
+      break;
+    case 'wss':
+      self.socketInstance(URL, req, wss, WebSocket, channelId);
+      break;
+  }
+}
+
+Subscriptions.prototype.createWebSocketServer = function() {
+  var self = this;
+
+  return new Promise(function(resolve, reject) {
+    var wss = null;
+
+    self.ID++;
+
+    wss = self.multiplexer.registerChannel(self.ID);
+
+    return resolve({
+      id: self.ID,
+      wss: wss
+    });
+  });
+};
+
+Subscriptions.prototype.socketInstance = function(url, req, wss, Type, channelId) {
+  console.log('Creating a new socketInstance for:', url, 'sessionId:', req.session.id);
+  var self = this;
+  var Socket = null;
+  var Connections = [];
+  var Index = 0;
+  var sessionId = req.session.id;
+  var wssRef = wss;
+  var channelIdRef = channelId;
+  wss.on('connection', function(conn) {
+    console.log('New connection to multiplex-server for channelId', channelIdRef);
+
+    conn.on('data', function(msg) {
+      console.log('Test purposes only. Received message from client:', msg);
+      conn.write('Test purposes only. Echo: ' + msg);
+    });
+
+    if (!Socket) {
+      if (Type == PollingSocket) {
+        Socket = new Type(url, req, 1000, req.body);
+      } else {
+        Socket = new Type(url);
+      }
+      console.log('Socket assigned for url', url);
+    }
+    conn.index = Index++;
+    // Add this client-connection into list of connections for this channelId/wss
+    Connections.push(conn);
+
+    conn.on('close', function() {
+      // Remove the browser connection from list of Connections for this channelId/wss
+      Connections.splice(conn.index, 1);
+      console.log('splicing conn.index', conn.index,' for channel', channelIdRef);
+
+      // Check if no other connections exist
+      if (Connections.length == 0) {
+        console.log('No more connections for', channelId, '. Will close socket server and downstream socket/poller.');
+        try {
+          // Close downstream socket/poller
+          Socket.close();
+
+          // Close socket server
+          conn.end();
+
+          // Remove from list of socketServers
+          delete self.socketServers[sessionId + wss.id];
+
+          // There is no unregisterChannel. Assuming
+          // sockjs/websocket-multiplex do the right
+          // things and cleanup after themselves.
+        } catch (e) {
+          console.log('Error closing socket server: ', e);
+        }
+        Index = 0;
+        delete Socket;
+      }
+    });
+
+    Socket.onopen = function() {
+      console.log('Opened a websocket to southbound server');
+    };
+
+    Socket.onerror = function(error) {
+      console.log('Error on southbound connection. Error:', error);
+    }
+
+    Socket.onmessage = function(data) {
+      var i;
+      var self = this;
+      if (req.body.transform && req.body.transform.constructor.name == "String") {
+        //someTransformObject[req.body.transform](data, send)
+        //req.body.transform(data, send);
+      } else {
+        if (Type == PollingSocket) {
+          send(data);
+        } else {
+          send(data.data);
+        }
+      }
+
+      function send(payload) {
+        var is401 = false;
+        try {
+          if (typeof payload == 'string') {
+            var jsonPayload = JSON.parse(payload);
+            is401 = jsonPayload.statusCode == 401;
+          }
+          else {
+            is401 = payload.statusCode == 401;
+          }
+        } catch(e) {
+          payload = {}
+        }
+
+        for (i = Connections.length - 1; i >= 0; i -= 1) {
+          // console.log('Sending payload to channelId:', channelId, ' on connection', i);
+          Connections[i].write(payload);
+        };
+        if (is401) {
+          try {
+            Socket.close();
+          } catch (e) {
+            console.log('Error closing Socket')
+          }
+        }
+      }
+
+    };
+  });
+};
+
+function PollingSocket(url, req, interval, config) {
+  console.log('Creating a new PollingSocket for url', url, 'sessionId:', req.session.id);
+  var self = this;
+  self.isClosed = false;
+  var requestHeaders = {};
+  _.extend(requestHeaders, {
+    'Authorization': req.get('Authorization')
+  });
+
+  var pollServer = function() {
+    Request({
+      url: url,
+      method: config.method || 'GET',
+      headers: requestHeaders,
+      json: config.payload,
+      rejectUnauthorized: false,
+      forever: constants.FOREVER_ON
+    }, function(error, response, body) {
+      if (error) {
+        console.log('Error polling: ' + url);
+      } else {
+        if (!self.isClosed) {
+          self.poll = setTimeout(pollServer, 1000 || interval);
+          var data = response.body;
+          if (self.onmessage) {
+            self.onmessage(data);
+          }
+        }
+      }
+    });
+  };
+  pollServer();
+};
+
+PollingSocket.prototype.close = function() {
+  console.log('Closing PollingSocket');
+  var self = this;
+  this.isClosed = true;
+  clearTimeout(self.poll);
+};
+
+
+module.exports = Subscriptions;
diff --git a/skyquake/framework/core/api_utils/utils.js b/skyquake/framework/core/api_utils/utils.js
new file mode 100644 (file)
index 0000000..163769a
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+// Helper Functions
+
+
+/**
+ * Utils for use across the api_server.
+ * @module framework/core/utils
+ */
+
+var fs = require('fs');
+var request = require('request');
+var Promise = require('promise');
+var CONSTANTS = require('./constants.js');
+var CONFD_PORT = '8008';
+var APIVersion = '/v1';
+var _ = require('lodash');
+
+var requestWrapper = function(request) {
+       if (process.env.HTTP_PROXY && process.env.HTTP_PROXY != '') {
+               request = request.defaults({
+                       'proxy': process.env.HTTP_PROXY
+               });
+       }
+       return request;
+}
+
+var confdPort = function(api_server) {
+       try {
+               api_server = api_server.replace(api_server.match(/[0-9](:[0-9]+)/)[1], '')
+       } catch (e) {
+
+       }
+       return api_server + ':' + CONFD_PORT;
+};
+
+
+var validateResponse = function(callerName, error, response, body, resolve, reject) {
+       var res = {};
+
+       if (error) {
+               console.log('Problem with "', callerName, '": ', error);
+               res.statusCode = 500;
+               res.errorMessage = {
+                       error: 'Problem with ' + callerName + ': ' + error
+               };
+               reject(res);
+               return false;
+       } else if (response.statusCode >= 400) {
+               console.log('Problem with "', callerName, '": ', response.statusCode, ':', body);
+               res.statusCode = response.statusCode;
+
+               // auth specific
+               if (response.statusCode == 401) {
+                       res.errorMessage = {
+                               error: 'Authentication needed' + body
+                       };
+                       reject(res);
+                       return false;
+               }
+
+               res.errorMessage = {
+                       error: 'Problem with ' + callerName + ': ' + response.statusCode + ': ' + typeof(body) == 'string' ? body : JSON.stringify(body),
+                       body: body
+               };
+
+               reject(res);
+               return false;
+       } else if (response.statusCode == 204) {
+               resolve({
+                       statusCode: response.statusCode,
+                       data: {}
+               });
+               return false;
+       } else {
+               return true;
+       }
+};
+
+
+var checkAuthorizationHeader = function(req) {
+       return new Promise(function(resolve, reject) {
+               if (req.get('Authorization') == null) {
+                       reject();
+               } else {
+                       resolve();
+               }
+       });
+};
+
+if (process.env.LOG_REQUESTS) {
+       var logFile = process.env.REQUESTS_LOG_FILE;
+
+       if (logFile && logFile != '') {
+               validateResponse = function(callerName, error, response, body, resolve, reject) {
+                       var res = {};
+
+                       if (error) {
+                               console.log('Problem with "', callerName, '": ', error);
+                               res.statusCode = 500;
+                               res.errorMessage = {
+                                       error: 'Problem with ' + callerName + ': ' + error
+                               };
+                               reject(res);
+                               fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Error: ' + error);
+                               return false;
+                       } else if (response.statusCode >= 400) {
+                               console.log('Problem with "', callerName, '": ', response.statusCode, ':', body);
+                               res.statusCode = response.statusCode;
+
+                               // auth specific
+                               if (response.statusCode == 401) {
+                                       res.errorMessage = {
+                                               error: 'Authentication needed' + body
+                                       };
+                                       reject(res);
+                                       fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Error Body: ' + body);
+                                       return false;
+                               }
+
+                               res.errorMessage = {
+                                       error: 'Problem with ' + callerName + ': ' + response.statusCode + ': ' + body
+                               };
+
+                               reject(res);
+                               fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Error Body: ' + body);
+                               return false;
+                       } else if (response.statusCode == 204) {
+                               resolve();
+                               fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Response Body: ' + body);
+                               return false;
+                       } else {
+                               fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Response Body: ' + body);
+                               return true;
+                       }
+               };
+       }
+}
+
+/**
+ * Serve the error response back back to HTTP requester
+ * @param {Object} error - object of the format
+ *                                     {
+ *                                             statusCode - HTTP code to respond back with
+ *                                             error - actual error JSON object to serve
+ *                                     }
+ * @param {Function} res - a handle to the express response function
+ */
+var sendErrorResponse = function(error, res) {
+       res.status(error.statusCode);
+       res.send(error);
+}
+
+/**
+ * Serve the success response back to HTTP requester
+ * @param {Object} response - object of the format
+ *                                     {
+ *                                             statusCode - HTTP code to respond back with
+ *                                             data - actual data JSON object to serve
+ *                                     }
+ * @param {Function} res - a handle to the express response function
+ */
+var sendSuccessResponse = function(response, res) {
+       res.status(response.statusCode);
+       res.send(response.data);
+}
+
+var passThroughConstructor = function(app) {
+       app.get('/passthrough/:type/*', function(req, res) {
+               var url = req.params[0];
+               var type = req.params.type;
+               var api_server = req.query["api_server"];
+               var uri = confdPort(api_server) + APIVersion + '/' + url + '?deep';
+               // Check that type is valid
+               switch (type) {
+                       case 'data':
+                               ;
+                       case 'collection':
+                               break;
+                       default:
+                               res.send({});
+               }
+               new Promise(function(resolve, reject) {
+                       request({
+                               uri: uri,
+                               method: 'GET',
+                               headers: _.extend({}, CONSTANTS.HTTP_HEADERS.accept[type], {
+                                       'Authorization': req.get('Authorization'),
+                                       forever: CONSTANTS.FOREVER_ON,
+                                       rejectUnauthorized: false,
+                               })
+                       }, function(error, response, body) {
+                               if (validateResponse('Passthrough: ' + url, error, response, body, resolve, reject)) {
+                                       resolve(JSON.parse(response.body))
+                               };
+                       });
+               }).then(function(data) {
+            res.send(data);
+        }, function(error) {
+               res.send({'error': error, uri: uri})
+        });;
+       });
+}
+
+module.exports = {
+       /**
+        * Ensure confd port is on api_server variable.
+        **/
+       confdPort: confdPort,
+
+       validateResponse: validateResponse,
+
+       checkAuthorizationHeader: checkAuthorizationHeader,
+
+       request: requestWrapper.call(null, request),
+
+       sendErrorResponse: sendErrorResponse,
+
+       sendSuccessResponse: sendSuccessResponse,
+
+       passThroughConstructor: passThroughConstructor
+};
diff --git a/skyquake/framework/core/modules/api/configuration.js b/skyquake/framework/core/modules/api/configuration.js
new file mode 100644 (file)
index 0000000..3762643
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * Configuration api module. Provides API functions to configure node
+ * @module framework/core/modules/api/configuration
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var Promise = require('bluebird');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var request = utils.request;
+var configurationAPI = {};
+var _ = require('lodash');
+var GLOBAL_CONFIGURATION = {
+    api_server: 'localhost',
+    ssl_enabled: true
+};
+
+/**
+ * Get the server configuration for the Express API
+ * @param {Object} req - the Express request object
+ * @return {Function} Promise that resolves with success object or rejects
+ *                                       with error
+ */
+configurationAPI.get = function(req) {
+       return new Promise(function(resolve, reject) {
+        resolve({
+            statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+            data: GLOBAL_CONFIGURATION
+        });
+    });
+};
+
+/**
+ * Update the server configuration for the Express API
+ * @param {Object} req - the Express request object
+ * @return {Function} Promise that resolves with success object or rejects
+ *                    with error
+ */
+configurationAPI.update = function(req) {
+    var newConfiguration = req.body;
+    return new Promise(function(resolve, reject) {
+        try {
+            _.merge(GLOBAL_CONFIGURATION, newConfiguration);
+            resolve({
+                statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.NO_CONTENT,
+                data: {}
+            })
+        } catch (e) {
+            console.log('Merging on new configuration failed. Error:', e);
+            reject({
+                statusCode: constants.HTTP_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
+                errorMessage: {
+                    error: 'Problem with merging new configuration. Error: ' + JSON.stringify(e)
+                }
+            });
+        }
+    });
+};
+
+configurationAPI.globalConfiguration = {};
+/**
+ * Internally used (by Node.js components) to update server configuration
+ * @param {Object} data - the configuration to merge
+ */
+configurationAPI.globalConfiguration.update = function(data) {
+    _.merge(GLOBAL_CONFIGURATION, data);
+};
+
+/**
+ * Internally used (by Node.js components) to get server configuration
+ * @param {Object} data - the configuration to merge
+ */
+configurationAPI.globalConfiguration.get = function() {
+    return GLOBAL_CONFIGURATION;
+};
+
+module.exports = configurationAPI;
diff --git a/skyquake/framework/core/modules/api/descriptorModelMetaAPI.js b/skyquake/framework/core/modules/api/descriptorModelMetaAPI.js
new file mode 100644 (file)
index 0000000..b0223b2
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+// DescriptorModelMeta API (NSD + VNFD)
+
+
+var ModelMeta = {};
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var _ = require('lodash');
+
+ModelMeta.get = function(req) {
+    var self = this;
+    var api_server = req.query['api_server'];
+
+    return new Promise(function(resolve, reject) {
+        Promise.all([
+            rp({
+                uri: utils.confdPort(api_server) + '/api/schema/nsd-catalog/nsd',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            }),
+            rp({
+                uri: utils.confdPort(api_server) + '/api/schema/vnfd-catalog/vnfd',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            })
+        ]).then(function(result) {
+            var response = {};
+            response['data'] = {};
+            if (result[0].body && result[1].body) {
+                response['data']['nsd'] = JSON.parse(result[0].body)['nsd'];
+                response['data']['vnfd'] = JSON.parse(result[1].body)['vnfd'];
+            }
+            response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+            resolve(response);
+        }).catch(function(error) {
+            var response = {};
+            console.log('Problem with ModelMeta.get', error);
+            response.statusCode = error.statusCode || 500;
+            response.errorMessage = {
+                error: 'Failed to get descriptorModelMeta' + error
+            };
+            reject(response);
+        });
+    });
+};
+
+module.exports = ModelMeta;
diff --git a/skyquake/framework/core/modules/api/navigation.js b/skyquake/framework/core/modules/api/navigation.js
new file mode 100644 (file)
index 0000000..5f22835
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * navigation api module. Provides API functions to interact with
+ * the navigation_manager
+ * @module framework/core/modules/api/navigation
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var navigation_manager = require('../navigation_manager');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var navigationAPI = {};
+
+/**
+ * Get the navigation object stored in this instance
+ * @param {Object} req - the Express request object with or without a plugin_id
+ * @return {Function} Promise that resolves with success object or rejects
+ *                                       with error
+ */
+navigationAPI.get = function(req) {
+       return new Promise(function(resolve, reject) {
+               if (req.params.plugin_id) {
+                       var navigation = navigation_manager.getNavigation();
+                       if (navigation[req.params.plugin_id]) {
+                               resolve({
+                                       statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+                                       data: navigation[req.params.plugin_id]
+                               });
+                       } else {
+                               reject({
+                                       statusCode: constants.HTTP_RESPONSE_CODES.ERROR.NOT_FOUND,
+                                       errorMessage: 'No navigation found for plugin_id ' + req.params.plugin_id
+                               });
+                       }
+               } else {
+                       resolve({
+                               statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+                               data: navigation_manager.getNavigation()
+                       });
+               }
+       });
+};
+
+/**
+ * Create the navigation object stored in this instance for a plugin.
+ * To be used across framework instances for informing each other of
+ * inter-instance navigation options.
+ * @param {Object} req - the Express request object
+ * @return {Function} Promise that resolves with success object or rejects
+ *                                       with error
+ */
+navigationAPI.post = function(req) {
+       return new Promise(function(resolve, reject) {
+               var plugin_nav = navigation_manager.getNavigation()[req.params.plugin_id] || {};
+               if (plugin_nav != {}) {
+                       reject({
+                               statusCode: constants.HTTP_RESPONSE_CODES.ERROR.CONFLICT,
+                               errorMessage: 'Navigation for ' + req.params.plugin_id + ' already exist'
+                       });
+               } else {
+                       navigation_manager.addNavigation(req.params.plugin_id, req.body);
+                       resolve({
+                               statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.CREATED,
+                               data: {}
+                       });
+               }
+       });
+};
+
+/**
+ * Update the navigation object stored in this instance for a plugin.
+ * @param {Object} req - the Express request object with a plugin_id and route_id
+ * @return {Function} Promise that resolves with success object or rejects
+ *                                       with error
+ */
+navigationAPI.put = function(req) {
+       return new Promise(function(resolve, reject) {
+               var plugin_nav = navigation_manager.getNavigation()[req.params.plugin_id]['routes'][req.params.route_id];
+               if (plugin_nav == null || plugin_nav == undefined) {
+                       reject({
+                               statusCode: constants.HTTP_RESPONSE_CODES.ERROR.BAD_REQUEST,
+                               errorMessage: 'Navigation for route' + req.params.route_id + ' under plugin ' + req.params.plugin_id + ' does not exist'
+                       });
+               } else {
+                       navigation_manager.addNavigation(req.plugin_id, req.body);
+                       resolve({
+                               statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+                               data: {}
+                       });
+               }
+       });
+};
+
+/**
+ * Delete a particulat route navigation object stored in this instance for a plugin.
+ * @param {Object} req - the Express request object with a plugin_id and route_id
+ * @return {Function} Promise that resolves with success object or rejects
+ *                                       with error
+ */
+navigationAPI.delete = function(req) {
+       return new Promise(function(resolve, reject) {
+               var plugin_nav = navigation_manager.getNavigation()[req.params.plugin_id]['routes'[req.params.route_id]];
+               if (plugin_nav == null || plugin_nav == undefined) {
+                       reject({
+                               statusCode: constants.HTTP_RESPONSE_CODES.ERROR.BAD_REQUEST,
+                               errorMessage: 'Navigation for route' + req.params.route_id + ' under plugin ' + req.params.plugin_id + ' does not exist'
+                       });
+               } else {
+                       navigation_manager.deleteNavigation(req.params.plugin_id, req.params.route_id);
+                       resolve({
+                               statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+                               data: {}
+                       });
+               }
+       });
+};
+
+
+module.exports = navigationAPI;
\ No newline at end of file
diff --git a/skyquake/framework/core/modules/api/restconf.js b/skyquake/framework/core/modules/api/restconf.js
new file mode 100644 (file)
index 0000000..5ba0eb5
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * restconf api module. Provides API functions to interact with RESTCONF
+ * @module framework/core/modules/api/restconf
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var Promise = require('bluebird');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var request = utils.request;
+var restconfAPI = {};
+var _ = require('lodash');
+restconfAPI['streams'] = {};
+
+/**
+ * Get the RESTCONF/Netconf streams from the RESTCONF endpoint
+ * @param {Object} req - the Express request object with or without a plugin_id
+ * @return {Function} Promise that resolves with success object or rejects
+ *                                       with error
+ */
+restconfAPI['streams'].get = function(req) {
+       var api_server = req.query["api_server"];
+    var uri = utils.confdPort(api_server);
+    var url = req.path;
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri + url + '?deep',
+            method: 'GET',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('restconfAPI.streams', error, response, body, resolve, reject)) {
+                // resolve(JSON.parse(response.body))
+                resolve({
+                       statusCode: response.statusCode,
+                       data: JSON.parse(response.body)
+                })
+            };
+        })
+    })
+};
+
+
+module.exports = restconfAPI;
diff --git a/skyquake/framework/core/modules/navigation_manager.js b/skyquake/framework/core/modules/navigation_manager.js
new file mode 100644 (file)
index 0000000..c85eba6
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * navigation_manager module. manages navigation state for a skyquake instance
+ * @module framework/core/modules/navigation_manager
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var path = require('path');
+var fs = require('fs');
+var util = require('util');
+var skyquakeEmitter = require('./skyquakeEmitter');
+require('require-json');
+var _ = require('lodash');
+
+/**
+ * navigation looks like:
+ * {
+ *             "plugin_name": <{routes>}>
+ * }
+ */
+
+var NAVIGATION = {};
+
+function addNavigation(plugin_name, routes) {
+       if (!NAVIGATION[plugin_name]) {
+               NAVIGATION[plugin_name] = {};
+       }
+
+       if (!NAVIGATION[plugin_name].routes) {
+               NAVIGATION[plugin_name].routes = routes;
+       } else {
+               _.extend(NAVIGATION[plugin_name].routes, routes);
+       }
+}
+function addOrder(plugin_name, order) {
+       if (!NAVIGATION[plugin_name]) {
+               NAVIGATION[plugin_name] = {};
+       }
+       NAVIGATION[plugin_name].order = order || 5;
+}
+function addPriority(plugin_name, priority) {
+       if (!NAVIGATION[plugin_name]) {
+               NAVIGATION[plugin_name] = {};
+       }
+       NAVIGATION[plugin_name].priority = priority || 1;
+}
+
+function addLabel(plugin_name, label) {
+       if (!NAVIGATION[plugin_name]) {
+               NAVIGATION[plugin_name] = {};
+       }
+       NAVIGATION[plugin_name].label = label || 'RW.UI Plugin';
+}
+
+function getNavigation() {
+       return NAVIGATION;
+}
+
+function deleteNavigation(plugin_name, route_id) {
+       delete NAVIGATION[plugin_name]['routes'][route_id];
+}
+
+function onNavigationDiscovered(plugin_name, plugin) {
+       addNavigation(plugin_name, plugin.routes);
+       addOrder(plugin_name, plugin.order);
+       addPriority(plugin_name, plugin.priority);
+       addLabel(plugin_name, plugin.name);
+}
+
+function init() {
+       skyquakeEmitter.on('config_discoverer.navigation_discovered', onNavigationDiscovered);
+}
+
+function config(config) {
+
+}
+
+function run() {
+
+}
+
+
+module.exports = {
+       init: init,
+       config: config,
+       run: run,
+       addNavigation: addNavigation,
+       getNavigation: getNavigation
+};
diff --git a/skyquake/framework/core/modules/plugin_discoverer.js b/skyquake/framework/core/modules/plugin_discoverer.js
new file mode 100644 (file)
index 0000000..6653e41
--- /dev/null
@@ -0,0 +1,80 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * plugin_discoverer module. Static plugin discovery at bootstrap
+ * and dynamic plugin discovery during runtime.
+ * @module framework/core/modules/plugin_discoverer
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+var path = require('path');
+var fs = require('fs');
+var util = require('util');
+var skyquakeEmitter = require('./skyquakeEmitter');
+
+
+var plugins_path = '';
+
+/**
+ * Module initialization function
+ */
+function init() {
+
+}
+
+/**
+ * Module configuration function
+ * @param {Object} config - configuration object
+ */
+function config(config) {
+       plugins_path = config.plugins_path;
+}
+
+/**
+ * Module run function.
+ */
+function run() {
+
+       fs.readdir(plugins_path, function(err, filenames) {
+               if (!err) {
+                       filenames.forEach(function(filename) {
+                               fs.stat(plugins_path + '/' + filename, function(err, stats) {
+                                       if (!err) {
+                                               if (stats.isDirectory()) {
+                                                       skyquakeEmitter.emit('plugin_discoverer.plugin_discovered', filename, path.join(plugins_path, path.sep, filename));
+                                               }
+                                       }
+                               });
+                       });
+               }
+       });
+
+       // Watch for modifications and new plugins
+       fs.watch(plugins_path, {persistent: true, recursive: true}, function(event, filename) {
+               var splitPath = filename.split(path.sep)
+               skyquakeEmitter.emit('plugin_discoverer.plugin_updated', splitPath[0], filename);
+       });
+}
+
+
+module.exports = {
+       init: init,
+       config: config,
+       run: run
+};
\ No newline at end of file
diff --git a/skyquake/framework/core/modules/routes/configuration.js b/skyquake/framework/core/modules/routes/configuration.js
new file mode 100644 (file)
index 0000000..3a686f0
--- /dev/null
@@ -0,0 +1,56 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * Node configuration routes module. 
+ * Provides a RESTful API to provide configuration
+ * details such as api_server.
+ * @module framework/core/modules/routes/configuration
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var configurationAPI = require('../api/configuration');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+    extended: true
+}));
+
+Router.put('/server-configuration', cors(), function(req, res) {
+    configurationAPI.update(req).then(function(data) {
+        utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+Router.get('/server-configuration', cors(), function(req, res) {
+    configurationAPI.get(req).then(function(data) {
+        utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+module.exports = Router;
diff --git a/skyquake/framework/core/modules/routes/descriptorModel.js b/skyquake/framework/core/modules/routes/descriptorModel.js
new file mode 100644 (file)
index 0000000..28b7f15
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * inactivity routes module. Provides a RESTful API for this
+ * skyquake instance's inactivity state.
+ * @module framework/core/modules/routes/inactivity
+ * @author Laurence Maultsby <laurence.maultsby@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+var descriptorModelMetaAPI = require('../api/descriptorModelMetaAPI.js');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+    extended: true
+}));
+
+Router.get('/descriptor-model-meta', cors(), function(req, res) {
+    descriptorModelMetaAPI.get(req).then(function(response) {
+        utils.sendSuccessResponse(response, res);
+    }, function(error) {
+        utils.sendErrorResponse(error, res);
+    });
+});
+
+module.exports = Router;
+
+
+
diff --git a/skyquake/framework/core/modules/routes/inactivity.js b/skyquake/framework/core/modules/routes/inactivity.js
new file mode 100644 (file)
index 0000000..7c3c440
--- /dev/null
@@ -0,0 +1,48 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * inactivity routes module. Provides a RESTful API for this
+ * skyquake instance's inactivity state.
+ * @module framework/core/modules/routes/inactivity
+ * @author Laurence Maultsby <laurence.maultsby@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+    extended: true
+}));
+
+Router.get('/inactivity-timeout', cors(), function(req, res) {
+    var response = {
+        statusCode: 200,
+        data: {
+            'inactivity-timeout': process.env.UI_TIMEOUT_SECS || 600000
+        }
+    }
+    utils.sendSuccessResponse(response, res);
+});
+
+module.exports = Router;
diff --git a/skyquake/framework/core/modules/routes/navigation.js b/skyquake/framework/core/modules/routes/navigation.js
new file mode 100644 (file)
index 0000000..82c7ec5
--- /dev/null
@@ -0,0 +1,85 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * navigation routes module. Provides a RESTful API for this
+ * skyquake instance's navigation state.
+ * @module framework/core/modules/routes/navigation
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var navAPI = require('../api/navigation');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+var configurationAPI = require('../api/configuration');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+    extended: true
+}));
+
+Router.get('/', cors(), function(req, res, next) {
+       res.redirect('/launchpad/?api_server=' + req.protocol + '://' + configurationAPI.globalConfiguration.get().api_server + '&upload_server=' + req.protocol + '://' + (configurationAPI.globalConfiguration.get().upload_server || req.hostname));
+});
+
+Router.get('/nav', cors(), function(req, res) {
+       navAPI.get(req).then(function(data) {
+               utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+Router.get('/nav/:plugin_id', cors(), function(req, res) {
+       navAPI.get(req).then(function(data) {
+               utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+Router.post('/nav/:plugin_id', cors(), function(req, res) {
+       navAPI.create(req).then(function(data) {
+               utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+Router.put('/nav/:plugin_id/:route_id', cors(), function(req, res) {
+       navAPI.update(req).then(function(data) {
+               utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+Router.delete('/nav/:plugin_id/:route_id', cors(), function(req, res) {
+       navAPI.delete(req).then(function(data) {
+               utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+
+module.exports = Router;
diff --git a/skyquake/framework/core/modules/routes/restconf.js b/skyquake/framework/core/modules/routes/restconf.js
new file mode 100644 (file)
index 0000000..7a073c5
--- /dev/null
@@ -0,0 +1,47 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * restconf specific routes module. Provides a RESTful API for RESTCONF APIs.
+ * @module framework/core/modules/routes/restconf
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var restconfAPI = require('../api/restconf');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+    extended: true
+}));
+
+Router.get('/api/operational/restconf-state/streams', cors(), function(req, res) {
+    restconfAPI['streams'].get(req).then(function(data) {
+        // res.send(data);
+        utils.sendSuccessResponse(data, res);
+       }, function(error) {
+               utils.sendErrorResponse(error, res);
+       });
+});
+
+module.exports = Router;
diff --git a/skyquake/framework/core/modules/routes/sockets.js b/skyquake/framework/core/modules/routes/sockets.js
new file mode 100644 (file)
index 0000000..da3f3b1
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * socket routes module. Provides a RESTful API for this
+ * skyquake instance's navigation state.
+ * @module framework/core/modules/routes/socket
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+
+var sockets = {};
+
+sockets.routes = function(socketManager) {
+       console.log('Configuring socket routes');
+       Router.use(bodyParser.json());
+       Router.use(cors());
+       Router.use(bodyParser.urlencoded({
+           extended: true
+       }));
+
+       Router.post('/socket-polling', cors(), function(req, res) {
+               socketManager.subscribe(req).then(function(data) {
+                       utils.sendSuccessResponse(data, res);
+               }, function(error) {
+                       utils.sendErrorResponse(error, res);
+               });
+       });
+
+       Router.get('/socket-polling-test', cors(), function(req, res) {
+               utils.sendSuccessResponse({
+                       statusCode: 200,
+                       data: {
+                               message: 'Hello socket polling'
+                       }
+               }, res);
+       });
+}
+
+sockets.router = Router;
+
+module.exports = sockets;
diff --git a/skyquake/framework/core/modules/skyquakeEmitter.js b/skyquake/framework/core/modules/skyquakeEmitter.js
new file mode 100644 (file)
index 0000000..d3cfeb9
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * skyquakeEmitter module. global channel for communication
+ * @module framework/core/modules/skyquakeEmitter
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var events = require('events');
+var skyquakeEmitter = new events.EventEmitter();
+
+module.exports = skyquakeEmitter;
\ No newline at end of file
diff --git a/skyquake/framework/js/gauge-modified.js b/skyquake/framework/js/gauge-modified.js
new file mode 100644 (file)
index 0000000..ad881c3
--- /dev/null
@@ -0,0 +1,1258 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+// (function(window){
+  /**!
+   * @license
+   * HTML5 Canvas Gauge implementation
+   *
+   * This code is subject to MIT license.
+   *
+   * Copyright (c) 2012 Mykhailo Stadnyk <mikhus@gmail.com>
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining a copy of
+   * this software and associated documentation files (the "Software"), to deal in
+   * the Software without restriction, including without limitation the rights to use,
+   * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+   * Software, and to permit persons to whom the Software is furnished to do so,
+   * subject to the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be included in all
+   * copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+   * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+   * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   *
+   * @authors: Mykhailo Stadnyk <mikhus@gmail.com>
+   *           Chris Poile <poile@edwards.usask.ca>
+   *           Luca Invernizzi <http://www.lucainvernizzi.net>
+   *           Robert Blackburn <http://www.rwblackburn.com>
+   */
+
+  /**
+   * @param {Object} config
+   * @constructor
+   */
+  var Gauge = function (config) {
+    Gauge.Collection.push(this);
+
+    /**
+     *  Default gauge configuration
+     *  @struct
+     */
+    this.config = {
+      isAggregate: false,
+      renderTo: null,
+      width: 200,
+      height: 200,
+      title: false,
+      maxValue: 100,
+      minValue: 0,
+      majorTicks: [],
+      minorTicks: 10,
+      strokeTicks: true,
+      units: false,
+      valueFormat: { "int": 3, "dec": 2 },
+      majorTicksFormat: { "int": 1, "dec": 0 },
+      glow: true,
+      animation: {
+        delay: 10,
+        duration: 250,
+        fn: 'cycle'
+      },
+      colors: {
+        plate: '#fff',
+        majorTicks: '#444',
+        minorTicks: '#666',
+        title: '#888',
+        units: '#888',
+        numbers: '#444',
+        needle: { start: 'rgba(240, 128, 128, 1)', end: 'rgba(255, 160, 122, .9)' }
+      },
+      highlights: [
+        {
+          from: 20,
+          to: 60,
+          color: '#eee'
+        },
+        {
+          from: 60,
+          to: 80,
+          color: '#ccc'
+        },
+        {
+          from: 80,
+          to: 100,
+          color: '#999'
+        }
+      ]
+    };
+
+    var
+      value = 0,
+      self = this,
+      fromValue = 0,
+      toValue = 0,
+      imready = false
+      ;
+
+    /**
+     * Sets a new value to gauge and updates the gauge view
+     *
+     * @param {number} val  - the new value to set to the gauge
+     * @return {Gauge} this - returns self
+     */
+    this.setValue = function (val) {
+
+      fromValue = config.animation ? value : val;
+
+      var dv = (config.maxValue - config.minValue) / 100;
+
+      toValue = val > config.maxValue ?
+      config.maxValue + dv :
+        val < config.minValue ?
+        config.minValue - dv :
+          val
+      ;
+
+      value = val;
+
+      if (toValue >= fromValue) {
+        config.arrow = 'up';
+      } else {
+        config.arrow = 'down';
+      }
+
+      config.animation ? animate() : this.draw();
+
+      return this;
+    };
+
+    /**
+     * Sets a new value to gauge and updates the gauge view without
+     * any animation (even if configured)
+     *
+     * @param {number} val  - the new value to set to the gauge
+     * @return {Gauge} this - returns self
+     */
+    this.setRawValue = function (val) {
+      fromValue = value = val;
+      this.draw();
+      return this;
+    };
+
+    /**
+     * Clears the value of the gauge
+     * @return {Gauge}
+     */
+    this.clear = function () {
+      value = fromValue = toValue = this.config.minValue;
+      this.draw();
+      return this;
+    };
+
+
+    /**
+     * Returns the current value been set to the gauge
+     *
+     * @return {number} value - current gauge's value
+     */
+    this.getValue = function () {
+      return value;
+    };
+
+    /**
+     * Ready event for the gauge. Use it whenever you
+     * initialize the gauge to be assured it was fully drawn
+     * before you start the update on it
+     *
+     * @event {Function} onready
+     */
+    this.onready = function () {
+    };
+
+    function applyRecursive(dst, src) {
+      for (var i in src) {
+        // modification by Chris Poile, Oct 08, 2012. More correct check of an Array instance
+        if (typeof src[i] == "object" && !(Object.prototype.toString.call(src[i]) === '[object Array]') && i != 'renderTo') {
+          if (typeof dst[i] != "object") {
+            dst[i] = {};
+          }
+
+          applyRecursive(dst[i], src[i]);
+        } else {
+          dst[i] = src[i];
+        }
+      }
+    };
+
+    applyRecursive(this.config, config);
+
+    this.config.minValue = parseFloat(this.config.minValue);
+    this.config.maxValue = parseFloat(this.config.maxValue);
+
+    config = this.config;
+    fromValue = value = config.minValue;
+
+    if (!config.renderTo) {
+      throw Error("Canvas element was not specified when creating the Gauge object!");
+    }
+
+    var
+      canvas = config.renderTo.tagName ? config.renderTo : document.getElementById(config.renderTo),
+      ctx = canvas.getContext('2d'),
+      cache, CW, CH, CX, CY, max, cctx
+      ;
+
+    function baseInit() {
+      canvas.width = config.width;
+      canvas.height = config.height;
+
+      cache = canvas.cloneNode(true);
+      cctx = cache.getContext('2d');
+      CW = canvas.width;
+      CH = canvas.height;
+      CX = CW / 2;
+      CY = CH / 2;
+      max = CX < CY ? CX : CY;
+
+      cache.i8d = false;
+
+      // translate cache to have 0, 0 in center
+      cctx.translate(CX, CY);
+      cctx.save();
+
+      // translate canvas to have 0,0 in center
+      ctx.translate(CX, CY);
+      ctx.save();
+    };
+
+    // do basic initialization
+    baseInit();
+
+    /**
+     * Updates the gauge config
+     *
+     * @param  {Object} config
+     * @return {Gauge}
+     */
+    this.updateConfig = function (config) {
+      applyRecursive(this.config, config);
+      baseInit();
+      this.draw();
+      return this;
+    };
+
+    var animateFx = {
+      linear: function (p) {
+        return p;
+      },
+      quad: function (p) {
+        return Math.pow(p, 2);
+      },
+      quint: function (p) {
+        return Math.pow(p, 5);
+      },
+      cycle: function (p) {
+        return 1 - Math.sin(Math.acos(p));
+      },
+      bounce: function (p) {
+        return 1 - (function (p) {
+            for (var a = 0, b = 1; 1; a += b, b /= 2) {
+              if (p >= (7 - 4 * a) / 11) {
+                return -Math.pow((11 - 6 * a - 11 * p) / 4, 2) + Math.pow(b, 2);
+              }
+            }
+          })(1 - p);
+      },
+      elastic: function (p) {
+        return 1 - (function (p) {
+            var x = 1.5;
+            return Math.pow(2, 10 * (p - 1)) * Math.cos(20 * Math.PI * x / 3 * p);
+          })(1 - p);
+      }
+    };
+
+    var animateInterval = null;
+
+    function _animate(opts) {
+      var start = new Date;
+
+      animateInterval = setInterval(function () {
+        var
+          timePassed = new Date - start,
+          progress = timePassed / opts.duration
+          ;
+
+        if (progress > 1) {
+          progress = 1;
+        }
+
+        var animateFn = typeof opts.delta == "function" ?
+            opts.delta :
+            animateFx[opts.delta]
+          ;
+
+        var delta = animateFn(progress);
+        opts.step(delta);
+
+        if (progress == 1) {
+          clearInterval(animateInterval);
+        }
+      }, opts.delay || 10);
+    };
+
+    function animate() {
+      animateInterval && clearInterval(animateInterval); // stop previous animation
+      var
+        path = (toValue - fromValue),
+        from = fromValue,
+        cfg = config.animation
+        ;
+
+      _animate({
+        delay: cfg.delay,
+        duration: cfg.duration,
+        delta: cfg.fn,
+        step: function (delta) {
+          fromValue = parseFloat(from) + path * delta;
+          self.draw();
+        }
+      });
+    };
+
+    // defaults
+    ctx.lineCap = "round";
+
+    /**
+     * Drows the gauge. Normally this function should be used to
+     * initally draw the gauge
+     *
+     * @return {Gauge} this - returns the self Gauge object
+     */
+    this.draw = function () {
+      if (!cache.i8d) {
+        // clear the cache
+        cctx.clearRect(-CX, -CY, CW, CH);
+        cctx.save();
+
+        var tmp = {ctx: ctx};
+        ctx = cctx;
+
+        drawPlate();
+        drawHighlights();
+        drawMinorTicks();
+        drawMajorTicks();
+        drawNumbers();
+        drawTitle();
+        drawUnits();
+
+        cache.i8d = true;
+        ctx = tmp.ctx;
+        delete tmp.ctx;
+      }
+
+      // clear the canvas
+      ctx.clearRect(-CX, -CY, CW, CH);
+      ctx.save();
+
+      ctx.drawImage(cache, -CX, -CY, CW, CH);
+
+      if (!Gauge.initialized) {
+        var iv = setInterval(function () {
+          if (!Gauge.initialized) {
+            return;
+          }
+
+          clearInterval(iv);
+
+          drawValueBox();
+          drawNeedle();
+          // drawArrow();
+
+          if (!imready) {
+            self.onready && self.onready();
+            imready = true;
+          }
+        }, 10);
+      } else {
+        drawValueBox();
+        drawNeedle();
+        // drawArrow();
+
+        if (!imready) {
+          self.onready && self.onready();
+          imready = true;
+        }
+      }
+
+      return this;
+    };
+
+    /**
+     * Transforms degrees to radians
+     */
+    function radians(degrees) {
+      return degrees * Math.PI / 180;
+    };
+
+    /**
+     * Linear gradient
+     */
+    function lgrad(clrFrom, clrTo, len) {
+      var grad = ctx.createLinearGradient(0, 0, 0, len);
+      grad.addColorStop(0, clrFrom);
+      grad.addColorStop(1, clrTo);
+
+      return grad;
+    };
+
+    function drawPlate() {
+      var
+        r0 = max / 100 * 93,
+        d0 = max - r0,
+        r1 = max / 100 * 91,
+        d1 = max - r1,
+        r2 = max / 100 * 88,
+        d2 = max - r2,
+        r3 = max / 100 * 85;
+
+      ctx.save();
+
+      if (config.glow) {
+        ctx.shadowBlur = d0;
+        ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
+      }
+
+      ctx.beginPath();
+      ctx.arc(0, 0, r0, 0, Math.PI * 2, true);
+      // ctx.fillStyle = lgrad( '#ddd', '#aaa', r0);
+      ctx.fillStyle = lgrad('hsla(0, 0%, 17%, 1)', 'hsla(0, 0%, 0%, 1)', r0);
+      //ctx.fill();
+
+      //ctx.restore();
+
+      ctx.beginPath();
+      ctx.arc(0, 0, r1, 0, Math.PI * 2, true);
+      // ctx.fillStyle = lgrad( '#fafafa', '#ccc', r1);
+      ctx.fillStyle = lgrad('hsla(0, 0%, 47%, 1)', 'hsla(0, 0%, 33%, 1)', r1);
+      //ctx.fill();
+
+      ctx.beginPath();
+      ctx.arc(0, 0, r2, 0, Math.PI * 2, true);
+      // ctx.fillStyle = lgrad( '#eee', '#f0f0f0', r2);
+      ctx.fillStyle = lgrad('hsla(0, 0%, 33%, 1)', 'hsla(0, 0%, 43%, 1)', r2);
+      //ctx.fill();
+
+      ctx.beginPath();
+      ctx.arc(0, 0, r3, 0, Math.PI * 2, true);
+      ctx.fillStyle = config.colors.plate;
+      //ctx.fill();
+
+      ctx.save();
+    };
+
+    /**
+     * Formats a number for display on the dial's plate using the majorTicksFormat config option.
+     *
+     * @param {number} num The number to format
+     * @returns {string} The formatted number
+     */
+    function formatMajorTickNumber(num) {
+      var r, isDec = false;
+
+      // First, force the correct number of digits right of the decimal.
+      if (config.majorTicksFormat.dec === 0) {
+        r = Math.round(num).toString();
+      } else {
+        r = num.toFixed(config.majorTicksFormat.dec);
+      }
+
+      // Second, force the correct number of digits left of the decimal.
+      if (config.majorTicksFormat["int"] > 1) {
+        // Does this number have a decimal?
+        isDec = (r.indexOf('.') > -1);
+
+        // Is this number a negative number?
+        if (r.indexOf('-') > -1) {
+          return '-' + [
+              config.majorTicksFormat["int"] + config.majorTicksFormat.dec + 2 + (isDec ? 1 : 0) - r.length
+            ].join('0') + r.replace('-', '');
+        } else {
+          return [
+              config.majorTicksFormat["int"] + config.majorTicksFormat.dec + 1 + (isDec ? 1 : 0) - r.length
+            ].join('0') + r;
+        }
+      } else {
+        return r;
+      }
+    }
+
+    // major ticks draw
+    function drawMajorTicks() {
+      var r = max / 100 * 81;
+
+      ctx.lineWidth = 1;
+      ctx.strokeStyle = config.colors.majorTicks;
+      ctx.save();
+
+      if (config.majorTicks.length === 0) {
+        var numberOfDefaultTicks = 5;
+        var tickSize = (config.maxValue - config.minValue) / numberOfDefaultTicks;
+
+        for (var i = 0; i < numberOfDefaultTicks; i++) {
+          config.majorTicks.push(formatMajorTickNumber(config.minValue + (tickSize * i)));
+        }
+        config.majorTicks.push(formatMajorTickNumber(config.maxValue));
+      }
+
+      for (var i = 0; i < config.majorTicks.length; ++i) {
+        var a = 45 + i * (270 / (config.majorTicks.length - 1));
+        ctx.rotate(radians(a));
+
+        ctx.beginPath();
+        ctx.moveTo(0, r);
+        ctx.lineTo(0, r - max / 100 * 15);
+        ctx.stroke();
+
+        ctx.restore();
+        ctx.save();
+      }
+
+      if (config.strokeTicks) {
+        ctx.rotate(radians(90));
+
+        ctx.beginPath();
+        ctx.arc(0, 0, r, radians(45), radians(315), false);
+        ctx.stroke();
+        ctx.restore();
+
+        ctx.save();
+      }
+    };
+
+    // minor ticks draw
+    function drawMinorTicks() {
+      var r = max / 100 * 81;
+
+      ctx.lineWidth = 1;
+      ctx.strokeStyle = config.colors.minorTicks;
+
+      ctx.save();
+
+      var len = config.minorTicks * (config.majorTicks.length - 1);
+
+      for (var i = 0; i < len; ++i) {
+        var a = 45 + i * (270 / len);
+        ctx.rotate(radians(a));
+
+        ctx.beginPath();
+        ctx.moveTo(0, r);
+        ctx.lineTo(0, r - max / 100 * 7.5);
+        ctx.stroke();
+
+        ctx.restore();
+        ctx.save();
+      }
+    };
+
+    // tick numbers draw
+    function drawNumbers() {
+      //var r = max / 100 * 55;
+      //
+      //for (var i = 0; i < config.majorTicks.length; ++i) {
+      //  var
+      //    a = 45 + i * (270 / (config.majorTicks.length - 1)),
+      //    p = rpoint(r, radians(a))
+      //    ;
+      //
+      //  ctx.font = 20 * (max / 200) + "px Arial";
+      //  ctx.fillStyle = config.colors.numbers;
+      //  ctx.lineWidth = 0;
+      //  ctx.textAlign = "center";
+      //  ctx.fillText(config.majorTicks[i], p.x, p.y + 3);
+      //}
+    };
+
+    // title draw
+    function drawTitle() {
+      if (!config.title) {
+        return;
+      }
+
+      ctx.save();
+      ctx.font = 24 * (max / 200) + "px Arial";
+      ctx.fillStyle = config.colors.title;
+      ctx.textAlign = "center";
+      ctx.fillText(config.title, 0, -max / 4.25);
+      ctx.restore();
+    };
+
+    // units draw
+    function drawUnits() {
+      if (!config.units) {
+        return;
+      }
+
+      ctx.save();
+      ctx.font = 22 * (max / 200) + "px Arial";
+      ctx.fillStyle = config.colors.units;
+      ctx.textAlign = "center";
+      ctx.fillText(config.units, 0, max / 3.25);
+      ctx.restore();
+    };
+
+
+    function drawArrow() {
+
+      if (config.arrow != "false") {
+
+        if (config.arrow == "up") {
+          var r = max / 100 * 2.0;
+          y0 = max / 100 * 64;
+          y1 = max / 100 * 55;
+          y2 = max / 100 * 53;
+          y3 = max / 100 * 50;
+          y4 = max / 100 * 45;
+          arrow_color = "rgba(107, 184, 20, 1)";
+
+          var x0 = max / 100 * -8
+          var x1 = max / 100 * -6
+          var x2 = max / 100 * -1.5
+          var x3 = max / 100 * 0
+          var x4 = max / 100 * 1.5
+          var x5 = max / 100 * 6
+          var x6 = max / 100 * 8
+
+          ctx.beginPath();
+          ctx.moveTo(x0, y2);
+          ctx.lineTo(x3 - r, y4 + r);
+          ctx.arcTo(x3, y4 - r, x3 + r, y4 + r, r * 1.09);
+          ctx.lineTo(x6, y2);
+          ctx.arcTo(x6 + r/2.0, y2 + r/1.0, x5, y1, r*.9)
+          ctx.lineTo(x4, y3);
+          ctx.lineTo(x4, y0);
+          ctx.arcTo(x3, y0 + r, x2, y0, r*.9);
+          ctx.lineTo(x2, y3);
+          ctx.lineTo(x1, y1);
+          ctx.arcTo(x1 - r, y1 - r/2.0, x0, y2, r*1.09)
+
+
+          ctx.closePath();
+          ctx.fillStyle = arrow_color;
+          ctx.fill();
+        } else {
+          var r = max / 100 * 2.0;
+          var y0 = max / 100 * 45;
+          var y1 = max / 100 * 54;
+          var y2 = max / 100 * 56;
+          var y3 = max / 100 * 59;
+          var y4 = max / 100 * 64;
+          var arrow_color = "rgba(252, 38, 50, 1)";
+
+          var x0 = max / 100 * -8
+          var x1 = max / 100 * -6
+          var x2 = max / 100 * -1.5
+          var x3 = max / 100 * 0
+          var x4 = max / 100 * 1.5
+          var x5 = max / 100 * 6
+          var x6 = max / 100 * 8
+
+          ctx.beginPath();
+          ctx.moveTo(x0, y2);
+          ctx.lineTo(x3 - r, y4 - r);
+          ctx.arcTo(x3, y4 + r, x3 + r, y4 - r, r * 1.09);
+          ctx.lineTo(x6, y2);
+          ctx.arcTo(x6 + r/2.0, y2 - r/1.0, x5, y1, r*.9)
+          ctx.lineTo(x4, y3);
+          ctx.lineTo(x4, y0);
+          ctx.arcTo(x3, y0 - r, x2, y0, r*.9);
+          ctx.lineTo(x2, y3);
+          ctx.lineTo(x1, y1);
+          ctx.arcTo(x1 - r, y1 + r/2.0, x0, y2, r*1.09)
+
+
+          ctx.closePath();
+          ctx.fillStyle = arrow_color;
+          ctx.fill();
+        }
+        ctx.save();
+        ctx.restore();
+      }
+    }
+
+    function padValue(val) {
+        var cdec = config.valueFormat['dec']
+        var cint = config.valueFormat['int']
+
+      val = parseFloat(val);
+      var n = (val < 0);
+
+      val = Math.abs(val);
+
+      if (cdec > 0) {
+        val = val.toFixed(cdec).toString().split('.');
+
+        for (var i = 0, s = cint - val[0].length; i < s; ++i) {
+          val[0] = '0' + val[0];
+        }
+
+        val = (n ? '-' : '') + val[0] + '.' + val[1];
+      } else {
+        val = Math.round(val).toString();
+
+        for (var i = 0, s = cint - val.length; i < s; ++i) {
+          val = '0' + val;
+        }
+
+        val = (n ? '-' : '') + val
+      }
+
+      return val;
+    };
+
+    function rpoint(r, a) {
+      var
+        x = 0, y = r,
+
+        sin = Math.sin(a),
+        cos = Math.cos(a),
+
+        X = x * cos - y * sin,
+        Y = x * sin + y * cos
+        ;
+
+      return { x: X, y: Y };
+    };
+    function clearCircle(x, y, radius)
+    {
+      ctx.beginPath();
+      ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
+      ctx.clip();
+      ctx.clearRect(x - radius - 1, y - radius - 1,
+        radius * 2 + 2, radius * 2 + 2);
+
+    };
+    // draws the highlight colors
+    function drawHighlights() {
+      ctx.save();
+
+      var r1 = max / 100 * 81;
+      var r2 = r1 - max / 100 * 15;
+
+      for (var i = 0, s = config.highlights.length; i < s; i++) {
+        var
+          hlt = config.highlights[i],
+          vd = (config.maxValue - config.minValue) / 270,
+          sa = radians(45 + (hlt.from - config.minValue) / vd),
+          ea = radians(45 + (hlt.to - config.minValue) / vd)
+          ;
+
+        ctx.beginPath();
+
+        ctx.rotate(radians(90));
+        ctx.arc(0, 0, r1, sa, ea, false);
+        ctx.restore();
+        ctx.save();
+
+        var
+          ps = rpoint(r2, sa),
+          pe = rpoint(r1, sa)
+          ;
+        ctx.moveTo(ps.x, ps.y);
+        ctx.lineTo(pe.x, pe.y);
+
+        var
+          ps1 = rpoint(r1, ea),
+          pe1 = rpoint(r2, ea)
+          ;
+
+        ctx.lineTo(ps1.x, ps1.y);
+        ctx.lineTo(pe1.x, pe1.y);
+        ctx.lineTo(ps.x, ps.y);
+
+        ctx.closePath();
+
+        ctx.fillStyle = hlt.color;
+        ctx.fill();
+
+        ctx.beginPath();
+        ctx.rotate(radians(90));
+        ctx.arc(0, 0, r2, sa - 0.2, ea + 0.2, false);
+        ctx.restore();
+
+        ctx.closePath();
+
+        ctx.fillStyle = config.colors.plate;
+        ctx.fill();
+        ctx.save();
+        ctx.imageSmoothingEnabled = true
+        //clearCircle(0, 0, 100)
+
+      }
+    };
+
+    // drows the gauge needle
+    function drawNeedle() {
+      var
+        r1 = 0 ,
+        r2 = 0 ,
+        rIn = max / 100 * 85,
+        rOut = max / 100 * 63,
+        rP = max / 100 * 59,
+        pad1 = max / 100 * 3,
+        pad2 = max / 100 * 2.5,
+
+        shad = function () {
+          ctx.shadowOffsetX = 2;
+          ctx.shadowOffsetY = 2;
+          ctx.shadowBlur = 10;
+          // ctx.shadowColor   = 'rgba(188, 143, 143, 0.45)';
+          ctx.shadowColor = 'rgba(50, 50, 50, .3)';
+        }
+        ;
+
+      shad();
+
+      ctx.save();
+
+      if (fromValue < 0) {
+        fromValue = Math.abs(config.minValue - fromValue);
+      } else if (config.minValue > 0) {
+        fromValue -= config.minValue
+      } else {
+        fromValue = Math.abs(config.minValue) + fromValue;
+      }
+
+      ctx.rotate(radians(45 + fromValue / ((config.maxValue - config.minValue) / 270)));
+
+      ctx.beginPath();
+      ctx.lineTo(-pad2, rOut);
+      ctx.lineTo(-pad2, rIn);
+      ctx.lineTo(pad2, rIn);
+      ctx.lineTo(pad2, rOut);
+      ctx.lineTo(0, rP);
+      ctx.closePath();
+      ctx.strokeStyle = "#999"
+      ctx.stroke();
+
+      ctx.fillStyle = lgrad(
+        config.colors.needle.start,
+        config.colors.needle.end,
+        rIn - rOut
+      );
+      ctx.fill();
+
+      // ctx.beginPath();
+      // ctx.lineTo(-_pad2, _rOut);
+      // ctx.lineTo(-_pad2, _rIn);
+      // ctx.lineTo(_pad2, _rIn);
+      // ctx.lineTo(_pad2, _rOut);
+      // ctx.lineTo(0, _rOut - 5);
+      // ctx.closePath();
+
+      // ctx.fillStyle = "#ccc"
+      // ctx.fill();
+
+      ctx.beginPath();
+      ctx.lineTo(-pad2, rIn);
+      ctx.lineTo(-pad2, rIn);
+      ctx.lineTo(-pad1, 0);
+      ctx.lineTo(-pad2, rOut);
+      ctx.lineTo(pad2 / 2 - 2, rOut);
+      ctx.closePath();
+      ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
+
+      //ctx.fill();
+
+      ctx.restore();
+
+      //shad();
+
+      ctx.beginPath();
+      ctx.arc(0, 0, r2 +.5, 0, Math.PI * 2, true);
+      // ctx.fillStyle = lgrad( '#f0f0f0', '#ccc', r1);
+      ctx.fillStyle = lgrad('#3b3b3b', '#121212', r1);
+      //ctx.fill();
+
+      ctx.restore();
+
+      ctx.beginPath();
+      ctx.arc(0, 0, r2, 0, Math.PI * 2, true);
+      // ctx.fillStyle = lgrad( "#e8e8e8", "#f5f5f5", r2);
+      ctx.fillStyle = 'rgba(255,255,255,1)';
+      //ctx.fill();
+    };
+
+    function roundRect(x, y, w, h, r) {
+      ctx.beginPath();
+
+      ctx.moveTo(x + r, y);
+      ctx.lineTo(x + w - r, y);
+
+      ctx.quadraticCurveTo(x + w, y, x + w, y + r);
+      ctx.lineTo(x + w, y + h - r);
+
+      ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
+      ctx.lineTo(x + r, y + h);
+
+      ctx.quadraticCurveTo(x, y + h, x, y + h - r);
+      ctx.lineTo(x, y + r);
+
+      ctx.quadraticCurveTo(x, y, x + r, y);
+
+      ctx.closePath();
+    };
+
+    // value box draw
+    function drawValueBox() {
+      ctx.save();
+
+      ctx.font = 100 +  " " + 73 * (max / 200) + "px 'roboto-light";
+      var
+        text = padValue(value),
+        tw = ctx.measureText('-' + padValue(0)).width,
+        y = max - max / 100 * 96,
+        x = 0,
+        th = 0.12 * max
+        ;
+
+      ctx.save();
+
+      roundRect(
+        -tw / 2 - 0.025 * max,
+        y - th - 0.04 * max,
+        tw + 0.05 * max,
+        th + 0.07 * max,
+        0.025 * max
+      );
+
+      var grd = ctx.createRadialGradient(
+        x,
+        y - 0.12 * max - 0.025 * max + (0.12 * max + 0.045 * max) / 2,
+        max / 10,
+        x,
+        y - 0.12 * max - 0.025 * max + (0.12 * max + 0.045 * max) / 2,
+        max / 5
+      );
+
+      // grd.addColorStop( 0, "#888");
+      //    grd.addColorStop( 1, "#666");
+
+      // ctx.strokeStyle = grd;
+      // ctx.lineWidth = 0.05 * max;
+      // ctx.stroke();
+
+      // ctx.shadowBlur  = 0.012 * max;
+      // ctx.shadowColor = 'rgba(0, 0, 0, 1)';
+
+      // ctx.fillStyle = "#babab2";
+      // ctx.fill();
+
+      // ctx.restore();
+
+      // ctx.shadowOffsetX = 0.004 * max;
+      // ctx.shadowOffsetY = 0.004 * max;
+      // ctx.shadowBlur    = 0.012 * max;
+      // ctx.shadowColor   = 'rgba(0, 0, 0, 0.3)';
+
+      // ctx.fillStyle = "#444";
+      ctx.fillStyle = "rgba(50,50,50,1)";
+      //      ctx.fillStyle = "rgba(50,50,50,1)";
+      ctx.textAlign = "center";
+
+      ctx.fillText(text, -x, y);
+
+
+      ctx.save();
+      ctx.font = 100 +  " " + 20 * (max / 200) + "px 'roboto-light";
+      //ctx.fillText(config.unit, -x, y + 30);
+      ctx.restore();
+
+    };
+  };
+
+// initialize
+  Gauge.initialized = false;
+  (function () {
+    var
+      d = document,
+      h = d.getElementsByTagName('head')[0],
+      ie = navigator.userAgent.toLocaleLowerCase().indexOf('msie') != -1,
+      url = 'fonts/digital-7-mono.' + (ie ? 'eot' : 'ttf'),
+
+    // RW: don't use mono font, this was causing err in js console
+      text = '',
+//        text = "@font-face {" +
+//            "font-family: 'Led';" +
+//            "src: url('" + url + "');" +
+//            "}",
+      ss,
+      r = d.createElement('style')
+      ;
+
+    r.type = 'text/css';
+
+    if (ie) {
+      h.appendChild(r);
+      ss = r.styleSheet;
+      ss.cssText = text;
+    } else {
+      try {
+        r.appendChild(d.createTextNode(text));
+      } catch (e) {
+        r.cssText = text;
+      }
+
+      h.appendChild(r);
+
+      ss = r.styleSheet ? r.styleSheet :
+        (r.sheet || d.styleSheets[d.styleSheets.length - 1])
+      ;
+    }
+
+    var iv = setInterval(function () {
+      if (!d.body) {
+        return;
+      }
+
+      clearInterval(iv);
+
+      var dd = d.createElement('div');
+
+      dd.style.fontFamily = 'Led';
+      dd.style.position = 'absolute';
+      dd.style.height = dd.style.width = 0;
+      dd.style.overflow = 'hidden';
+
+      dd.innerHTML = '.';
+
+      d.body.appendChild(dd);
+
+      setTimeout(function () { // no other way to handle font is rendered by a browser
+        // just give the browser around 250ms to do that :(
+        Gauge.initialized = true;
+        dd.parentNode.removeChild(dd);
+      }, 250);
+    }, 1);
+  })();
+
+  Gauge.Collection = [];
+  Gauge.Collection.get = function (id) {
+    var self = this;
+
+    if (typeof(id) == 'string') {
+      for (var i = 0, s = self.length; i < s; i++) {
+        var canvas = self[i].config.renderTo.tagName ? self[i].config.renderTo : document.getElementById(self[i].config.renderTo);
+        if (canvas.getAttribute('id') == id) {
+          return self[i];
+        }
+      }
+    } else if (typeof(id) == 'number') {
+      return self[id];
+    } else {
+      return null;
+    }
+  };
+
+  function domReady(handler) {
+    if (window.addEventListener) {
+      window.addEventListener('DOMContentLoaded', handler, false);
+    } else {
+      window.attachEvent('onload', handler);
+    }
+  }
+
+  domReady(function () {
+    function toCamelCase(arr) {
+      var str = arr[0];
+      for (var i = 1, s = arr.length; i < s; i++) {
+        str += arr[i].substr(0, 1).toUpperCase() + arr[i].substr(1, arr[i].length - 1);
+      }
+      return str;
+    };
+
+    function trim(str) {
+      return str.replace(/^\s+|\s+$/g, '');
+    };
+
+    var c = document.getElementsByTagName('canvas');
+
+    for (var i = 0, s = c.length; i < s; i++) {
+
+      if (c[i].getAttribute('data-type') == 'canv-gauge') {
+        var
+          gauge = c[i],
+          config = {},
+          prop,
+          w = parseInt(gauge.getAttribute('width'), 10),
+          h = parseInt(gauge.getAttribute('height'), 10)
+          ;
+
+        config.renderTo = gauge;
+
+        if (w) {
+          config.width = w;
+        }
+
+        if (h) {
+          config.height = h;
+        }
+
+        for (var ii = 0, ss = gauge.attributes.length; ii < ss; ii++) {
+          prop = gauge.attributes.item(ii).nodeName;
+
+          if (prop != 'data-type' && prop.substr(0, 5) == 'data-') {
+            var
+              cfgProp = prop.substr(5, prop.length - 5).toLowerCase().split('-'),
+              attrValue = gauge.getAttribute(prop)
+              ;
+
+            if (!attrValue) {
+              continue;
+            }
+
+            switch (cfgProp[0]) {
+              case 'colors' :
+              {
+                if (cfgProp[1]) {
+                  if (!config.colors) {
+                    config.colors = {};
+                  }
+
+                  if (cfgProp[1] == 'needle') {
+                    var parts = attrValue.split(/\s+/);
+
+                    if (parts[0] && parts[1]) {
+                      config.colors.needle = { start: parts[0], end: parts[1] };
+                    }
+                    else {
+                      config.colors.needle = attrValue;
+                    }
+                  }
+                  else {
+                    cfgProp.shift();
+                    config.colors[toCamelCase(cfgProp)] = attrValue;
+                  }
+                }
+                break;
+              }
+              case 'highlights' :
+              {
+                if (!config.highlights) {
+                  config.highlights = [];
+                }
+
+                var hls = attrValue.match(/(?:(?:-?\d*\.)?(-?\d+){1,2} ){2}(?:(?:#|0x)?(?:[0-9A-F|a-f]){3,8}|rgba?\(.*?\))/g);
+
+                for (var j = 0, l = hls.length; j < l; j++) {
+                  var
+                    cfg = trim(hls[j]).split(/\s+/),
+                    hlCfg = {}
+                    ;
+
+                  if (cfg[0] && cfg[0] != '') {
+                    hlCfg.from = cfg[0];
+                  }
+
+                  if (cfg[1] && cfg[1] != '') {
+                    hlCfg.to = cfg[1];
+                  }
+
+                  if (cfg[2] && cfg[2] != '') {
+                    hlCfg.color = cfg[2];
+                  }
+
+                  config.highlights.push(hlCfg);
+                }
+                break;
+              }
+              case 'animation' :
+              {
+                if (cfgProp[1]) {
+                  if (!config.animation) {
+                    config.animation = {};
+                  }
+
+                  if (cfgProp[1] == 'fn' && /^\s*function\s*\(/.test(attrValue)) {
+                    attrValue = eval('(' + attrValue + ')');
+                  }
+
+                  config.animation[cfgProp[1]] = attrValue;
+                }
+                break;
+              }
+              default :
+              {
+                var cfgName = toCamelCase(cfgProp);
+
+                if (cfgName == 'onready') {
+                  continue;
+                }
+
+                if (cfgName == 'majorTicks') {
+                  attrValue = attrValue.split(/\s+/);
+                }
+                else if (cfgName == 'strokeTicks' || cfgName == 'glow') {
+                  attrValue = attrValue == 'true' ? true : false;
+                }
+                else if (cfgName == 'valueFormat') {
+                  var val = attrValue.split('.');
+
+                  if (val.length == 2) {
+                    attrValue = {
+                      'int': parseInt(val[0], 10),
+                      'dec': parseInt(val[1], 10)
+                    }
+                  }
+                  else {
+                    continue;
+                  }
+                }
+
+                config[cfgName] = attrValue;
+                break;
+              }
+            }
+          }
+        }
+
+        var g = new Gauge(config);
+
+        if (gauge.getAttribute('data-value')) {
+          g.setRawValue(parseFloat(gauge.getAttribute('data-value')));
+        }
+
+        if (gauge.getAttribute('data-onready')) {
+          g.onready = function () {
+            eval(this.config.renderTo.getAttribute('data-onready'));
+          };
+        }
+
+        g.draw();
+      }
+    }
+  });
+module.exports = Gauge;
+  // window['Gauge'] = Gauge;
+
+// })(window);
diff --git a/skyquake/framework/js/n3-line-chart.js b/skyquake/framework/js/n3-line-chart.js
new file mode 100644 (file)
index 0000000..b3105cd
--- /dev/null
@@ -0,0 +1,1821 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/*
+line-chart - v1.1.9 - 21 June 2015
+https://github.com/n3-charts/line-chart
+Copyright (c) 2015 n3-charts
+ */
+var directive, m, mod, old_m,
+  __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+old_m = angular.module('n3-charts.linechart', ['n3charts.utils']);
+
+m = angular.module('n3-line-chart', ['n3charts.utils']);
+
+directive = function(name, conf) {
+  old_m.directive(name, conf);
+  return m.directive(name, conf);
+};
+
+directive('linechart', [
+  'n3utils', '$window', '$timeout', function(n3utils, $window, $timeout) {
+    var link;
+    link = function(scope, element, attrs, ctrl) {
+      var dispatch, id, initialHandlers, isUpdatingOptions, promise, updateEvents, window_resize, _u;
+      _u = n3utils;
+      dispatch = _u.getEventDispatcher();
+      id = _u.uuid();
+      element[0].style['font-size'] = 0;
+      scope.redraw = function() {
+        scope.update();
+      };
+      isUpdatingOptions = false;
+      initialHandlers = {
+        onSeriesVisibilityChange: function(_arg) {
+          var index, newVisibility, series;
+          series = _arg.series, index = _arg.index, newVisibility = _arg.newVisibility;
+          scope.options.series[index].visible = newVisibility;
+          return scope.$apply();
+        }
+      };
+      scope.update = function() {
+        var axes, columnWidth, dataPerSeries, dimensions, fn, handlers, isThumbnail, options, svg;
+        options = _u.sanitizeOptions(scope.options, attrs.mode);
+        handlers = angular.extend(initialHandlers, _u.getTooltipHandlers(options));
+        dataPerSeries = _u.getDataPerSeries(scope.data, options);
+        dimensions = _u.getDimensions(options, element, attrs);
+        isThumbnail = attrs.mode === 'thumbnail';
+        _u.clean(element[0]);
+        svg = _u.bootstrap(element[0], id, dimensions);
+        fn = function(key) {
+          return (options.series.filter(function(s) {
+            return s.axis === key && s.visible !== false;
+          })).length > 0;
+        };
+        axes = _u.createAxes(svg, dimensions, options.axes).andAddThemIf({
+          all: !isThumbnail,
+          x: true,
+          y: fn('y'),
+          y2: fn('y2')
+        });
+        if (dataPerSeries.length) {
+          _u.setScalesDomain(axes, scope.data, options.series, svg, options);
+        }
+        _u.createContent(svg, id, options, handlers);
+        if (dataPerSeries.length) {
+          columnWidth = _u.getBestColumnWidth(axes, dimensions, dataPerSeries, options);
+          _u.drawArea(svg, axes, dataPerSeries, options, handlers).drawColumns(svg, axes, dataPerSeries, columnWidth, options, handlers, dispatch).drawLines(svg, axes, dataPerSeries, options, handlers);
+          if (options.drawDots) {
+            _u.drawDots(svg, axes, dataPerSeries, options, handlers, dispatch);
+          }
+        }
+        if (options.drawLegend) {
+          _u.drawLegend(svg, options.series, dimensions, handlers, dispatch);
+        }
+        if (options.tooltip.mode === 'scrubber') {
+          return _u.createGlass(svg, dimensions, handlers, axes, dataPerSeries, options, dispatch, columnWidth);
+        } else if (options.tooltip.mode !== 'none') {
+          return _u.addTooltips(svg, dimensions, options.axes);
+        }
+      };
+      updateEvents = function() {
+        if (scope.oldclick) {
+          dispatch.on('click', scope.oldclick);
+        } else if (scope.click) {
+          dispatch.on('click', scope.click);
+        } else {
+          dispatch.on('click', null);
+        }
+        if (scope.oldhover) {
+          dispatch.on('hover', scope.oldhover);
+        } else if (scope.hover) {
+          dispatch.on('hover', scope.hover);
+        } else {
+          dispatch.on('hover', null);
+        }
+        if (scope.oldfocus) {
+          dispatch.on('focus', scope.oldfocus);
+        } else if (scope.focus) {
+          dispatch.on('focus', scope.focus);
+        } else {
+          dispatch.on('focus', null);
+        }
+        if (scope.toggle) {
+          return dispatch.on('toggle', scope.toggle);
+        } else {
+          return dispatch.on('toggle', null);
+        }
+      };
+      promise = void 0;
+      window_resize = function() {
+        if (promise != null) {
+          $timeout.cancel(promise);
+        }
+        return promise = $timeout(scope.redraw, 1);
+      };
+      $window.addEventListener('resize', window_resize);
+      scope.$watch('data', scope.redraw, true);
+      scope.$watch('options', scope.redraw, true);
+      scope.$watchCollection('[click, hover, focus, toggle]', updateEvents);
+      scope.$watchCollection('[oldclick, oldhover, oldfocus]', updateEvents);
+      console.log('data', scope.data)
+      window_resize();
+    };
+    return {
+      replace: true,
+      restrict: 'E',
+      scope: {
+        data: '=',
+        options: '=',
+        oldclick: '=click',
+        oldhover: '=hover',
+        oldfocus: '=focus',
+        click: '=onClick',
+        hover: '=onHover',
+        focus: '=onFocus',
+        toggle: '=onToggle'
+      },
+      template: '<div></div>',
+      link: link
+    };
+  }
+]);
+
+mod = angular.module('n3charts.utils', []);
+
+mod.factory('n3utils', [
+  '$window', '$log', '$rootScope', function($window, $log, $rootScope) {
+    return {
+      addPatterns: function(svg, series) {
+        var pattern;
+        pattern = svg.select('defs').selectAll('pattern').data(series.filter(function(s) {
+          return s.striped;
+        })).enter().append('pattern').attr({
+          id: function(s) {
+            return s.type + 'Pattern_' + s.index;
+          },
+          patternUnits: "userSpaceOnUse",
+          x: 0,
+          y: 0,
+          width: 60,
+          height: 60
+        }).append('g').style({
+          'fill': function(s) {
+            return s.color;
+          },
+          'fill-opacity': 0.3
+        });
+        pattern.append('rect').style('fill-opacity', 0.3).attr('width', 60).attr('height', 60);
+        pattern.append('path').attr('d', "M 10 0 l10 0 l -20 20 l 0 -10 z");
+        pattern.append('path').attr('d', "M40 0 l10 0 l-50 50 l0 -10 z");
+        pattern.append('path').attr('d', "M60 10 l0 10 l-40 40 l-10 0 z");
+        return pattern.append('path').attr('d', "M60 40 l0 10 l-10 10 l -10 0 z");
+      },
+      drawArea: function(svg, scales, data, options) {
+        var areaSeries, drawers;
+        areaSeries = data.filter(function(series) {
+          return series.type === 'area';
+        });
+        this.addPatterns(svg, areaSeries);
+        drawers = {
+          y: this.createLeftAreaDrawer(scales, options.lineMode, options.tension),
+          y2: this.createRightAreaDrawer(scales, options.lineMode, options.tension)
+        };
+        svg.select('.content').selectAll('.areaGroup').data(areaSeries).enter().append('g').attr('class', function(s) {
+          return 'areaGroup ' + 'series_' + s.index;
+        }).append('path').attr('class', 'area').style('fill', function(s) {
+          if (s.striped !== true) {
+            return s.color;
+          }
+          return "url(#areaPattern_" + s.index + ")";
+        }).style('opacity', function(s) {
+          if (s.striped) {
+            return '1';
+          } else {
+            return '0.3';
+          }
+        }).attr('d', function(d) {
+          return drawers[d.axis](d.values);
+        });
+        return this;
+      },
+      createLeftAreaDrawer: function(scales, mode, tension) {
+        return d3.svg.area().x(function(d) {
+          return scales.xScale(d.x);
+        }).y0(function(d) {
+          return scales.yScale(d.y0);
+        }).y1(function(d) {
+          return scales.yScale(d.y0 + d.y);
+        }).interpolate(mode).tension(tension);
+      },
+      createRightAreaDrawer: function(scales, mode, tension) {
+        return d3.svg.area().x(function(d) {
+          return scales.xScale(d.x);
+        }).y0(function(d) {
+          return scales.y2Scale(d.y0);
+        }).y1(function(d) {
+          return scales.y2Scale(d.y0 + d.y);
+        }).interpolate(mode).tension(tension);
+      },
+      getPseudoColumns: function(data, options) {
+        var keys, pseudoColumns;
+        data = data.filter(function(s) {
+          return s.type === 'column';
+        });
+        pseudoColumns = {};
+        keys = [];
+        data.forEach(function(series) {
+          var i, inAStack, index;
+          inAStack = false;
+          options.stacks.forEach(function(stack, index) {
+            var _ref;
+            if ((series.id != null) && (_ref = series.id, __indexOf.call(stack.series, _ref) >= 0)) {
+              pseudoColumns[series.id] = index;
+              if (__indexOf.call(keys, index) < 0) {
+                keys.push(index);
+              }
+              return inAStack = true;
+            }
+          });
+          if (inAStack === false) {
+            i = pseudoColumns[series.id] = index = keys.length;
+            return keys.push(i);
+          }
+        });
+        return {
+          pseudoColumns: pseudoColumns,
+          keys: keys
+        };
+      },
+      getMinDelta: function(seriesData, key, scale, range) {
+        return d3.min(seriesData.map(function(series) {
+          return series.values.map(function(d) {
+            return scale(d[key]);
+          }).filter(function(e) {
+            if (range) {
+              return e >= range[0] && e <= range[1];
+            } else {
+              return true;
+            }
+          }).reduce(function(prev, cur, i, arr) {
+            var diff;
+            diff = i > 0 ? cur - arr[i - 1] : Number.MAX_VALUE;
+            if (diff < prev) {
+              return diff;
+            } else {
+              return prev;
+            }
+          }, Number.MAX_VALUE);
+        }));
+      },
+      getBestColumnWidth: function(axes, dimensions, seriesData, options) {
+        var colData, delta, innerWidth, keys, nSeries, pseudoColumns, _ref;
+        if (!(seriesData && seriesData.length !== 0)) {
+          return 10;
+        }
+        if ((seriesData.filter(function(s) {
+          return s.type === 'column';
+        })).length === 0) {
+          return 10;
+        }
+        _ref = this.getPseudoColumns(seriesData, options), pseudoColumns = _ref.pseudoColumns, keys = _ref.keys;
+        innerWidth = dimensions.width - dimensions.left - dimensions.right;
+        colData = seriesData.filter(function(d) {
+          return pseudoColumns.hasOwnProperty(d.id);
+        });
+        delta = this.getMinDelta(colData, 'x', axes.xScale, [0, innerWidth]);
+        if (delta > innerWidth) {
+          delta = 0.25 * innerWidth;
+        }
+        nSeries = keys.length;
+        return parseInt((delta - options.columnsHGap) / nSeries);
+      },
+      getColumnAxis: function(data, columnWidth, options) {
+        var keys, pseudoColumns, x1, _ref;
+        _ref = this.getPseudoColumns(data, options), pseudoColumns = _ref.pseudoColumns, keys = _ref.keys;
+        x1 = d3.scale.ordinal().domain(keys).rangeBands([0, keys.length * columnWidth], 0);
+        return function(s) {
+          var index;
+          if (pseudoColumns[s.id] == null) {
+            return 0;
+          }
+          index = pseudoColumns[s.id];
+          return x1(index) - keys.length * columnWidth / 2;
+        };
+      },
+      drawColumns: function(svg, axes, data, columnWidth, options, handlers, dispatch) {
+        var colGroup, x1;
+        data = data.filter(function(s) {
+          return s.type === 'column';
+        });
+        x1 = this.getColumnAxis(data, columnWidth, options);
+        data.forEach(function(s) {
+          return s.xOffset = x1(s) + columnWidth * .5;
+        });
+        colGroup = svg.select('.content').selectAll('.columnGroup').data(data).enter().append("g").attr('class', function(s) {
+          return 'columnGroup series_' + s.index;
+        }).attr('transform', function(s) {
+          return "translate(" + x1(s) + ",0)";
+        });
+        colGroup.each(function(series) {
+          return d3.select(this).selectAll("rect").data(series.values).enter().append("rect").style({
+            'stroke': series.color,
+            'fill': series.color,
+            'stroke-opacity': function(d) {
+              if (d.y === 0) {
+                return '0';
+              } else {
+                return '1';
+              }
+            },
+            'stroke-width': '1px',
+            'fill-opacity': function(d) {
+              if (d.y === 0) {
+                return 0;
+              } else {
+                return 0.7;
+              }
+            }
+          }).attr({
+            width: columnWidth,
+            x: function(d) {
+              return axes.xScale(d.x);
+            },
+            height: function(d) {
+              if (d.y === 0) {
+                return axes[d.axis + 'Scale'].range()[0];
+              }
+              return Math.abs(axes[d.axis + 'Scale'](d.y0 + d.y) - axes[d.axis + 'Scale'](d.y0));
+            },
+            y: function(d) {
+              if (d.y === 0) {
+                return 0;
+              } else {
+                return axes[d.axis + 'Scale'](Math.max(0, d.y0 + d.y));
+              }
+            }
+          }).on({
+            'click': function(d, i) {
+              return dispatch.click(d, i);
+            }
+          }).on('mouseover', function(d, i) {
+            dispatch.hover(d, i);
+            return typeof handlers.onMouseOver === "function" ? handlers.onMouseOver(svg, {
+              series: series,
+              x: axes.xScale(d.x),
+              y: axes[d.axis + 'Scale'](d.y0 + d.y),
+              datum: d
+            }, options.axes) : void 0;
+          }).on('mouseout', function(d) {
+            return typeof handlers.onMouseOut === "function" ? handlers.onMouseOut(svg) : void 0;
+          });
+        });
+        return this;
+      },
+      drawDots: function(svg, axes, data, options, handlers, dispatch) {
+        var dotGroup;
+        dotGroup = svg.select('.content').selectAll('.dotGroup').data(data.filter(function(s) {
+          var _ref;
+          return ((_ref = s.type) === 'line' || _ref === 'area') && s.drawDots;
+        })).enter().append('g');
+        dotGroup.attr({
+          "class": function(s) {
+            return "dotGroup series_" + s.index;
+          },
+          fill: function(s) {
+            return s.color;
+          }
+        }).selectAll('.dot').data(function(d) {
+          return d.values;
+        }).enter().append('circle').attr({
+          'class': 'dot',
+          'r': function(d) {
+            return d.dotSize;
+          },
+          'cx': function(d) {
+            return axes.xScale(d.x);
+          },
+          'cy': function(d) {
+            return axes[d.axis + 'Scale'](d.y + d.y0);
+          }
+        }).style({
+          'stroke': 'white',
+          'stroke-width': '2px'
+        }).on({
+          'click': function(d, i) {
+            return dispatch.click(d, i);
+          }
+        }).on({
+          'mouseover': function(d, i) {
+            return dispatch.hover(d, i);
+          }
+        });
+        if (options.tooltip.mode !== 'none') {
+          dotGroup.on('mouseover', function(series) {
+            var d, target;
+            target = d3.select(d3.event.target);
+            d = target.datum();
+            target.attr('r', function(s) {
+              return s.dotSize + 2;
+            });
+            return typeof handlers.onMouseOver === "function" ? handlers.onMouseOver(svg, {
+              series: series,
+              x: target.attr('cx'),
+              y: target.attr('cy'),
+              datum: d
+            }, options.axes) : void 0;
+          }).on('mouseout', function(d) {
+            d3.select(d3.event.target).attr('r', function(s) {
+              return s.dotSize;
+            });
+            return typeof handlers.onMouseOut === "function" ? handlers.onMouseOut(svg) : void 0;
+          });
+        }
+        return this;
+      },
+      getEventDispatcher: function() {
+        var events;
+        events = ['focus', 'hover', 'click', 'toggle'];
+        return d3.dispatch.apply(this, events);
+      },
+      computeLegendLayout: function(svg, series, dimensions) {
+        var cumul, i, j, leftLayout, leftWidths, padding, rightLayout, rightWidths, that, w;
+        padding = 10;
+        that = this;
+        leftWidths = this.getLegendItemsWidths(svg, 'y');
+        leftLayout = [0];
+        i = 1;
+        while (i < leftWidths.length) {
+          leftLayout.push(leftWidths[i - 1] + leftLayout[i - 1] + padding);
+          i++;
+        }
+        rightWidths = this.getLegendItemsWidths(svg, 'y2');
+        if (!(rightWidths.length > 0)) {
+          return [leftLayout];
+        }
+        w = dimensions.width - dimensions.right - dimensions.left;
+        cumul = 0;
+        rightLayout = [];
+        j = rightWidths.length - 1;
+        while (j >= 0) {
+          rightLayout.push(w - cumul - rightWidths[j]);
+          cumul += rightWidths[j] + padding;
+          j--;
+        }
+        rightLayout.reverse();
+        return [leftLayout, rightLayout];
+      },
+      getLegendItemsWidths: function(svg, axis) {
+        var bbox, i, items, that, widths;
+        that = this;
+        bbox = function(t) {
+          return that.getTextBBox(t).width;
+        };
+        items = svg.selectAll(".legendItem." + axis);
+        if (!(items.length > 0)) {
+          return [];
+        }
+        widths = [];
+        i = 0;
+        while (i < items[0].length) {
+          widths.push(bbox(items[0][i]));
+          i++;
+        }
+        return widths;
+      },
+      drawLegend: function(svg, series, dimensions, handlers, dispatch) {
+        var d, groups, legend, that, translateLegends;
+        that = this;
+        legend = svg.append('g').attr('class', 'legend');
+        d = 16;
+        svg.select('defs').append('svg:clipPath').attr('id', 'legend-clip').append('circle').attr('r', d / 2);
+        groups = legend.selectAll('.legendItem').data(series);
+        groups.enter().append('g').on('click', function(s, i) {
+          var visibility;
+          visibility = !(s.visible !== false);
+          dispatch.toggle(s, i, visibility);
+          return typeof handlers.onSeriesVisibilityChange === "function" ? handlers.onSeriesVisibilityChange({
+            series: s,
+            index: i,
+            newVisibility: visibility
+          }) : void 0;
+        });
+        groups.attr({
+          'class': function(s, i) {
+            return "legendItem series_" + i + " " + s.axis;
+          },
+          'opacity': function(s, i) {
+            if (s.visible === false) {
+              that.toggleSeries(svg, i);
+              return '0.2';
+            }
+            return '1';
+          }
+        }).each(function(s) {
+          var item, _ref;
+          item = d3.select(this);
+          item.append('circle').attr({
+            'fill': s.color,
+            'stroke': s.color,
+            'stroke-width': '2px',
+            'r': d / 2
+          });
+          item.append('path').attr({
+            'clip-path': 'url(#legend-clip)',
+            'fill-opacity': (_ref = s.type) === 'area' || _ref === 'column' ? '1' : '0',
+            'fill': 'white',
+            'stroke': 'white',
+            'stroke-width': '2px',
+            'd': that.getLegendItemPath(s, d, d)
+          });
+          item.append('circle').attr({
+            'fill-opacity': 0,
+            'stroke': s.color,
+            'stroke-width': '2px',
+            'r': d / 2
+          });
+          return item.append('text').attr({
+            'class': function(d, i) {
+              return "legendText series_" + i;
+            },
+            'font-family': 'Courier',
+            'font-size': 10,
+            'transform': 'translate(13, 4)',
+            'text-rendering': 'geometric-precision'
+          }).text(s.label || s.y);
+        });
+        translateLegends = function() {
+          var left, right, _ref;
+          _ref = that.computeLegendLayout(svg, series, dimensions), left = _ref[0], right = _ref[1];
+          return groups.attr({
+            'transform': function(s, i) {
+              if (s.axis === 'y') {
+                return "translate(" + (left.shift()) + "," + (dimensions.height - 40) + ")";
+              } else {
+                return "translate(" + (right.shift()) + "," + (dimensions.height - 40) + ")";
+              }
+            }
+          });
+        };
+        translateLegends();
+        setTimeout(translateLegends, 0);
+        return this;
+      },
+      getLegendItemPath: function(series, w, h) {
+        var base_path, path;
+        if (series.type === 'column') {
+          path = 'M' + (-w / 3) + ' ' + (-h / 8) + ' l0 ' + h + ' ';
+          path += 'M0' + ' ' + (-h / 3) + ' l0 ' + h + ' ';
+          path += 'M' + w / 3 + ' ' + (-h / 10) + ' l0 ' + h + ' ';
+          return path;
+        }
+        base_path = 'M-' + w / 2 + ' 0' + h / 3 + ' l' + w / 3 + ' -' + h / 3 + ' l' + w / 3 + ' ' + h / 3 + ' l' + w / 3 + ' -' + 2 * h / 3;
+        if (series.type === 'area') {
+          base_path + ' l0 ' + h + ' l-' + w + ' 0z';
+        }
+        return base_path;
+      },
+      toggleSeries: function(svg, index) {
+        var isVisible;
+        isVisible = false;
+        svg.select('.content').selectAll('.series_' + index).style('display', function(s) {
+          if (d3.select(this).style('display') === 'none') {
+            isVisible = true;
+            return 'initial';
+          } else {
+            isVisible = false;
+            return 'none';
+          }
+        });
+        return isVisible;
+      },
+      drawLines: function(svg, scales, data, options, handlers) {
+        var drawers, interpolateData, lineGroup;
+        drawers = {
+          y: this.createLeftLineDrawer(scales, options.lineMode, options.tension),
+          y2: this.createRightLineDrawer(scales, options.lineMode, options.tension)
+        };
+        lineGroup = svg.select('.content').selectAll('.lineGroup').data(data.filter(function(s) {
+          var _ref;
+          return (_ref = s.type) === 'line' || _ref === 'area';
+        })).enter().append('g');
+        lineGroup.style('stroke', function(s) {
+          return s.color;
+        }).attr('class', function(s) {
+          return "lineGroup series_" + s.index;
+        }).append('path').attr({
+          "class": 'line',
+          d: function(d) {
+            return drawers[d.axis](d.values);
+          }
+        }).style({
+          'fill': 'none',
+          'stroke-width': function(s) {
+            return s.thickness;
+          },
+          'stroke-dasharray': function(s) {
+            if (s.lineMode === 'dashed') {
+              return '10,3';
+            }
+            return void 0;
+          }
+        });
+        if (options.tooltip.interpolate) {
+          interpolateData = function(series) {
+            var datum, error, i, interpDatum, maxXPos, maxXValue, maxYPos, maxYValue, minXPos, minXValue, minYPos, minYValue, mousePos, target, valuesData, x, xPercentage, xVal, y, yPercentage, yVal, _i, _len;
+            target = d3.select(d3.event.target);
+            try {
+              mousePos = d3.mouse(this);
+            } catch (_error) {
+              error = _error;
+              mousePos = [0, 0];
+            }
+            valuesData = target.datum().values;
+            for (i = _i = 0, _len = valuesData.length; _i < _len; i = ++_i) {
+              datum = valuesData[i];
+              x = scales.xScale(datum.x);
+              y = scales.yScale(datum.y);
+              if ((typeof minXPos === "undefined" || minXPos === null) || x < minXPos) {
+                minXPos = x;
+                minXValue = datum.x;
+              }
+              if ((typeof maxXPos === "undefined" || maxXPos === null) || x > maxXPos) {
+                maxXPos = x;
+                maxXValue = datum.x;
+              }
+              if ((typeof minYPos === "undefined" || minYPos === null) || y < minYPos) {
+                minYPos = y;
+              }
+              if ((typeof maxYPos === "undefined" || maxYPos === null) || y > maxYPos) {
+                maxYPos = y;
+              }
+              if ((typeof minYValue === "undefined" || minYValue === null) || datum.y < minYValue) {
+                minYValue = datum.y;
+              }
+              if ((typeof maxYValue === "undefined" || maxYValue === null) || datum.y > maxYValue) {
+                maxYValue = datum.y;
+              }
+            }
+            xPercentage = (mousePos[0] - minXPos) / (maxXPos - minXPos);
+            yPercentage = (mousePos[1] - minYPos) / (maxYPos - minYPos);
+            xVal = Math.round(xPercentage * (maxXValue - minXValue) + minXValue);
+            yVal = Math.round((1 - yPercentage) * (maxYValue - minYValue) + minYValue);
+            interpDatum = {
+              x: xVal,
+              y: yVal
+            };
+            return typeof handlers.onMouseOver === "function" ? handlers.onMouseOver(svg, {
+              series: series,
+              x: mousePos[0],
+              y: mousePos[1],
+              datum: interpDatum
+            }, options.axes) : void 0;
+          };
+          lineGroup.on('mousemove', interpolateData).on('mouseout', function(d) {
+            return typeof handlers.onMouseOut === "function" ? handlers.onMouseOut(svg) : void 0;
+          });
+        }
+        return this;
+      },
+      createLeftLineDrawer: function(scales, mode, tension) {
+        return d3.svg.line().x(function(d) {
+          return scales.xScale(d.x);
+        }).y(function(d) {
+          return scales.yScale(d.y + d.y0);
+        }).interpolate(mode).tension(tension);
+      },
+      createRightLineDrawer: function(scales, mode, tension) {
+        return d3.svg.line().x(function(d) {
+          return scales.xScale(d.x);
+        }).y(function(d) {
+          return scales.y2Scale(d.y + d.y0);
+        }).interpolate(mode).tension(tension);
+      },
+      getPixelCssProp: function(element, propertyName) {
+        var string;
+        string = $window.getComputedStyle(element, null).getPropertyValue(propertyName);
+        return +string.replace(/px$/, '');
+      },
+      getDefaultMargins: function() {
+        return {
+          top: 20,
+          right: 50,
+          bottom: 60,
+          left: 50
+        };
+      },
+      getDefaultThumbnailMargins: function() {
+        return {
+          top: 1,
+          right: 1,
+          bottom: 2,
+          left: 0
+        };
+      },
+      getElementDimensions: function(element, width, height) {
+        var bottom, dim, left, parent, right, top;
+        dim = {};
+        parent = element;
+        top = this.getPixelCssProp(parent, 'padding-top');
+        bottom = this.getPixelCssProp(parent, 'padding-bottom');
+        left = this.getPixelCssProp(parent, 'padding-left');
+        right = this.getPixelCssProp(parent, 'padding-right');
+        dim.width = +(width || parent.offsetWidth || 900) - left - right;
+        dim.height = +(height || parent.offsetHeight || 500) - top - bottom;
+        return dim;
+      },
+      getDimensions: function(options, element, attrs) {
+        var dim;
+        dim = this.getElementDimensions(element[0].parentElement, attrs.width, attrs.height);
+        dim = angular.extend(options.margin, dim);
+        return dim;
+      },
+      clean: function(element) {
+        return d3.select(element).on('keydown', null).on('keyup', null).select('svg').remove();
+      },
+      uuid: function() {
+        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+          var r, v;
+          r = Math.random() * 16 | 0;
+          v = c === 'x' ? r : r & 0x3 | 0x8;
+          return v.toString(16);
+        });
+      },
+      bootstrap: function(element, id, dimensions) {
+        var defs, height, svg, width;
+        d3.select(element).classed('chart', true);
+        width = dimensions.width;
+        height = dimensions.height;
+        svg = d3.select(element).append('svg').attr({
+          width: width,
+          height: height
+        }).append('g').attr('transform', 'translate(' + dimensions.left + ',' + dimensions.top + ')');
+        defs = svg.append('defs').attr('class', 'patterns');
+        defs.append('clipPath').attr('class', 'content-clip').attr('id', "content-clip-" + id).append('rect').attr({
+          'x': 0,
+          'y': 0,
+          'width': width - dimensions.left - dimensions.right,
+          'height': height - dimensions.top - dimensions.bottom
+        });
+        return svg;
+      },
+      createContent: function(svg, id, options) {
+        var content;
+        content = svg.append('g').attr('class', 'content');
+        if (options.hideOverflow) {
+          return content.attr('clip-path', "url(#content-clip-" + id + ")");
+        }
+      },
+      createGlass: function(svg, dimensions, handlers, axes, data, options, dispatch, columnWidth) {
+        var glass, scrubberGroup, that;
+        that = this;
+        glass = svg.append('g').attr({
+          'class': 'glass-container',
+          'opacity': 0
+        });
+        scrubberGroup = glass.selectAll('.scrubberItem').data(data).enter().append('g').attr('class', function(s, i) {
+          return "scrubberItem series_" + i;
+        });
+        scrubberGroup.each(function(s, i) {
+          var g, g2, item;
+          item = d3.select(this);
+          g = item.append('g').attr({
+            'class': "rightTT"
+          });
+          g.append('path').attr({
+            'class': "scrubberPath series_" + i,
+            'y': '-7px',
+            'fill': s.color
+          });
+          that.styleTooltip(g.append('text').style('text-anchor', 'start').attr({
+            'class': function(d, i) {
+              return "scrubberText series_" + i;
+            },
+            'height': '14px',
+            'transform': 'translate(7, 3)',
+            'text-rendering': 'geometric-precision'
+          })).text(s.label || s.y);
+          g2 = item.append('g').attr({
+            'class': "leftTT"
+          });
+          g2.append('path').attr({
+            'class': "scrubberPath series_" + i,
+            'y': '-7px',
+            'fill': s.color
+          });
+          that.styleTooltip(g2.append('text').style('text-anchor', 'end').attr({
+            'class': "scrubberText series_" + i,
+            'height': '14px',
+            'transform': 'translate(-13, 3)',
+            'text-rendering': 'geometric-precision'
+          })).text(s.label || s.y);
+          return item.append('circle').attr({
+            'class': "scrubberDot series_" + i,
+            'fill': 'white',
+            'stroke': s.color,
+            'stroke-width': '2px',
+            'r': 4
+          });
+        });
+        return glass.append('rect').attr({
+          "class": 'glass',
+          width: dimensions.width - dimensions.left - dimensions.right,
+          height: dimensions.height - dimensions.top - dimensions.bottom
+        }).style('fill', 'white').style('fill-opacity', 0.000001).on('mouseover', function() {
+          return handlers.onChartHover(svg, d3.select(this), axes, data, options, dispatch, columnWidth);
+        });
+      },
+      getDataPerSeries: function(data, options) {
+        var axes, layout, series, straightened;
+        series = options.series;
+        axes = options.axes;
+        if (!(series && series.length && data && data.length)) {
+          return [];
+        }
+        straightened = series.map(function(s, i) {
+          var seriesData;
+          seriesData = {
+            index: i,
+            name: s.y,
+            values: [],
+            color: s.color,
+            axis: s.axis || 'y',
+            xOffset: 0,
+            type: s.type,
+            thickness: s.thickness,
+            drawDots: s.drawDots !== false
+          };
+          if (s.dotSize != null) {
+            seriesData.dotSize = s.dotSize;
+          }
+          if (s.striped === true) {
+            seriesData.striped = true;
+          }
+          if (s.lineMode != null) {
+            seriesData.lineMode = s.lineMode;
+          }
+          if (s.id) {
+            seriesData.id = s.id;
+          }
+          data.filter(function(row) {
+            return row[s.y] != null;
+          }).forEach(function(row) {
+            var d;
+            d = {
+              x: row[options.axes.x.key],
+              y: row[s.y],
+              y0: 0,
+              axis: s.axis || 'y'
+            };
+            if (s.dotSize != null) {
+              d.dotSize = s.dotSize;
+            }
+            return seriesData.values.push(d);
+          });
+          return seriesData;
+        });
+        if ((options.stacks == null) || options.stacks.length === 0) {
+          return straightened;
+        }
+        layout = d3.layout.stack().values(function(s) {
+          return s.values;
+        });
+        options.stacks.forEach(function(stack) {
+          var layers;
+          if (!(stack.series.length > 0)) {
+            return;
+          }
+          layers = straightened.filter(function(s, i) {
+            var _ref;
+            return (s.id != null) && (_ref = s.id, __indexOf.call(stack.series, _ref) >= 0);
+          });
+          return layout(layers);
+        });
+        return straightened;
+      },
+      estimateSideTooltipWidth: function(svg, text) {
+        var bbox, t;
+        t = svg.append('text');
+        t.text('' + text);
+        this.styleTooltip(t);
+        bbox = this.getTextBBox(t[0][0]);
+        t.remove();
+        return bbox;
+      },
+      getTextBBox: function(svgTextElement) {
+        var error;
+        if (svgTextElement !== null) {
+          try {
+            return svgTextElement.getBBox();
+          } catch (_error) {
+            error = _error;
+            return {
+              height: 0,
+              width: 0,
+              y: 0,
+              x: 0
+            };
+          }
+        }
+        return {};
+      },
+      getWidestTickWidth: function(svg, axisKey) {
+        var bbox, max, ticks, _ref;
+        max = 0;
+        bbox = this.getTextBBox;
+        ticks = svg.select("." + axisKey + ".axis").selectAll('.tick');
+        if ((_ref = ticks[0]) != null) {
+          _ref.forEach(function(t) {
+            return max = Math.max(max, bbox(t).width);
+          });
+        }
+        return max;
+      },
+      getWidestOrdinate: function(data, series, options) {
+        var widest;
+        widest = '';
+        data.forEach(function(row) {
+          return series.forEach(function(series) {
+            var v, _ref;
+            v = row[series.y];
+            if ((series.axis != null) && ((_ref = options.axes[series.axis]) != null ? _ref.ticksFormatter : void 0)) {
+              v = options.axes[series.axis].ticksFormatter(v);
+            }
+            if (v == null) {
+              return;
+            }
+            if (('' + v).length > ('' + widest).length) {
+              return widest = v;
+            }
+          });
+        });
+        return widest;
+      },
+      getDefaultOptions: function() {
+        return {
+          tooltip: {
+            mode: 'scrubber'
+          },
+          lineMode: 'linear',
+          tension: 0.7,
+          margin: this.getDefaultMargins(),
+          axes: {
+            x: {
+              type: 'linear',
+              key: 'x'
+            },
+            y: {
+              type: 'linear'
+            }
+          },
+          series: [],
+          drawLegend: true,
+          drawDots: true,
+          stacks: [],
+          columnsHGap: 5,
+          hideOverflow: false
+        };
+      },
+      sanitizeOptions: function(options, mode) {
+        var defaultMargin;
+        if (options == null) {
+          options = {};
+        }
+        if (mode === 'thumbnail') {
+          options.drawLegend = false;
+          options.drawDots = false;
+          options.tooltip = {
+            mode: 'none',
+            interpolate: false
+          };
+        }
+        options.series = this.sanitizeSeriesOptions(options.series);
+        options.stacks = this.sanitizeSeriesStacks(options.stacks, options.series);
+        options.axes = this.sanitizeAxes(options.axes, this.haveSecondYAxis(options.series));
+        options.tooltip = this.sanitizeTooltip(options.tooltip);
+        options.margin = this.sanitizeMargins(options.margin);
+        options.lineMode || (options.lineMode = this.getDefaultOptions().lineMode);
+        options.tension = /^\d+(\.\d+)?$/.test(options.tension) ? options.tension : this.getDefaultOptions().tension;
+        options.drawLegend = options.drawLegend !== false;
+        options.drawDots = options.drawDots !== false;
+        if (!angular.isNumber(options.columnsHGap)) {
+          options.columnsHGap = 5;
+        }
+        options.hideOverflow = options.hideOverflow || false;
+        defaultMargin = mode === 'thumbnail' ? this.getDefaultThumbnailMargins() : this.getDefaultMargins();
+        options.series = angular.extend(this.getDefaultOptions().series, options.series);
+        options.axes = angular.extend(this.getDefaultOptions().axes, options.axes);
+        options.tooltip = angular.extend(this.getDefaultOptions().tooltip, options.tooltip);
+        options.margin = angular.extend(defaultMargin, options.margin);
+        return options;
+      },
+      sanitizeMargins: function(options) {
+        var attrs, margin, opt, value;
+        attrs = ['top', 'right', 'bottom', 'left'];
+        margin = {};
+        for (opt in options) {
+          value = options[opt];
+          if (__indexOf.call(attrs, opt) >= 0) {
+            margin[opt] = parseFloat(value);
+          }
+        }
+        return margin;
+      },
+      sanitizeSeriesStacks: function(stacks, series) {
+        var seriesKeys;
+        if (stacks == null) {
+          return [];
+        }
+        seriesKeys = {};
+        series.forEach(function(s) {
+          return seriesKeys[s.id] = s;
+        });
+        stacks.forEach(function(stack) {
+          return stack.series.forEach(function(id) {
+            var s;
+            s = seriesKeys[id];
+            if (s != null) {
+              if (s.axis !== stack.axis) {
+                return $log.warn("Series " + id + " is not on the same axis as its stack");
+              }
+            } else {
+              if (!s) {
+                return $log.warn("Unknown series found in stack : " + id);
+              }
+            }
+          });
+        });
+        return stacks;
+      },
+      sanitizeTooltip: function(options) {
+        var _ref;
+        if (!options) {
+          return {
+            mode: 'scrubber'
+          };
+        }
+        if ((_ref = options.mode) !== 'none' && _ref !== 'axes' && _ref !== 'scrubber') {
+          options.mode = 'scrubber';
+        }
+        if (options.mode === 'scrubber') {
+          delete options.interpolate;
+        } else {
+          options.interpolate = !!options.interpolate;
+        }
+        if (options.mode === 'scrubber' && options.interpolate) {
+          throw new Error('Interpolation is not supported for scrubber tooltip mode.');
+        }
+        return options;
+      },
+      sanitizeSeriesOptions: function(options) {
+        var colors, knownIds;
+        if (options == null) {
+          return [];
+        }
+        colors = d3.scale.category10();
+        knownIds = {};
+        options.forEach(function(s, i) {
+          if (knownIds[s.id] != null) {
+            throw new Error("Twice the same ID (" + s.id + ") ? Really ?");
+          }
+          if (s.id != null) {
+            return knownIds[s.id] = s;
+          }
+        });
+        options.forEach(function(s, i) {
+          var cnt, _ref, _ref1, _ref2, _ref3;
+          s.axis = ((_ref = s.axis) != null ? _ref.toLowerCase() : void 0) !== 'y2' ? 'y' : 'y2';
+          s.color || (s.color = colors(i));
+          s.type = (_ref1 = s.type) === 'line' || _ref1 === 'area' || _ref1 === 'column' ? s.type : "line";
+          if (s.type === 'column') {
+            delete s.thickness;
+            delete s.lineMode;
+            delete s.drawDots;
+            delete s.dotSize;
+          } else if (!/^\d+px$/.test(s.thickness)) {
+            s.thickness = '1px';
+          }
+          if ((_ref2 = s.type) === 'line' || _ref2 === 'area') {
+            if ((_ref3 = s.lineMode) !== 'dashed') {
+              delete s.lineMode;
+            }
+            if (s.drawDots !== false && (s.dotSize == null)) {
+              s.dotSize = 2;
+            }
+          }
+          if (s.id == null) {
+            cnt = 0;
+            while (knownIds["series_" + cnt] != null) {
+              cnt++;
+            }
+            s.id = "series_" + cnt;
+            knownIds[s.id] = s;
+          }
+          if (s.drawDots === false) {
+            return delete s.dotSize;
+          }
+        });
+        return options;
+      },
+      sanitizeAxes: function(axesOptions, secondAxis) {
+        var _base;
+        if (axesOptions == null) {
+          axesOptions = {};
+        }
+        axesOptions.x = this.sanitizeAxisOptions(axesOptions.x);
+        (_base = axesOptions.x).key || (_base.key = "x");
+        axesOptions.y = this.sanitizeAxisOptions(axesOptions.y);
+        if (secondAxis) {
+          axesOptions.y2 = this.sanitizeAxisOptions(axesOptions.y2);
+        }
+        return axesOptions;
+      },
+      sanitizeExtrema: function(options) {
+        var max, min;
+        min = this.getSanitizedNumber(options.min);
+        if (min != null) {
+          options.min = min;
+        } else {
+          delete options.min;
+        }
+        max = this.getSanitizedNumber(options.max);
+        if (max != null) {
+          return options.max = max;
+        } else {
+          return delete options.max;
+        }
+      },
+      getSanitizedNumber: function(value) {
+        var number;
+        if (value == null) {
+          return void 0;
+        }
+        number = parseFloat(value);
+        if (isNaN(number)) {
+          $log.warn("Invalid extremum value : " + value + ", deleting it.");
+          return void 0;
+        }
+        return number;
+      },
+      sanitizeAxisOptions: function(options) {
+        if (options == null) {
+          return {
+            type: 'linear'
+          };
+        }
+        options.type || (options.type = 'linear');
+        if (options.ticksRotate != null) {
+          options.ticksRotate = this.getSanitizedNumber(options.ticksRotate);
+        }
+        if (options.labelFunction != null) {
+          options.ticksFormatter = options.labelFunction;
+        }
+        if (options.ticksFormat != null) {
+          if (options.type === 'date') {
+            options.ticksFormatter = d3.time.format(options.ticksFormat);
+          } else {
+            options.ticksFormatter = d3.format(options.ticksFormat);
+          }
+          if (options.tooltipFormatter == null) {
+            options.tooltipFormatter = options.ticksFormatter;
+          }
+        }
+        if (options.tooltipFormat != null) {
+          if (options.type === 'date') {
+            options.tooltipFormatter = d3.time.format(options.tooltipFormat);
+          } else {
+            options.tooltipFormatter = d3.format(options.tooltipFormat);
+          }
+        }
+        if (options.ticksInterval != null) {
+          options.ticksInterval = this.getSanitizedNumber(options.ticksInterval);
+        }
+        this.sanitizeExtrema(options);
+        return options;
+      },
+      createAxes: function(svg, dimensions, axesOptions) {
+        var createY2Axis, height, style, width, x, xAxis, y, y2, y2Axis, yAxis;
+        createY2Axis = axesOptions.y2 != null;
+        width = dimensions.width;
+        height = dimensions.height;
+        width = width - dimensions.left - dimensions.right;
+        height = height - dimensions.top - dimensions.bottom;
+        x = void 0;
+        if (axesOptions.x.type === 'date') {
+          x = d3.time.scale().rangeRound([0, width]);
+        } else {
+          x = d3.scale.linear().rangeRound([0, width]);
+        }
+        xAxis = this.createAxis(x, 'x', axesOptions);
+        y = void 0;
+        if (axesOptions.y.type === 'log') {
+          y = d3.scale.log().clamp(true).rangeRound([height, 0]);
+        } else {
+          y = d3.scale.linear().rangeRound([height, 0]);
+        }
+        y.clamp(true);
+        yAxis = this.createAxis(y, 'y', axesOptions);
+        y2 = void 0;
+        if (createY2Axis && axesOptions.y2.type === 'log') {
+          y2 = d3.scale.log().clamp(true).rangeRound([height, 0]);
+        } else {
+          y2 = d3.scale.linear().rangeRound([height, 0]);
+        }
+        y2.clamp(true);
+        y2Axis = this.createAxis(y2, 'y2', axesOptions);
+        style = function(group) {
+          group.style({
+            'font': '10px Courier',
+            'shape-rendering': 'crispEdges'
+          });
+          return group.selectAll('path').style({
+            'fill': 'none',
+            'stroke': '#000'
+          });
+        };
+        return {
+          xScale: x,
+          yScale: y,
+          y2Scale: y2,
+          xAxis: xAxis,
+          yAxis: yAxis,
+          y2Axis: y2Axis,
+          andAddThemIf: function(conditions) {
+            if (!!conditions.all) {
+              if (!!conditions.x) {
+                svg.append('g').attr('class', 'x axis').attr('transform', 'translate(0,' + height + ')').call(xAxis).call(style);
+              }
+              if (!!conditions.y) {
+                svg.append('g').attr('class', 'y axis').call(yAxis).call(style);
+              }
+              if (createY2Axis && !!conditions.y2) {
+                svg.append('g').attr('class', 'y2 axis').attr('transform', 'translate(' + width + ', 0)').call(y2Axis).call(style);
+              }
+            }
+            return {
+              xScale: x,
+              yScale: y,
+              y2Scale: y2,
+              xAxis: xAxis,
+              yAxis: yAxis,
+              y2Axis: y2Axis
+            };
+          }
+        };
+      },
+      createAxis: function(scale, key, options) {
+        var axis, o, sides;
+        sides = {
+          x: 'bottom',
+          y: 'left',
+          y2: 'right'
+        };
+        o = options[key];
+        axis = d3.svg.axis().scale(scale).orient(sides[key]).tickFormat(o != null ? o.ticksFormatter : void 0);
+        if (o == null) {
+          return axis;
+        }
+        if (angular.isArray(o.ticks)) {
+          axis.tickValues(o.ticks);
+        } else if (angular.isNumber(o.ticks)) {
+          axis.ticks(o.ticks);
+        } else if (angular.isFunction(o.ticks)) {
+          axis.ticks(o.ticks, o.ticksInterval);
+        }
+        return axis;
+      },
+      setScalesDomain: function(scales, data, series, svg, options) {
+        var axis, y2Domain, yDomain;
+        this.setXScale(scales.xScale, data, series, options.axes);
+        axis = svg.selectAll('.x.axis').call(scales.xAxis);
+        if (options.axes.x.ticksRotate != null) {
+          axis.selectAll('.tick>text').attr('dy', null).attr('transform', 'translate(0,5) rotate(' + options.axes.x.ticksRotate + ' 0,6)').style('text-anchor', options.axes.x.ticksRotate >= 0 ? 'start' : 'end');
+        }
+        if ((series.filter(function(s) {
+          return s.axis === 'y' && s.visible !== false;
+        })).length > 0) {
+          yDomain = this.getVerticalDomain(options, data, series, 'y');
+          scales.yScale.domain(yDomain).nice();
+          axis = svg.selectAll('.y.axis').call(scales.yAxis);
+          if (options.axes.y.ticksRotate != null) {
+            axis.selectAll('.tick>text').attr('transform', 'rotate(' + options.axes.y.ticksRotate + ' -6,0)').style('text-anchor', 'end');
+          }
+        }
+        if ((series.filter(function(s) {
+          return s.axis === 'y2' && s.visible !== false;
+        })).length > 0) {
+          y2Domain = this.getVerticalDomain(options, data, series, 'y2');
+          scales.y2Scale.domain(y2Domain).nice();
+          axis = svg.selectAll('.y2.axis').call(scales.y2Axis);
+          if (options.axes.y2.ticksRotate != null) {
+            return axis.selectAll('.tick>text').attr('transform', 'rotate(' + options.axes.y2.ticksRotate + ' 6,0)').style('text-anchor', 'start');
+          }
+        }
+      },
+      getVerticalDomain: function(options, data, series, key) {
+        var domain, mySeries, o;
+        if (!(o = options.axes[key])) {
+          return [];
+        }
+        if ((o.ticks != null) && angular.isArray(o.ticks)) {
+          return [o.ticks[0], o.ticks[o.ticks.length - 1]];
+        }
+        mySeries = series.filter(function(s) {
+          return s.axis === key && s.visible !== false;
+        });
+        domain = this.yExtent(series.filter(function(s) {
+          return s.axis === key && s.visible !== false;
+        }), data, options.stacks.filter(function(stack) {
+          return stack.axis === key;
+        }));
+        if (o.type === 'log') {
+          domain[0] = domain[0] === 0 ? 0.001 : domain[0];
+        }
+        if (o.min != null) {
+          domain[0] = o.min;
+        }
+        if (o.max != null) {
+          domain[1] = o.max;
+        }
+        return domain;
+      },
+      yExtent: function(series, data, stacks) {
+        var groups, maxY, minY;
+        minY = Number.POSITIVE_INFINITY;
+        maxY = Number.NEGATIVE_INFINITY;
+        groups = [];
+        stacks.forEach(function(stack) {
+          return groups.push(stack.series.map(function(id) {
+            return (series.filter(function(s) {
+              return s.id === id;
+            }))[0];
+          }));
+        });
+        series.forEach(function(series, i) {
+          var isInStack;
+          isInStack = false;
+          stacks.forEach(function(stack) {
+            var _ref;
+            if (_ref = series.id, __indexOf.call(stack.series, _ref) >= 0) {
+              return isInStack = true;
+            }
+          });
+          if (!isInStack) {
+            return groups.push([series]);
+          }
+        });
+        groups.forEach(function(group) {
+          group = group.filter(Boolean);
+          minY = Math.min(minY, d3.min(data, function(d) {
+            return group.reduce((function(a, s) {
+              return Math.min(a, d[s.y]);
+            }), Number.POSITIVE_INFINITY);
+          }));
+          return maxY = Math.max(maxY, d3.max(data, function(d) {
+            return group.reduce((function(a, s) {
+              return a + d[s.y];
+            }), 0);
+          }));
+        });
+        if (minY === maxY) {
+          if (minY > 0) {
+            return [0, minY * 2];
+          } else {
+            return [minY * 2, 0];
+          }
+        }
+        return [minY, maxY];
+      },
+      setXScale: function(xScale, data, series, axesOptions) {
+        var domain, o;
+        domain = this.xExtent(data, axesOptions.x.key);
+        if (series.filter(function(s) {
+          return s.type === 'column';
+        }).length) {
+          this.adjustXDomainForColumns(domain, data, axesOptions.x.key);
+        }
+        o = axesOptions.x;
+        if (o.min != null) {
+          domain[0] = o.min;
+        }
+        if (o.max != null) {
+          domain[1] = o.max;
+        }
+        return xScale.domain(domain);
+      },
+      xExtent: function(data, key) {
+        var from, to, _ref;
+        _ref = d3.extent(data, function(d) {
+          return d[key];
+        }), from = _ref[0], to = _ref[1];
+        if (from === to) {
+          if (from > 0) {
+            return [0, from * 2];
+          } else {
+            return [from * 2, 0];
+          }
+        }
+        return [from, to];
+      },
+      adjustXDomainForColumns: function(domain, data, field) {
+        var step;
+        step = this.getAverageStep(data, field);
+        if (angular.isDate(domain[0])) {
+          domain[0] = new Date(domain[0].getTime() - step);
+          return domain[1] = new Date(domain[1].getTime() + step);
+        } else {
+          domain[0] = domain[0] - step;
+          return domain[1] = domain[1] + step;
+        }
+      },
+      getAverageStep: function(data, field) {
+        var i, n, sum;
+        if (!(data.length > 1)) {
+          return 0;
+        }
+        sum = 0;
+        n = data.length - 1;
+        i = 0;
+        while (i < n) {
+          sum += data[i + 1][field] - data[i][field];
+          i++;
+        }
+        return sum / n;
+      },
+      haveSecondYAxis: function(series) {
+        return !series.every(function(s) {
+          return s.axis !== 'y2';
+        });
+      },
+      showScrubber: function(svg, glass, axes, data, options, dispatch, columnWidth) {
+        var that;
+        that = this;
+        glass.on('mousemove', function() {
+          svg.selectAll('.glass-container').attr('opacity', 1);
+          return that.updateScrubber(svg, d3.mouse(this), axes, data, options, dispatch, columnWidth);
+        });
+        return glass.on('mouseout', function() {
+          glass.on('mousemove', null);
+          return svg.selectAll('.glass-container').attr('opacity', 0);
+        });
+      },
+      getClosestPoint: function(values, xValue) {
+        var d, d0, d1, i, xBisector;
+        xBisector = d3.bisector(function(d) {
+          return d.x;
+        }).left;
+        i = xBisector(values, xValue);
+        if (i === 0) {
+          return values[0];
+        }
+        if (i > values.length - 1) {
+          return values[values.length - 1];
+        }
+        d0 = values[i - 1];
+        d1 = values[i];
+        d = xValue - d0.x > d1.x - xValue ? d1 : d0;
+        return d;
+      },
+      updateScrubber: function(svg, _arg, axes, data, options, dispatch, columnWidth) {
+        var ease, positions, that, tickLength, x, y;
+        x = _arg[0], y = _arg[1];
+        ease = function(element) {
+          return element.transition().duration(50);
+        };
+        that = this;
+        positions = [];
+        data.forEach(function(series, index) {
+          var color, item, lText, left, rText, right, side, sizes, text, v, xInvert, xPos, yInvert;
+          item = svg.select(".scrubberItem.series_" + index);
+          if (options.series[index].visible === false) {
+            item.attr('opacity', 0);
+            return;
+          }
+          item.attr('opacity', 1);
+          xInvert = axes.xScale.invert(x);
+          yInvert = axes.yScale.invert(y);
+          v = that.getClosestPoint(series.values, xInvert);
+          dispatch.focus(v, series.values.indexOf(v), [xInvert, yInvert]);
+          text = v.x + ' : ' + v.y;
+          if (options.tooltip.formatter) {
+            text = options.tooltip.formatter(v.x, v.y, options.series[index]);
+          }
+          right = item.select('.rightTT');
+          rText = right.select('text');
+          rText.text(text);
+          left = item.select('.leftTT');
+          lText = left.select('text');
+          lText.text(text);
+          sizes = {
+            right: that.getTextBBox(rText[0][0]).width + 5,
+            left: that.getTextBBox(lText[0][0]).width + 5
+          };
+          side = series.axis === 'y2' ? 'right' : 'left';
+          xPos = axes.xScale(v.x);
+          if (side === 'left') {
+            if (xPos + that.getTextBBox(lText[0][0]).x - 10 < 0) {
+              side = 'right';
+            }
+          } else if (side === 'right') {
+            if (xPos + sizes.right > that.getTextBBox(svg.select('.glass')[0][0]).width) {
+              side = 'left';
+            }
+          }
+          if (side === 'left') {
+            ease(right).attr('opacity', 0);
+            ease(left).attr('opacity', 1);
+          } else {
+            ease(right).attr('opacity', 1);
+            ease(left).attr('opacity', 0);
+          }
+          positions[index] = {
+            index: index,
+            x: xPos,
+            y: axes[v.axis + 'Scale'](v.y + v.y0),
+            side: side,
+            sizes: sizes
+          };
+          color = angular.isFunction(series.color) ? series.color(v, series.values.indexOf(v)) : series.color;
+          item.selectAll('circle').attr('stroke', color);
+          return item.selectAll('path').attr('fill', color);
+        });
+        positions = this.preventOverlapping(positions);
+        tickLength = Math.max(15, 100 / columnWidth);
+        return data.forEach(function(series, index) {
+          var item, p, tt, xOffset;
+          if (options.series[index].visible === false) {
+            return;
+          }
+          p = positions[index];
+          item = svg.select(".scrubberItem.series_" + index);
+          tt = item.select("." + p.side + "TT");
+          xOffset = (p.side === 'left' ? series.xOffset : -series.xOffset);
+          tt.select('text').attr('transform', function() {
+            if (p.side === 'left') {
+              return "translate(" + (-3 - tickLength - xOffset) + ", " + (p.labelOffset + 3) + ")";
+            } else {
+              return "translate(" + (4 + tickLength + xOffset) + ", " + (p.labelOffset + 3) + ")";
+            }
+          });
+          tt.select('path').attr('d', that.getScrubberPath(p.sizes[p.side] + 1, p.labelOffset, p.side, tickLength + xOffset));
+          return ease(item).attr({
+            'transform': "translate(" + (positions[index].x + series.xOffset) + ", " + positions[index].y + ")"
+          });
+        });
+      },
+      getScrubberPath: function(w, yOffset, side, padding) {
+        var h, p, xdir, ydir;
+        h = 18;
+        p = padding;
+        w = w;
+        xdir = side === 'left' ? 1 : -1;
+        ydir = 1;
+        if (yOffset !== 0) {
+          ydir = Math.abs(yOffset) / yOffset;
+        }
+        yOffset || (yOffset = 0);
+        return ["m0 0", "l" + xdir + " 0", "l0 " + (yOffset + ydir), "l" + (-xdir * (p + 1)) + " 0", "l0 " + (-h / 2 - ydir), "l" + (-xdir * w) + " 0", "l0 " + h, "l" + (xdir * w) + " 0", "l0 " + (-h / 2 - ydir), "l" + (xdir * (p - 1)) + " 0", "l0 " + (-yOffset + ydir), "l1 0", "z"].join('');
+      },
+      preventOverlapping: function(positions) {
+        var abscissas, getNeighbours, h, offset;
+        h = 18;
+        abscissas = {};
+        positions.forEach(function(p) {
+          var _name;
+          abscissas[_name = p.x] || (abscissas[_name] = {
+            left: [],
+            right: []
+          });
+          return abscissas[p.x][p.side].push(p);
+        });
+        getNeighbours = function(side) {
+          var foundNeighbour, neighbourhood, neighbours, neighboursForX, p, sides, x, y, _ref;
+          neighbours = [];
+          for (x in abscissas) {
+            sides = abscissas[x];
+            if (sides[side].length === 0) {
+              continue;
+            }
+            neighboursForX = {};
+            while (sides[side].length > 0) {
+              p = sides[side].pop();
+              foundNeighbour = false;
+              for (y in neighboursForX) {
+                neighbourhood = neighboursForX[y];
+                if ((+y - h <= (_ref = p.y) && _ref <= +y + h)) {
+                  neighbourhood.push(p);
+                  foundNeighbour = true;
+                }
+              }
+              if (!foundNeighbour) {
+                neighboursForX[p.y] = [p];
+              }
+            }
+            neighbours.push(neighboursForX);
+          }
+          return neighbours;
+        };
+        offset = function(neighboursForAbscissas) {
+          var abs, n, neighbours, start, step, xNeighbours, y;
+          step = 20;
+          for (abs in neighboursForAbscissas) {
+            xNeighbours = neighboursForAbscissas[abs];
+            for (y in xNeighbours) {
+              neighbours = xNeighbours[y];
+              n = neighbours.length;
+              if (n === 1) {
+                neighbours[0].labelOffset = 0;
+                continue;
+              }
+              neighbours = neighbours.sort(function(a, b) {
+                return a.y - b.y;
+              });
+              if (n % 2 === 0) {
+                start = -(step / 2) * (n / 2);
+              } else {
+                start = -(n - 1) / 2 * step;
+              }
+              neighbours.forEach(function(neighbour, i) {
+                return neighbour.labelOffset = start + step * i;
+              });
+            }
+          }
+        };
+        offset(getNeighbours('left'));
+        offset(getNeighbours('right'));
+        return positions;
+      },
+      getTooltipHandlers: function(options) {
+        if (options.tooltip.mode === 'scrubber') {
+          return {
+            onChartHover: angular.bind(this, this.showScrubber)
+          };
+        } else {
+          return {
+            onMouseOver: angular.bind(this, this.onMouseOver),
+            onMouseOut: angular.bind(this, this.onMouseOut)
+          };
+        }
+      },
+      styleTooltip: function(d3TextElement) {
+        return d3TextElement.attr({
+          'font-family': 'monospace',
+          'font-size': 10,
+          'fill': 'white',
+          'text-rendering': 'geometric-precision'
+        });
+      },
+      addTooltips: function(svg, dimensions, axesOptions) {
+        var h, height, p, w, width, xTooltip, y2Tooltip, yTooltip;
+        width = dimensions.width;
+        height = dimensions.height;
+        width = width - dimensions.left - dimensions.right;
+        height = height - dimensions.top - dimensions.bottom;
+        w = 24;
+        h = 18;
+        p = 5;
+        xTooltip = svg.append('g').attr({
+          'id': 'xTooltip',
+          'class': 'xTooltip',
+          'opacity': 0
+        });
+        xTooltip.append('path').attr('transform', "translate(0," + (height + 1) + ")");
+        this.styleTooltip(xTooltip.append('text').style('text-anchor', 'middle').attr({
+          'width': w,
+          'height': h,
+          'transform': 'translate(0,' + (height + 19) + ')'
+        }));
+        yTooltip = svg.append('g').attr({
+          id: 'yTooltip',
+          "class": 'yTooltip',
+          opacity: 0
+        });
+        yTooltip.append('path');
+        this.styleTooltip(yTooltip.append('text').attr({
+          'width': h,
+          'height': w
+        }));
+        if (axesOptions.y2 != null) {
+          y2Tooltip = svg.append('g').attr({
+            'id': 'y2Tooltip',
+            'class': 'y2Tooltip',
+            'opacity': 0,
+            'transform': 'translate(' + width + ',0)'
+          });
+          y2Tooltip.append('path');
+          return this.styleTooltip(y2Tooltip.append('text').attr({
+            'width': h,
+            'height': w
+          }));
+        }
+      },
+      onMouseOver: function(svg, event, axesOptions) {
+        this.updateXTooltip(svg, event, axesOptions.x);
+        if (event.series.axis === 'y2') {
+          return this.updateY2Tooltip(svg, event, axesOptions.y2);
+        } else {
+          return this.updateYTooltip(svg, event, axesOptions.y);
+        }
+      },
+      onMouseOut: function(svg) {
+        return this.hideTooltips(svg);
+      },
+      updateXTooltip: function(svg, _arg, xAxisOptions) {
+        var color, datum, label, series, textX, x, xTooltip, _f;
+        x = _arg.x, datum = _arg.datum, series = _arg.series;
+        xTooltip = svg.select("#xTooltip");
+        xTooltip.transition().attr({
+          'opacity': 1.0,
+          'transform': "translate(" + x + ",0)"
+        });
+        _f = xAxisOptions.tooltipFormatter;
+        textX = _f ? _f(datum.x) : datum.x;
+        label = xTooltip.select('text');
+        label.text(textX);
+        color = angular.isFunction(series.color) ? series.color(datum, series.values.indexOf(datum)) : series.color;
+        return xTooltip.select('path').style('fill', color).attr('d', this.getXTooltipPath(label[0][0]));
+      },
+      getXTooltipPath: function(textElement) {
+        var h, p, w;
+        w = Math.max(this.getTextBBox(textElement).width, 15);
+        h = 18;
+        p = 5;
+        return 'm-' + w / 2 + ' ' + p + ' ' + 'l0 ' + h + ' ' + 'l' + w + ' 0 ' + 'l0 ' + '' + (-h) + 'l' + (-w / 2 + p) + ' 0 ' + 'l' + (-p) + ' -' + h / 4 + ' ' + 'l' + (-p) + ' ' + h / 4 + ' ' + 'l' + (-w / 2 + p) + ' 0z';
+      },
+      updateYTooltip: function(svg, _arg, yAxisOptions) {
+        var color, datum, label, series, textY, w, y, yTooltip, _f;
+        y = _arg.y, datum = _arg.datum, series = _arg.series;
+        yTooltip = svg.select("#yTooltip");
+        yTooltip.transition().attr({
+          'opacity': 1.0,
+          'transform': "translate(0, " + y + ")"
+        });
+        _f = yAxisOptions.tooltipFormatter;
+        textY = _f ? _f(datum.y) : datum.y;
+        label = yTooltip.select('text');
+        label.text(textY);
+        w = this.getTextBBox(label[0][0]).width + 5;
+        label.attr({
+          'transform': 'translate(' + (-w - 2) + ',3)',
+          'width': w
+        });
+        color = angular.isFunction(series.color) ? series.color(datum, series.values.indexOf(datum)) : series.color;
+        return yTooltip.select('path').style('fill', color).attr('d', this.getYTooltipPath(w));
+      },
+      updateY2Tooltip: function(svg, _arg, yAxisOptions) {
+        var color, datum, label, series, textY, w, y, y2Tooltip, _f;
+        y = _arg.y, datum = _arg.datum, series = _arg.series;
+        y2Tooltip = svg.select("#y2Tooltip");
+        y2Tooltip.transition().attr('opacity', 1.0);
+        _f = yAxisOptions.tooltipFormatter;
+        textY = _f ? _f(datum.y) : datum.y;
+        label = y2Tooltip.select('text');
+        label.text(textY);
+        w = this.getTextBBox(label[0][0]).width + 5;
+        label.attr({
+          'transform': 'translate(7, ' + (parseFloat(y) + 3) + ')',
+          'w': w
+        });
+        color = angular.isFunction(series.color) ? series.color(datum, series.values.indexOf(datum)) : series.color;
+        return y2Tooltip.select('path').style('fill', color).attr({
+          'd': this.getY2TooltipPath(w),
+          'transform': 'translate(0, ' + y + ')'
+        });
+      },
+      getYTooltipPath: function(w) {
+        var h, p;
+        h = 18;
+        p = 5;
+        return 'm0 0' + 'l' + (-p) + ' ' + (-p) + ' ' + 'l0 ' + (-h / 2 + p) + ' ' + 'l' + (-w) + ' 0 ' + 'l0 ' + h + ' ' + 'l' + w + ' 0 ' + 'l0 ' + (-h / 2 + p) + 'l' + (-p) + ' ' + p + 'z';
+      },
+      getY2TooltipPath: function(w) {
+        var h, p;
+        h = 18;
+        p = 5;
+        return 'm0 0' + 'l' + p + ' ' + p + ' ' + 'l0 ' + (h / 2 - p) + ' ' + 'l' + w + ' 0 ' + 'l0 ' + (-h) + ' ' + 'l' + (-w) + ' 0 ' + 'l0 ' + (h / 2 - p) + ' ' + 'l' + (-p) + ' ' + p + 'z';
+      },
+      hideTooltips: function(svg) {
+        svg.select("#xTooltip").transition().attr('opacity', 0);
+        svg.select("#yTooltip").transition().attr('opacity', 0);
+        return svg.select("#y2Tooltip").transition().attr('opacity', 0);
+      }
+    };
+  }
+]);
diff --git a/skyquake/framework/style/_colors.scss b/skyquake/framework/style/_colors.scss
new file mode 100644 (file)
index 0000000..9378984
--- /dev/null
@@ -0,0 +1,124 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+$darker-gray: rgb(91,91,91);
+$dark-gray: rgb(211, 211, 211);
+$lightest-gray: rgb(221,221,221);
+$light-green: rgb(147, 203, 67);
+$light-blue: rgb(0, 168, 235);
+$lighter-blue: rgb(159, 196, 244);
+
+
+$primary-header: $light-green;
+$secondary-header: $dark-gray;
+$body-color:$lightest-gray;
+
+$error-red:#FF5F5F;
+
+//PC
+
+$black: #000;
+$gray-lightest: #f1f1f1;
+$gray-lighter: #e5e5e5;
+$gray-light: #dadada;
+$gray: #ccc;
+$gray-dark: #999;
+$gray-darker: #666;
+$gray-darkest: #333;
+$white: #FFF;
+//
+// Brand Colors
+//
+$brand-blue-light: #30baef;
+$brand-blue: #00acee;
+$brand-blue-dark: #147ca3;
+$brand-green-light: #93cb43;
+$brand-green: #7cc118;
+
+
+/*
+    New Styles. Phase out old above
+*/
+
+/* NEUTRL
+############################################################################ */
+
+$neutral-white: hsl( 0, 100%, 100%);
+$neutral-light-1: hsl(360, 100%, 50%);
+$neutral-light-2: hsl(360, 100%, 50%);
+$neutral-light-3: hsl(360, 100%, 50%);
+$neutral-light-4: hsl(360, 100%, 50%);
+$neutral-light-5: hsl(360, 100%, 50%);
+
+$neutral-dark-1: hsl(360, 100%, 50%);
+$neutral-dark-2: hsl(360, 100%, 50%);
+$neutral-dark-3: hsl(360, 100%, 50%);
+$neutral-dark-4: hsl(360, 100%, 50%);
+$neutral-dark-5: hsl(360, 100%, 50%);
+$netral-black: hsl(0, 100%, 0%);
+
+
+
+/* SUCCESS, WARNING, ALERT
+############################################################################ */
+
+$success: hsl(198, 59%, 56%);
+$warning: hsl(39, 89%, 67%);
+$alert: hsl(5, 100%, 71%);
+
+
+
+/* ROOT
+############################################################################ */
+
+$header: hsl(218, 18%, 17%);
+$body: hsl(181, 6%, 95%);
+
+
+
+/* BASE
+############################################################################ */
+
+$primary: hsl(204, 100%, 39%);
+$focus: hsla(204, 100%, 39%, 1);
+
+
+
+/* BUTTON
+############################################################################ */
+/* Normal */
+$normalBackground: hsl(211, 3%, 91%);
+$normalForeground: hsl(211, 3%, 11%);
+
+$normalHoverBackground: darken($normalBackground, 10%);
+$normalHoverForeground: $normalForeground;
+
+$normalActiveBackground: saturate($primary, 50%);
+$normalActiveForeground: $neutral-white;
+
+/* Primary */
+$primaryBackground: $primary;
+$primaryForeground: $neutral-white;
+
+$primaryHoverBackground: darken($primaryBackground, 10%);
+$primaryHoverForeground: $primaryForeground;
+
+$primaryActiveBackground: saturate($primary, 50%);
+$primaryActiveForeground: $neutral-white;
+
diff --git a/skyquake/framework/style/base.scss b/skyquake/framework/style/base.scss
new file mode 100644 (file)
index 0000000..02dbee0
--- /dev/null
@@ -0,0 +1,433 @@
+/* /fonts
+############################################################################ */
+
+/* Source Sans Pro */
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 200;
+  src: url('/fonts/SourceSansPro-ExtraLight.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 200;
+  src: url('/fonts/SourceSansPro-ExtraLightIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 300;
+  src: url('/fonts/SourceSansPro-Light.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 300;
+  src: url('/fonts/SourceSansPro-LightIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 400;
+  src: url('/fonts/SourceSansPro-Regular.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 400;
+  src: url('/fonts/SourceSansPro-It.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 600;
+  src: url('/fonts/SourceSansPro-Semibold.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 600;
+  src: url('/fonts/SourceSansPro-SemiboldIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 700;
+  src: url('/fonts/SourceSansPro-Bold.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 700;
+  src: url('/fonts/SourceSansPro-BoldIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 900;
+  src: url('/fonts/SourceSansPro-Black.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Pro';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 900;
+  src: url('/fonts/SourceSansPro-BlackIt.otf.woff') format('woff');
+}
+
+/* Source Sans Code */
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 200;
+  src: url('/fonts/SourceSansCode-ExtraLight.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 200;
+  src: url('/fonts/SourceSansCode-ExtraLightIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 300;
+  src: url('/fonts/SourceSansCode-Light.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 300;
+  src: url('/fonts/SourceSansCode-LightIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 400;
+  src: url('/fonts/SourceSansCode-Regular.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 400;
+  src: url('/fonts/SourceSansCode-It.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 600;
+  src: url('/fonts/SourceSansCode-Semibold.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 600;
+  src: url('/fonts/SourceSansCode-SemiboldIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 700;
+  src: url('/fonts/SourceSansCode-Bold.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 700;
+  src: url('/fonts/SourceSansCode-BoldIt.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: normal;
+  font-weight: 900;
+  src: url('/fonts/SourceSansCode-Black.otf.woff') format('woff');
+}
+
+@font-face{
+  font-family: 'Source Sans Code';
+  font-stretch: normal;
+  font-style: italic;
+  font-weight: 900;
+  src: url('/fonts/SourceSansCode-BlackIt.otf.woff') format('woff');
+}
+
+
+/* ICONS
+############################################################################ */
+
+.svg-24px {
+  fill: black;
+  height: 24px;
+  width: 24px;
+}
+
+
+
+/* ROOT
+############################################################################ */
+
+*, *::before, *::after {
+  box-sizing: border-box;
+}
+
+html {
+  font-family: "Source Sans Pro", helvetica, arial, sans-serif;
+  font-size: 16px;
+  height: 100%;
+  line-height: 1;
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+  width: 100%;
+}
+
+body {
+  height: 100%;
+  margin: 0;
+  width: 100%
+}
+
+
+
+/* DISPLAY
+############################################################################ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block;
+}
+
+progress {
+  vertical-align: baseline;
+}
+
+
+
+/* LINKS
+############################################################################ */
+
+a {
+  background-color: transparent;
+  -webkit-text-decoration-skip: objects;
+}
+
+a:active,
+a:hover {
+  outline-width: 0;
+}
+
+
+
+/* TEXT-LEVEL SEMANTICS
+############################################################################ */
+
+abbr[title] {
+  border-bottom: none;
+  text-decoration: underline;
+  text-decoration: underline dotted;
+}
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+small {
+  font-size: 80%;
+}
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sub {
+  bottom: -0.25em;
+}
+sup {
+  top: -0.5em;
+}
+
+
+
+/* EMBEDDED CONTENT
+############################################################################ */
+
+svg:not(:root) {
+  overflow: hidden;
+}
+
+
+
+/* GROUPING CONTENT
+############################################################################ */
+
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+
+hr {
+  box-sizing: content-box;
+  height: 0;
+  overflow: visible;
+}
+
+dl {
+  -webkit-margin-before: 0px;
+  -webkit-margin-after: 0px;
+}
+
+/* FORMS
+############################################################################ */
+
+button,
+input,
+select,
+textarea {
+  font: inherit;
+  margin: 0;
+}
+
+optgroup {
+  font-weight: bold;
+}
+
+button,
+input {
+  overflow: visible;
+}
+
+button,
+select {
+  text-transform: none;
+}
+
+button,
+html [type="button"],
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button;
+}
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+
+fieldset {
+  border: 1px solid #c0c0c0;
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em;
+}
+
+legend {
+  box-sizing: border-box;
+  color: inherit;
+  display: table;
+  max-width: 100%;
+  padding: 0;
+  white-space: normal;
+}
+
+textarea {
+  overflow: auto;
+}
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+[type="search"] {
+  -webkit-appearance: textfield;
+  outline-offset: -2px;
+}
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+::-webkit-input-placeholder {
+  color: inherit;
+  opacity: 0.54;
+}
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button;
+  font: inherit;
+}
diff --git a/skyquake/framework/style/common.scss b/skyquake/framework/style/common.scss
new file mode 100644 (file)
index 0000000..db161b2
--- /dev/null
@@ -0,0 +1,127 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@import '../../node_modules/open-iconic/font/css/open-iconic.css';
+@import './_colors.scss';
+
+$green: #31D2B1;
+$black: #2D3036;
+$white: #F8F9FC;
+$headers: #EFF5FE;
+$grey: #ABB6C6;
+
+/* Mixins */
+
+@mixin arrow($size, $color) {
+    width: 0;
+    height:0;
+    &--up {
+        border-left: $size solid transparent;
+        border-right: $size solid transparent;
+
+        border-bottom: $size solid $color;
+    }
+    &--down {
+        border-left: $size solid transparent;
+        border-right: $size solid transparent;
+
+        border-top: $size solid $color;
+    }
+    &--left {
+        border-top: $size solid transparent;
+        border-bottom: $size solid transparent;
+
+        border-right: $size solid $color;
+    }
+    &--right {
+        border-top: $size solid transparent;
+        border-bottom: $size solid transparent;
+
+        border-left: $size solid $color;
+    }
+}
+
+
+/* General */
+
+
+.crouton {
+    color: #FFF;
+    line-height: 140%;
+    border-radius: 3px;
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    max-width: 700px;
+    width: 90%;
+    text-align: center;
+    z-index: 99999;
+    margin: 0 auto;
+    div {
+        padding: 20px;
+        &.info {
+            background-color: #1F8DD6;
+        }
+        &.success {
+            background-color: #50CD84;
+        }
+        &.warning {
+            background-color: #FF8859;
+        }
+        &.error {
+            background-color: #FF5F5F;
+        }
+        span {
+            display: block;
+            margin-bottom: 0;
+            margin-left: 0px;
+        }
+        .buttons {
+            text-align: right;
+            button {
+                &.btn, &.retry, &.close, &.cancel, &.ignore {
+                    padding: 0px;
+                    border: 1px solid transparent;
+                    border-radius: 3px;
+                }
+                &:hover {
+                    opacity: .75;
+                }
+                &.retry {
+                    border-color: #FFF;
+                }
+                &.btn {
+                    &.close {
+                        border-color: #FF5F5F;
+                        margin-left: 10px;
+                    }
+                }
+            }
+        }
+    }
+}
+.noticeSubText {
+    padding-bottom:0.5rem;
+    color:$darker-gray;
+    font-size:0.75rem;
+    &_right {
+        text-align:right;
+    }
+}
diff --git a/skyquake/framework/style/core.css b/skyquake/framework/style/core.css
new file mode 100644 (file)
index 0000000..2a64a8c
--- /dev/null
@@ -0,0 +1,2062 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "./vendor/css-reset-2.0/css-reset.css";
+.has-drop-shadow {
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+em.circle {
+    border: 1px solid #333;
+    border-radius: 50%;
+    display: inline-block;
+    padding: 0 .225rem
+}
+@font-face {
+    font-family: roboto-regular;
+    src: url(./fonts/Roboto-Regular-webfont.eot);
+    src: url(./fonts/Roboto-Regular-webfont.eot?#iefix) format('embedded-opentype'), url(./fonts/Roboto-Regular-webfont.woff) format('woff'), url(./fonts/Roboto-Regular-webfont.ttf) format('truetype'), url(./fonts/Roboto-Regular-webfont.svg#robotoregular) format('svg')
+}
+@font-face {
+    font-family: roboto-condensed-bold;
+    src: url(./fonts/RobotoCondensed-Bold-webfont.eot);
+    src: url(./fonts/RobotoCondensed-Bold-webfont.eot?#iefix) format('embedded-opentype'), url(./fonts/RobotoCondensed-Bold-webfont.woff) format('woff'), url(./fonts/RobotoCondensed-Bold-webfont.ttf) format('truetype'), url(./fonts/RobotoCondensed-Bold-webfont.svg#roboto_condensedbold) format('svg')
+}
+@font-face {
+    font-family: roboto-light;
+    src: url(./fonts/Roboto-Light-webfont.ttf)
+}
+body {
+    font-family: roboto-regular, Helvetica, Arial, sans-serif;
+    line-height: 1.2
+}
+h1 {
+    font-size: 1.625rem;
+    font-weight: 400
+}
+h2 {
+    font-size: 1.375rem
+}
+em.large {
+    font-size: 1.75rem
+}
+.all-caps {
+    font-weight: 700;
+    text-transform: uppercase
+}
+.small-caps {
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.unit {
+    font-size: .5625rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.label {
+    font-size: .625rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+body {
+    background: #f1f1f1;
+    margin: 0;
+    padding: 0
+}
+.flex-row {
+    display: flex;
+    flex-direction: row
+}
+.flex-center {
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.header-app {
+    background-color: #f1f1f1;
+    height: 91px;
+    padding: 20px 0;
+    position: relative
+}
+.header-app h1 {
+    background: url(./img/header-logo.png) no-repeat left center;
+    height: 51px;
+    line-height: 51px;
+    margin-left: 80px;
+    padding-left: 118px;
+    position: absolute;
+    left: 0;
+    text-transform: uppercase
+}
+.header-app nav.launchpad-nav {
+    box-sizing: border-box;
+    height: 28px;
+    line-height: 28px;
+    position: absolute;
+    right: 80px;
+    top: 32px
+}
+.header-app nav.launchpad-nav:before,
+.header-app nav.launchpad-nav:after {
+    content: " ";
+    display: block
+}
+.header-app nav.launchpad-nav:after {
+    clear: both
+}
+.header-app nav.launchpad-nav a {
+    border-left: 1px solid #e5e5e5;
+    display: block;
+    float: left;
+    height: 28px;
+    margin-left: 20px;
+    padding-left: 20px;
+    color:black;
+    text-decoration:none;
+}
+.header-app nav.launchpad-nav h4 {
+    display: inline-block;
+    font-size: 11px;
+    margin-right: 8px;
+    text-transform: uppercase
+}
+.header-app nav.launchpad-nav img {
+    width: 28px
+}
+.header-app nav.viewport-nav {
+    position: absolute;
+    right: 0
+}
+.header-app nav.viewport-nav a {
+    text-decoration: none
+}
+.header-app nav.viewport-nav h2 {
+    color: #30baef;
+    font-size: 100%;
+    height: 54px;
+    line-height: 54px;
+    margin-right: 24px;
+    padding-right: 55px;
+    text-transform: uppercase
+}
+.header-app nav.viewport-nav.top h2 {
+    background: url(./img/viewport-nav-top.png) no-repeat right center
+}
+.header-app nav.viewport-nav.right h2 {
+    background: url(./img/viewport-nav-right.png) no-repeat right center
+}
+.header-app nav.viewport-nav.bottom h2 {
+    background: url(./img/viewport-nav-bottom.png) no-repeat right center
+}
+.header-app nav.viewport-nav.left h2 {
+    background: url(./img/viewport-nav-left.png) no-repeat right center
+}
+.header-app nav.viewport-nav.center h2 {
+    background: url(./img/viewport-nav-center.png) no-repeat right center
+}
+.app-body {
+    margin-bottom: 12px
+}
+.app-body:before,
+.app-body:after {
+    content: " ";
+    display: block
+}
+.app-body:after {
+    clear: both
+}
+.has-corner-accents {
+    position: relative
+}
+.corner-accent {
+    border: 1px solid #000;
+    display: block;
+    height: 4px;
+    position: absolute;
+    width: 4px
+}
+.corner-accent.top {
+    border-bottom: 0;
+    top: -1px
+}
+.corner-accent.right {
+    border-left: 0;
+    right: -1px
+}
+.corner-accent.bottom {
+    border-top: 0;
+    bottom: -1px
+}
+.corner-accent.left {
+    border-right: 0;
+    left: -1px
+}
+.has-diag-corners {
+    position: relative
+}
+.has-diag-corners.top:before {
+    border-left: 149px solid #dadada;
+    border-top: 134px solid #ccc;
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 0
+}
+.has-diag-corners.top:after {
+    border-right: 149px solid #dadada;
+    border-top: 134px solid #ccc;
+    content: '';
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 0
+}
+.has-diag-corners.bottom:before {
+    border-right: 149px solid #ccc;
+    border-top: 134px solid #dadada;
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 0
+}
+.has-diag-corners.bottom:after {
+    border-left: 149px solid #ccc;
+    border-top: 134px solid #dadada;
+    content: '';
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 0
+}
+.active {
+    background-color: #00acee!important;
+    border-color: #00acee!important;
+    color: #fff!important
+}
+.active-text {
+    color: #00acee!important
+}
+.status-clear {
+    background: #93cb43!important;
+    color: #fff
+}
+.status-clear-text {
+    color: #93cb43
+}
+.status-info {
+    background: #30baef!important;
+    color: #fff
+}
+.status-info-text {
+    color: #30baef
+}
+.dropdown-set {
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.dropdown {
+    position: relative
+}
+.dropdown>a {
+    background-color: #00acee;
+    color: #fff;
+    display: block;
+    margin: 0 .875rem;
+    padding: .625rem;
+    position: relative;
+    width: 16rem;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.dropdown>a i {
+    font-size: 1.375rem;
+    position: absolute;
+    right: .5rem;
+    top: .5rem
+}
+.dropdown>ul {
+    display: none;
+    position: absolute;
+    left: 0;
+    top: 0
+}
+.fleet-card {
+    background-color: rgba(203, 209, 209, .5);
+    flex: 0 1 48%;
+    height: 403px;
+    margin: 12px 0 12px 20px
+}
+.fleet-card .layout-col.left {
+    flex: 0 1 69%
+}
+.fleet-card .layout-col.right {
+    flex: 0 1 31%
+}
+.fleet-card-header {
+    color: #fff
+}
+.fleet-card-pwr-status {
+    background-color: #93cb43;
+    position: relative
+}
+.fleet-card-pwr-status:before,
+.fleet-card-pwr-status:after {
+    content: " ";
+    display: block
+}
+.fleet-card-pwr-status:after {
+    clear: both
+}
+.fleet-card-pwr-status a[href] {
+    display: inline-block;
+    height: 53px;
+    width: 89%
+}
+.fleet-card-pwr-status h2 {
+    color: #fff;
+    float: left;
+    font-size: 16px;
+    font-weight: 400;
+    margin: 21px 0 0 24px;
+    text-transform: uppercase
+}
+.fleet-card-pwr-status .button-open-viewport {
+    position: absolute;
+    right: 12px;
+    top: 19px;
+    width: 20px
+}
+.fleet-card-pwr-btn {
+    background-color: #333;
+    box-shadow: 2px 2px rgba(0, 0, 0, .35);
+    color: #93cb43;
+    cursor: pointer;
+    display: inline-block;
+    float: left;
+    padding: 12px
+}
+.fleet-card-env-status {
+    align-items: center;
+    background-color: #7cc118;
+    font-size: 10px;
+    height: 75px;
+    display: flex;
+    justify-content: flex-start
+}
+.fleet-card-env-status h3 {
+    font-size: 12px;
+    text-transform: uppercase
+}
+.fleet-card-env-status i {
+    float: left;
+    font-size: 30px;
+    margin: 12px
+}
+.fleet-card-env-status>div {
+    float: left;
+    margin-left: 22px
+}
+.fleet-card-graph {
+    border: 2px solid rgba(252, 252, 252, .5);
+    border-right: 0;
+    border-bottom: 0;
+    flex: 0 1 50%;
+    padding: 24px 0;
+    text-align: center
+}
+.fleet-card-graph:first-child {
+    border-left: 0
+}
+.fleet-card-graph h3 {
+    font-size: 12px;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.fleet-card-graph img {
+    margin-top: 18px;
+    width: 75%
+}
+.fleet-card-graph-container {
+    height: 271px
+}
+.fleet-card-params {
+    background-color: #e5e5e5;
+    border-left: 2px solid rgba(252, 252, 252, .5);
+    font-size: 11px;
+    text-align: center
+}
+.fleet-card-params dt {
+    background-color: #ccc;
+    padding: 8px 0 4px;
+    text-transform: uppercase
+}
+.fleet-card-params dd {
+    background-color: #ccc;
+    border-bottom: 2px solid #f1f1f1;
+    padding: 4px 0 8px
+}
+.fleet-card-params-detail {
+    background: #fff;
+    box-sizing: border-box;
+    font-size: 11px;
+    text-align: center
+}
+.fleet-card-params-detail.sla-panel,
+.fleet-card-params-detail.nfvi-panel {
+    cursor: pointer;
+    height: 403px;
+    padding: 0 20px
+}
+.fleet-card-params-detail h4 {
+    padding-top: 24px;
+    text-transform: uppercase
+}
+.fleet-card-params-detail h4 i {
+    font-size: 16px;
+    margin-left: 18px
+}
+.fleet-card-params-detail li {
+    border-top: 1px solid #e5e5e5;
+    margin-top: 20px;
+    padding-top: 20px
+}
+.fleet-card-params-detail li:first-child {
+    border: 0
+}
+.fleet-card-params-detail.trafgen-panel {
+    height: 403px;
+    position: relative
+}
+.fleet-card-params-detail.trafgen-panel h4 {
+    padding-top: 24px;
+    text-transform: uppercase
+}
+.fleet-card-params-detail.trafgen-panel h4 i {
+    font-size: 16px;
+    margin-left: 18px
+}
+.fleet-card-params-detail.trafgen-panel .slider-container {
+    font-size: 12px;
+    padding: 0 50px;
+    margin-top: 48px;
+    justify-content: space-between
+}
+.fleet-card-params-detail.trafgen-panel .slider-vert {
+    flex: 0 1 25%;
+    margin: 0
+}
+.fleet-card-params-detail.trafgen-panel .slider-vert-track {
+    width: 30px
+}
+.fleet-card-params-detail.trafgen-panel .slider-vert-header {
+    font-size: 10px;
+    margin-bottom: 6px
+}
+.fleet-card-params-detail.trafgen-panel .slider-vert-start-val {
+    margin-bottom: 3px
+}
+.fleet-card-params-detail.trafgen-panel .slider-vert-end-val {
+    margin-top: 3px
+}
+.fleet-card-params-detail.trafgen-panel .packet-size-slider .slider-vert-header {
+    margin-left: -16px
+}
+.fleet-card-params-detail.trafgen-panel .packet-size-slider .slider-vert-position {
+    top: 130px
+}
+.fleet-card-params-detail.trafgen-panel .packet-size-slider .slider-vert-position.left {
+    width: 69p
+}
+.fleet-card-params-detail.trafgen-panel .rate-slider .slider-vert-position {
+    top: 40px
+}
+.fleet-card-toggle-set {
+    border-bottom: 2px solid #f1f1f1;
+    padding: 18px
+}
+.fleet-card-toggle-set a[role=button] {
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.fleet-card-toggle-set a:last-child {
+    margin-bottom: 0
+}
+.fleet-card-actions {
+    background-color: #ccc;
+    padding: 22px 18px
+}
+.fleet-card-actions .button-set {
+    margin-top: 6px
+}
+.fleet-card-actions a[role=button] {
+    display: block;
+    float: left;
+    text-align: center;
+    text-transform: uppercase;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.fleet-card-actions .trafgen-start {
+    background-color: #333;
+    color: #fff;
+    flex: 0 1 80%;
+    margin-right: 2px;
+    padding: 8px 0
+}
+.fleet-card-actions .trafgen-start i {
+    margin-right: 6px
+}
+.fleet-card-actions .trafgen-toggle {
+    background-color: #fff;
+    color: #333;
+    flex: 0 1 20%;
+    padding: 2px 8px 2px 11px;
+    font-size: 21px
+}
+.fleet-card-toggle {
+    background-color: #fff;
+    box-shadow: 4px 4px #e5e5e5;
+    color: #30baef;
+    cursor: pointer;
+    display: block;
+    margin-bottom: 12px;
+    padding: 20px
+}
+.fleet-card-toggle h4 {
+    color: #000;
+    margin-bottom: 6px;
+    text-transform: uppercase
+}
+.fleet-card.empty-card {
+    font-size: 12px;
+    text-align: center;
+    text-transform: uppercase
+}
+.fleet-card.empty-card a {
+    color: #000;
+    display: block;
+    font-weight: 700;
+    height: 100%;
+    text-decoration: none;
+    width: 100%
+}
+.fleet-card.empty-card a img {
+    margin-top: 130px
+}
+.fleet-card.empty-card a p {
+    margin-top: 24px
+}
+.navpanel-container {
+    background-color: #dadada;
+    box-sizing: border-box;
+    display: flex;
+    flex-flow: row wrap
+}
+.navpanel {
+    background-color: #ccc;
+    box-sizing: border-box;
+    color: #000;
+    padding: 1.5rem 0;
+    text-align: center;
+    text-decoration: none
+}
+.navpanel.top {
+    flex: 1 0 100%;
+    order: 1
+}
+.navpanel.right {
+    order: 4
+}
+.navpanel.bottom {
+    align-self: baseline;
+    flex: 0 1 100%;
+    order: 5
+}
+.navpanel.left {
+    order: 2
+}
+.navpanel.left,
+.navpanel.right {
+    background-color: #dadada;
+    flex: 0 1 auto;
+    padding: 0 1.5rem;
+    width: 148px
+}
+.mainpanel {
+    flex: 2 1;
+    order: 3
+}
+.progress-bar {
+    background: #fff;
+    height: 30px;
+    line-height: 30px;
+    padding-right: 12px;
+    position: relative;
+    text-align: right
+}
+.progress-bar span {
+    background: #30baef;
+    color: #fff;
+    display: block;
+    font-size: .75rem;
+    height: 30px;
+    padding: 0 .75em;
+    position: absolute;
+    left: 0;
+    top: 0
+}
+.config-parent {
+    cursor: pointer
+}
+.config-list {
+    display: block;
+    margin-left: 10px
+}
+.config-list.closed {
+    display: none
+}
+.slider-container {
+    text-align: center
+}
+.slider-vert {
+    float: left;
+    width: 42px;
+    margin-left: 47px!important
+}
+.slider-vert-header {
+    font-size: 11px;
+    margin-bottom: 4px;
+    text-transform: uppercase;
+    white-space: nowrap
+}
+.slider-vert-start-val,
+.slider-vert-end-val {
+    font-size: 14px
+}
+.slider-vert-track {
+    border-left: 1px solid #ccc;
+    border-right: 1px solid #ccc;
+    height: 200px;
+    position: relative;
+    width: 30px
+}
+.slider-vert-handle {
+    background-color: #00acee;
+    box-shadow: 2px 2px rgba(0, 0, 0, .2);
+    display: inline-block;
+    height: 16px;
+    width: 34px
+}
+.slider-vert-position {
+    color: #30baef;
+    font-size: 12px;
+    position: absolute;
+    white-space: nowrap!important
+}
+.slider-vert-position.left {
+    left: -38px
+}
+.slider-vert-position.left .slider-vert-handle {
+    float: right;
+    margin-left: 6px
+}
+.slider-vert-position.right {
+    left: -3px
+}
+.slider-vert-position.right .slider-vert-handle {
+    float: left;
+    margin-right: 6px
+}
+.slider-toggle {
+    float: left;
+    margin: 12px 27px 12px 0;
+    white-space: nowrap;
+    width: 43%
+}
+.slider-toggle:before,
+.slider-toggle:after {
+    content: " ";
+    display: block
+}
+.slider-toggle:after {
+    clear: both
+}
+.slider-toggle label {
+    display: block;
+    font-size: 13px;
+    margin-bottom: 8px;
+    text-transform: uppercase
+}
+.slider-toggle-track {
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.slider-toggle-track:before,
+.slider-toggle-track:after {
+    content: " ";
+    display: block
+}
+.slider-toggle-track:after {
+    clear: both
+}
+.slider-toggle-option {
+    background-color: #fff;
+    color: #dadada;
+    float: left;
+    font-size: 12px;
+    margin-top: -4px;
+    padding: 8px;
+    text-align: center;
+    width: 50%
+}
+a[role=button] {
+    cursor: pointer
+}
+.button-action-toggle {
+    background-color: #333;
+    box-shadow: 4px 4px #e5e5e5;
+    color: #fff;
+    cursor: pointer;
+    display: block;
+    padding: 12px 0;
+    text-align: center;
+    text-transform: uppercase
+}
+.button-action-toggle i {
+    margin-right: 6px
+}
+.button-half-border {
+    border: 2px solid #000;
+    border-top: 0;
+    box-shadow: 2px 2px rgba(0, 0, 0, .35);
+    padding: 4px 24px;
+    position: relative;
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.button-half-border:before,
+.button-half-border:after {
+    background: #ccc;
+    content: '';
+    display: block;
+    height: 10px;
+    position: absolute;
+    top: 0;
+    width: 4px
+}
+.button-half-border:before {
+    left: -4px
+}
+.button-half-border:after {
+    right: -4px
+}
+.step-control {
+    position: relative;
+    text-align: center
+}
+.step-control .step {
+    cursor: pointer;
+    display: block;
+    position: absolute;
+    top: 0
+}
+.step-control .step.decrease {
+    left: 0
+}
+.step-control .step.increase {
+    right: 0
+}
+.toggle-set {
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.toggle-control {
+    align-content: center;
+    display: flex;
+    width: 18.75rem;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.toggle-control>a {
+    background-color: #fff;
+    color: #333;
+    flex: 0 1 9.375rem;
+    padding: .625rem 0;
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.toggle-control>a.selected {
+    background-color: #00acee;
+    color: #fff
+}
+.splitterContainer {
+    -webkit-flex: 1;
+    -moz-flex: 1;
+    -ms-flex: 1;
+    flex: 1;
+    display: flex;
+    -webkit-flex-direction: column;
+    -moz-flex-direction: column;
+    -ms-flex-direction: column;
+    flex-direction: column
+}
+.splitterContainer .content {
+    margin-right: 60px
+}
+.splitterContainer #handle {
+    z-index: 3;
+    position: relative;
+    cursor: row-resize;
+    min-height: 20px
+}
+.splitterContainer .splitter {
+    height: 32px;
+    width: 100%;
+    box-shadow: none;
+    background-image: none;
+    align-items: center;
+    padding: 4px;
+    border-top: 1px solid #121212;
+    border-bottom: 1px solid #121212;
+    background-color: #454545;
+    z-index: 999
+}
+.splitterContainer .splitter .adjust {
+    position: absolute;
+    right: 0;
+    top: 0;
+    margin-top: 5px
+}
+.splitterContainer .splitter .adjust .splitterButtons {
+    position: relative;
+    float: left;
+    border: 1px solid #fff;
+    border-radius: 8px;
+    fill: #fff;
+    height: 15px;
+    width: 15px;
+    cursor: pointer;
+    color: #fff
+}
+.splitterContainer .vpane-top {
+    flex: 1;
+    overflow-y: scroll
+}
+.splitterContainer .vpane-bottom {
+    display: block;
+    overflow-y: scroll;
+    padding: 10px;
+    position: relative
+}
+.launchpad {
+    flex-wrap: wrap
+}
+.create-fleet-header {
+    color: #00acee;
+    display: inline-block;
+    margin: 0 0 20px 24px;
+    position: relative
+}
+.create-fleet-header img {
+    position: absolute;
+    right: -24px;
+    bottom: 0;
+    width: 16px
+}
+.create-fleet-services,
+.create-fleet-pool {
+    background-color: #e5e5e5
+}
+.create-fleet>.flex-row {
+    justify-content: space-around
+}
+.create-fleet>.flex-row>li {
+    flex: 0 1 30%
+}
+.create-fleet>.flex-row>li h3 {
+    background-color: #fff;
+    padding: 12px 18px;
+    text-transform: uppercase
+}
+.create-fleet .list-fleet-services {
+    flex-wrap: wrap;
+    text-align: center;
+    margin: 24px auto;
+    width: 90%
+}
+.create-fleet .list-fleet-services a {
+    background-color: #fff;
+    flex: 0 1 32%;
+    margin: 0 4px 4px 0;
+    padding: 4px;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.create-fleet .list-fleet-services a h5 {
+    font-size: 10px;
+    margin: 5px 0 0 5px;
+    text-align: left
+}
+.create-fleet .list-fleet-services a img {
+    margin-top: 10px;
+    width: 70%
+}
+.create-fleet .list-pools {
+    padding: 24px
+}
+.create-fleet .list-pools li a {
+    background-color: #fff;
+    display: block;
+    font-size: 12px;
+    margin-bottom: 24px;
+    padding: 12px;
+    text-align: center;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.create-fleet .list-pools li h4 {
+    text-align: left
+}
+.create-fleet .list-pools li img {
+    margin-top: 24px;
+    width: 65%
+}
+.create-fleet .parameter-controls {
+    background-color: #e5e5e5;
+    padding: 18px 0 18px 24px
+}
+.create-fleet .parameter-controls:before,
+.create-fleet .parameter-controls:after {
+    content: " ";
+    display: block
+}
+.create-fleet .parameter-controls:after {
+    clear: both
+}
+.create-fleet .parameter-controls.epa label {
+    display: block;
+    float: left;
+    margin: 6px 0 0
+}
+.create-fleet .parameter-controls.epa .slider-toggle {
+    width: 100%
+}
+.create-fleet .parameter-controls.epa .slider-toggle-track {
+    float: right;
+    margin-right: 27px;
+    width: 43%
+}
+.create-fleet .parameter-controls.epa .slider-toggle-option {
+    color: #333
+}
+.create-fleet .parameter-controls.vmf li {
+    font-size: 13px;
+    margin-bottom: 12px
+}
+.create-fleet .parameter-controls.vmf li:before,
+.create-fleet .parameter-controls.vmf li:after {
+    content: " ";
+    display: block
+}
+.create-fleet .parameter-controls.vmf li:after {
+    clear: both
+}
+.create-fleet .parameter-controls.vmf label {
+    display: block;
+    float: left;
+    padding: 10px 0 6px;
+    text-transform: uppercase
+}
+.create-fleet .parameter-controls.vmf .step-control {
+    background-color: #fff;
+    color: #30baef;
+    float: right;
+    margin-right: 27px;
+    padding: 10px 0 6px;
+    text-align: center;
+    width: 175px
+}
+.create-fleet .parameter-controls.vmf .step-control .step {
+    font-size: 16px;
+    height: 31px;
+    width: 31px;
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.create-fleet .parameter-controls.vmf .step-control .step.decrease {
+    background-color: #ccc;
+    border-right: 2px solid #e5e5e5;
+    color: #666
+}
+.create-fleet .parameter-controls.vmf .step-control .step.increase {
+    background-color: #fff;
+    border-left: 2px solid #e5e5e5;
+    color: #333;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.create-fleet .adv-toggle h4 {
+    background-color: #fff;
+    color: #333
+}
+.create-fleet-params h4 {
+    background-color: #00acee;
+    color: #fff;
+    font-size: 12px;
+    padding: 6px 22px;
+    position: relative;
+    text-transform: uppercase;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.create-fleet-params h4 i {
+    font-size: 18px;
+    position: absolute;
+    right: 12px;
+    top: 6px
+}
+.create-fleet-actions {
+    clear: both;
+    margin-top: 36px;
+    text-align: center
+}
+.create-fleet-actions a {
+    color: #000;
+    display: inline-block;
+    font-size: 12px;
+    padding: 8px 64px;
+    text-decoration: none;
+    text-transform: uppercase;
+    box-shadow: 2px 2px rgba(0, 0, 0, .15)
+}
+.create-fleet-actions a.save {
+    background-color: #fff;
+    border: 1px solid #ccc;
+    border-top: 0;
+    cursor: pointer;
+    margin-right: 48px
+}
+.create-fleet-actions a.launch {
+    background-color: #333;
+    border: 1px solid #000;
+    border-top: 0;
+    color: #fff
+}
+.create-fleet-actions a.launch:hover,
+.create-fleet-actions a.launch:active {
+    background: #00acee;
+    color: #fff
+}
+.viewport-dash {
+    font-size: .75rem
+}
+.viewport-dash .mainpanel {
+    background: #f1f1f1;
+    border-left: .1875rem solid #c2c2c2;
+    border-right: .1875rem solid #c2c2c2;
+    box-sizing: border-box;
+    padding: 2.25rem
+}
+.viewport-dash .mainpanel.flex-row {
+    align-items: flex-start;
+    flex-wrap: wrap
+}
+.viewport-dash .mainpanel.flex-row .flex-left {
+    flex: 0 1 45%
+}
+.viewport-dash .mainpanel.flex-row .flex-right {
+    flex: 0 1 55%
+}
+.viewport-dash .mainpanel.flex-row .flex-right .flex-row {
+    align-items: stretch;
+    flex-wrap: wrap
+}
+.viewport-dash .mainpanel.flex-row .flex-right .flex-row .sla-container {
+    flex: 0 1 75%
+}
+.viewport-dash .mainpanel.flex-row .flex-right .flex-row .network-container {
+    flex: 0 1 25%
+}
+.viewport-dash .mainpanel.flex-row .flex-right .flex-row .mgmt-container {
+    flex: 0 1 100%
+}
+.viewport-dash .mainpanel h2 {
+    background-color: #fff;
+    margin-bottom: .125rem;
+    font-size: .75rem;
+    padding: 1.125rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .mainpanel table {
+    text-align: center
+}
+.viewport-dash .mainpanel table th {
+    background: #dadada;
+    padding: .375rem;
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .mainpanel table td {
+    background: #e5e5e5;
+    border-right: .0625rem solid #e5e5e5;
+    padding: .5625rem 1.5rem
+}
+.viewport-dash .mainpanel table td .status-clear-text {
+    margin-bottom: .75rem
+}
+.viewport-dash .mano {
+    margin-bottom: 1.5rem
+}
+.viewport-dash .mano dl {
+    align-items: center;
+    background: #7cc118;
+    color: #fff
+}
+.viewport-dash .mano dl:before,
+.viewport-dash .mano dl:after {
+    content: " ";
+    display: block
+}
+.viewport-dash .mano dl:after {
+    clear: both
+}
+.viewport-dash .mano dl dt,
+.viewport-dash .mano dl dd {
+    display: flex;
+    padding: .375rem 1.125rem
+}
+.viewport-dash .mano dl dt {
+    float: left;
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .mano dl dd {
+    float: right
+}
+.viewport-dash .mano table {
+    width: 100%
+}
+.viewport-dash .mano table td:last-child {
+    border: 0
+}
+.viewport-dash .vcs table {
+    border-collapse: separate;
+    border-spacing: .0625rem solid;
+    width: 100%
+}
+.viewport-dash .vcs table thead th {
+    background-color: #e5e5e5;
+    border-right: 1px solid #dadada;
+    padding: 1.125rem 0
+}
+.viewport-dash .vcs table thead th:last-child {
+    border: 0
+}
+.viewport-dash .vcs table tbody td {
+    width: 30%;
+    border-bottom: 1px solid #e5e5e5
+}
+.viewport-dash .vcs table tbody th {
+    padding-left: 1.125rem;
+    text-align: left;
+    width: 40%
+}
+.viewport-dash .vcs table tbody tr:nth-child(even) th {
+    background-color: #e5e5e5
+}
+.viewport-dash .sla {
+    flex: 1 1 60%;
+    flex-wrap: nowrap;
+    margin: 0 1.5rem
+}
+.viewport-dash .sla h3 {
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .sla .wp-pool-manager {
+    flex: 0 1 30%
+}
+.viewport-dash .sla .wp {
+    background: #dadada;
+    margin-bottom: .125rem;
+    padding: .75rem;
+    text-align: center
+}
+.viewport-dash .sla .wp h3 {
+    text-align: left
+}
+.viewport-dash .sla .wp img {
+    margin: .875rem 0;
+    width: 90%
+}
+.viewport-dash .sla .pool-manager {
+    background: #dadada;
+    padding: .6875rem
+}
+.viewport-dash .sla .pool-manager .progress-bar {
+    margin: .75rem 0
+}
+.viewport-dash .sla table.stats {
+    border-left: 2px solid #f1f1f1;
+    flex: 0 1 70%;
+    text-align: left;
+    width: 70%
+}
+.viewport-dash .sla table.stats th,
+.viewport-dash .sla table.stats td {
+    border-bottom: 1px solid #f1f1f1;
+    border-right: 1px solid #f1f1f1;
+    padding: .375rem;
+    vertical-align: middle;
+    width: 50%
+}
+.viewport-dash .sla table.stats td {
+    text-align: right
+}
+.viewport-dash .sla table.stats th {
+    background: #dadada
+}
+.viewport-dash .sla table.stats th.alt {
+    background: #e5e5e5
+}
+.viewport-dash .network li {
+    background-color: #dadada;
+    font-size: 1.625rem;
+    margin-top: .125rem;
+    padding: 1.125rem .875rem;
+    text-align: center
+}
+.viewport-dash .network li:nth-child(even) {
+    background-color: #e5e5e5
+}
+.viewport-dash .network li:last-child {
+    border: 0
+}
+.viewport-dash .network li .label {
+    display: block;
+    margin-bottom: .6rem
+}
+.viewport-dash .mgmt {
+    margin: 1.5rem 0 0 1.5rem
+}
+.viewport-dash .mgmt:before,
+.viewport-dash .mgmt:after {
+    content: " ";
+    display: block
+}
+.viewport-dash .mgmt:after {
+    clear: both
+}
+.viewport-dash .mgmt ul {
+    width: 100%
+}
+.viewport-dash .mgmt ul:before,
+.viewport-dash .mgmt ul:after {
+    content: " ";
+    display: block
+}
+.viewport-dash .mgmt ul:after {
+    clear: both
+}
+.viewport-dash .mgmt h2 {
+    padding: 0
+}
+.viewport-dash .mgmt li {
+    background: #dadada;
+    flex: 1 1 20.5%;
+    font-size: 1.625rem;
+    height: 5.938rem;
+    margin-left: .125rem;
+    padding: .5rem 0;
+    text-align: center
+}
+.viewport-dash .mgmt li:first-child {
+    background-color: #fff;
+    flex: 0 1 10%;
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.viewport-dash .mgmt li:nth-child(even) {
+    background-color: #e5e5e5
+}
+.viewport-dash .mgmt li .label {
+    display: block;
+    margin-bottom: .875rem
+}
+.viewport-dash .mgmt li .unit {
+    display: block
+}
+.viewport-dash .navpanel .service-orch {
+    display: flex;
+    align-items: center;
+    margin-left: 11.88rem
+}
+.viewport-dash .navpanel .service-orch .button-half-border {
+    float: left;
+    margin-right: 7.75rem
+}
+.viewport-dash .navpanel .service-orch li {
+    background: #e5e5e5;
+    float: left;
+    height: 5.313rem;
+    padding: .75rem 1.5rem;
+    position: relative;
+    margin-right: 1.5rem;
+    width: 7.75rem;
+    align-items: center;
+    display: flex;
+    justify-content: center;
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .navpanel .service-orch li:after {
+    border-top: 1px solid #333;
+    content: '';
+    position: absolute;
+    right: -24px;
+    top: 50%;
+    width: 24px
+}
+.viewport-dash .navpanel .service-orch li:last-child {
+    margin: 0
+}
+.viewport-dash .navpanel .service-orch li:last-child:after {
+    border: 0
+}
+.viewport-dash .navpanel .vnf .button-half-border,
+.viewport-dash .navpanel .analytics .button-half-border {
+    margin: 1rem 0 1.5rem
+}
+.viewport-dash .navpanel .vnf .button-half-border:before,
+.viewport-dash .navpanel .analytics .button-half-border:before,
+.viewport-dash .navpanel .vnf .button-half-border:after,
+.viewport-dash .navpanel .analytics .button-half-border:after {
+    background: #dadada
+}
+.viewport-dash .navpanel .vnf dt,
+.viewport-dash .navpanel .analytics dt,
+.viewport-dash .navpanel .vnf dd,
+.viewport-dash .navpanel .analytics dd {
+    margin-bottom: .1875rem;
+    padding: .5rem
+}
+.viewport-dash .navpanel .vnf dt,
+.viewport-dash .navpanel .analytics dt {
+    background: #fff;
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .navpanel .vnf dd,
+.viewport-dash .navpanel .analytics dd {
+    background: #ccc;
+    font-size: 1.375rem
+}
+.viewport-dash .navpanel .vnf .unit,
+.viewport-dash .navpanel .analytics .unit {
+    display: block;
+    margin-top: .5rem
+}
+.viewport-dash .navpanel .vim {
+    display: flex;
+    align-items: center;
+    margin-left: 11.88rem
+}
+.viewport-dash .navpanel .vim .button-half-border {
+    float: left;
+    margin-right: 2.25rem
+}
+.viewport-dash .navpanel .vim table {
+    border-collapse: separate;
+    border-spacing: .125rem;
+    float: left;
+    text-align: center
+}
+.viewport-dash .navpanel .vim table:last-child {
+    margin-left: 1.5rem
+}
+.viewport-dash .navpanel .vim table th {
+    background: #fff;
+    padding: .5rem .75rem;
+    text-align: left;
+    font-size: .6875rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-dash .navpanel .vim table td {
+    background: #e5e5e5;
+    font-size: 1.375rem;
+    padding: .375rem 1rem .375rem
+}
+.viewport-dash .navpanel .vim table td .label {
+    display: block;
+    margin-bottom: .5rem
+}
+.viewport-so .vpane-bottom {
+    display: flex
+}
+.viewport-so .panel-half {
+    padding: 10px
+}
+.viewport-vim {
+    font-size: .75rem
+}
+.viewport-vim .mainpanel {
+    background: #f1f1f1;
+    padding: 1.5rem
+}
+.viewport-vim .mainpanel .vim-controls {
+    margin-bottom: 3rem
+}
+.viewport-vim .mainpanel .vim-controls>* {
+    flex: 1 1 auto;
+    justify-content: flex-end
+}
+.viewport-vim .mainpanel .vim-controls h2 {
+    margin-top: .375rem
+}
+.viewport-vim .switch-table-set {
+    justify-content: space-around;
+    margin-bottom: 3rem
+}
+.viewport-vim .switch-table {
+    flex: 0 1 30%
+}
+.viewport-vim .switch-table table {
+    width: 100%
+}
+.viewport-vim .switch-table th,
+.viewport-vim .switch-table td {
+    border-bottom: 2px solid #f1f1f1;
+    vertical-align: middle;
+    padding: .5625rem .875rem
+}
+.viewport-vim .switch-table th.switch h3 {
+    background: url(./img/icon-switch.png) no-repeat left top;
+    height: 1.7rem;
+    padding-left: 4rem;
+    padding-top: .55rem
+}
+.viewport-vim .switch-table th.host {
+    background: #ccc url(./img/icon-host.png) no-repeat 21px center;
+    height: 4rem;
+    padding: 0 1.25rem 0 3.375rem
+}
+.viewport-vim .switch-table thead th {
+    background-color: #fff;
+    font-size: .875rem;
+    font-weight: 700
+}
+.viewport-vim .switch-table thead th:last-child {
+    text-align: left
+}
+.viewport-vim .switch-table thead th small {
+    display: block;
+    font-size: .75rem;
+    font-weight: 400;
+    margin-top: .375rem
+}
+.viewport-vim .switch-table tbody th {
+    background-color: #ccc;
+    color: #fff;
+    padding: .5625rem .875rem .875rem 0
+}
+.viewport-vim .switch-table tbody td {
+    background-color: #e5e5e5;
+    font-size: .625rem
+}
+.viewport-vim .switch-table tbody td em {
+    margin-right: .5rem
+}
+.viewport-vim .switch-table tbody td i {
+    font-size: .5625rem;
+    margin-right: .125rem
+}
+.viewport-vim .switch-table tbody td i.inactive {
+    color: #ccc
+}
+.viewport-vim .switch-table tbody tr.selected th {
+    background-color: #00acee
+}
+.viewport-vim .switch-table tbody tr.selected td {
+    background-color: #fff
+}
+.viewport-vim .switch-table tbody tr.selected td:last-child {
+    background: #fff url(./img/table-cell-bg.png) repeat-y right top
+}
+.viewport-vim .vim-legend {
+    display: inline-flex
+}
+.viewport-vim .vim-legend div {
+    background-color: #e5e5e5;
+    padding: .75rem 1.5rem;
+    margin-right: .125rem
+}
+.viewport-vim .vim-legend div:last-of-type {
+    margin-right: 0
+}
+.viewport-vim .vim-legend ul {
+    float: left
+}
+.viewport-vim .vim-legend ul:first-child {
+    margin-right: 2.25rem
+}
+.viewport-vim .vim-legend ol li:first-child {
+    align-items: center;
+    background: url(./img/icon-host-sm.png) no-repeat left center;
+    display: flex;
+    height: 2.188rem;
+    margin-bottom: -.5rem;
+    padding-left: 1.75rem
+}
+.viewport-vim .vim-legend li {
+    margin: .75rem 0
+}
+.viewport-vim .vim-legend li em,
+.viewport-vim .vim-legend li i {
+    margin-right: .75rem
+}
+.viewport-vim .navpanel.top {
+    background-color: #ccc;
+    height: 30px;
+    padding: 0;
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.viewport-vim .navpanel.top:before {
+    border-left: 32px solid #dadada;
+    border-top: 30px solid #ccc
+}
+.viewport-vim .navpanel.top:after {
+    border-right: 32px solid #dadada;
+    border-top: 30px solid #ccc
+}
+.viewport-vim .navpanel.left,
+.viewport-vim .navpanel.right {
+    background-color: #f1f1f1;
+    padding: 0;
+    position: relative;
+    width: 38px
+}
+.viewport-vim .navpanel.left .tilt,
+.viewport-vim .navpanel.right .tilt {
+    background-color: #dadada;
+    height: 100%;
+    position: absolute;
+    left: 24px;
+    top: -2px;
+    transform: rotate(-2deg);
+    width: 38px
+}
+.viewport-vim .navpanel.left .tilt {
+    left: -24px;
+    transform: rotate(2deg)
+}
+.viewport-vnf h2 {
+    padding-bottom: 2rem
+}
+.viewport-vnf h3 {
+    background: #fff;
+    font-size: .875rem;
+    padding: 1.125rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-vnf h4 {
+    font-size: .75rem;
+    margin-bottom: .5625rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.viewport-vnf.navpanel-container {
+    background-color: #f1f1f1
+}
+.viewport-vnf .flex-row {
+    align-items: flex-start;
+    position: relative;
+    width: 100%
+}
+.viewport-vnf .flex-row .link-diagram {
+    position: absolute;
+    bottom: -3.813rem;
+    left: 13.5%
+}
+.viewport-vnf .flex-row .link-diagram img {
+    width: 80%
+}
+.viewport-vnf .mainpanel {
+    margin: 0 0 5rem 5rem
+}
+.viewport-vnf .vnf-card {
+    flex: 0 1 30.5%;
+    margin-right: 2rem;
+    background-color: #e5e5e5
+}
+.viewport-vnf .vnf-card:first-child {
+    margin-left: 0
+}
+.viewport-vnf .vnf-card:last-child {
+    margin-right: 0
+}
+.viewport-vnf .vnf-card table {
+    width: 100%
+}
+.viewport-vnf .vnf-card td {
+    border-bottom: 2px solid #f1f1f1;
+    border-right: 2px solid #f1f1f1;
+    padding: 1.125em 0;
+    text-align: center;
+    width: 50%
+}
+.viewport-vnf .vnf-card td:last-child {
+    border-right: 0
+}
+.viewport-vnf .vnf-card td img {
+    width: 75%
+}
+.viewport-vnf .vnf-card td small {
+    display: block;
+    margin-bottom: 1.5em
+}
+.viewport-vnf .vnf-card tr:first-child td {
+    background-color: #e5e5e5
+}
+.viewport-vnf .vnf-card tr:last-child td {
+    background-color: #dadada
+}
+.viewport-vnf .vnf-card>ul {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    width: 99.8%;
+    border-bottom: 2px solid #f1f1f1
+}
+.viewport-vnf .vnf-card>ul li {
+    background-color: #e5e5e5;
+    flex: 1 1 auto;
+    margin-right: .125rem;
+    padding: 1.5em .75em;
+    text-align: center
+}
+.viewport-vnf .vnf-card>ul li:first-child {
+    flex: 0 1 18%
+}
+.viewport-vnf .vnf-card>ul li:last-child {
+    margin-right: 0
+}
+.viewport-vnf .vnf-card>div {
+    background-color: #dadada;
+    box-sizing: border-box;
+    margin-top: .125rem;
+    padding: .75rem 1.5rem 1.5rem;
+    text-align: center;
+    width: 99.8%
+}
+.viewport-vnf .vnf-card>div .button-action-toggle {
+    font-size: .75rem
+}
+.viewport-vnf .vnf-card.vlb .bindings {
+    padding: 1.125rem 1.5rem
+}
+.viewport-vnf .vnf-card.vlb .bindings em {
+    display: block;
+    margin: 1.063rem 0
+}
+.viewport-vnf .vnf-card.vlb .bindings img {
+    width: .75rem
+}
+.viewport-vnf .navpanel.top,
+.viewport-vnf .navpanel.bottom {
+    background-color: #f1f1f1;
+    height: 38px;
+    overflow: hidden;
+    padding: 0;
+    position: relative
+}
+.viewport-vnf .navpanel.top .tilt,
+.viewport-vnf .navpanel.bottom .tilt {
+    background-color: #dadada;
+    height: 38px;
+    position: absolute;
+    left: 0;
+    top: -25px;
+    transform: rotate(1.4deg);
+    width: 100%
+}
+.viewport-vnf .navpanel.top:before,
+.viewport-vnf .navpanel.bottom:before {
+    border: 0
+}
+.viewport-vnf .navpanel.top:after {
+    border-right: 48px solid #ccc;
+    border-top: 38px solid #dadada
+}
+.viewport-vnf .navpanel.bottom {
+    transform: scaleY(-1)
+}
+.viewport-vnf .navpanel.bottom:after {
+    border-left: 48px solid #dadada;
+    border-top: 38px solid #ccc;
+    transform: scaleY(-1)
+}
+.viewport-vnf .navpanel.right {
+    background-color: #ccc;
+    width: 48px;
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.wag-app>h1 {
+    height: 63px;
+    line-height: 51px;
+    margin-left: 80px;
+    padding-left: 118px
+}
+.wag h2 {
+    padding-bottom: 2rem
+}
+.wag h3 {
+    background: #fff;
+    font-size: .875rem;
+    padding: 1.125rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.wag h4 {
+    font-size: .75rem;
+    margin-bottom: .5625rem;
+    font-weight: 700;
+    text-transform: uppercase
+}
+.wag .slider-container {
+    width: 50%!important;
+    margin: auto
+}
+.wag.navpanel-container {
+    background-color: #f1f1f1
+}
+.wag .flex-row {
+    align-items: flex-start;
+    position: relative;
+    width: 100%
+}
+.wag .mainpanel {
+    margin: 0 5rem 5rem 5rem
+}
+.wag .wag-outer-container {
+    display: flex
+}
+.wag .wag-inner-container {
+    flex-direction: column;
+    flex: 3 1 auto
+}
+.wag .wag-inner-inner-container {
+    display: flex;
+    flex: 1 1 auto;
+    margin-bottom: 40px
+}
+.wag .wag-inner-inner-container .slider-vert-header {
+    margin: 105px 0 0 -16px
+}
+.wag .wag-top-row tbody {
+    height: 614px
+}
+.wag .wag-top-row-half tbody {
+    height: 307px
+}
+.wag .wag-analytics tbody {
+    display: flex;
+    height: 360px
+}
+.wag .wag-analytics tr,
+.wag .wag-top-row tr,
+.wag .wag-top-row-half tr {
+    flex: 1 1 auto
+}
+.wag .wag-analytics tr:last-child {
+    flex: 20 1 auto
+}
+.wag .vnf-card {
+    flex: 1 1 auto;
+    margin-right: 2rem
+}
+.wag .vnf-card:first-child {
+    margin-left: 0;
+    flex: 1 1 auto
+}
+.wag .vnf-card:last-child {
+    margin-right: 0
+}
+.wag .vnf-card table {
+    width: 100%
+}
+.wag .vnf-card td {
+    border-bottom: 2px solid #f1f1f1;
+    border-right: 2px solid #f1f1f1;
+    padding: 1.125em 0;
+    text-align: center;
+    width: 50%
+}
+.wag .vnf-card td:last-child {
+    border-right: 0
+}
+.wag .vnf-card td img {
+    width: 75%
+}
+.wag .vnf-card td small {
+    display: block;
+    margin-bottom: 1.5em
+}
+.wag .vnf-card tr:nth-child(even) td {
+    background-color: #e5e5e5
+}
+.wag .vnf-card tr:nth-child(odd) td {
+    background-color: #dadada
+}
+.wag .vnf-card tr.lighter td {
+    background-color: #e5e5e5
+}
+.wag .vnf-card>ul {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    width: 99.8%
+}
+.wag .vnf-card>ul li {
+    background-color: #e5e5e5;
+    flex: 1 1 auto;
+    margin-right: .125rem;
+    padding: 1.5em .75em;
+    text-align: center
+}
+.wag .vnf-card>ul li:first-child {
+    flex: 0 1 18%
+}
+.wag .vnf-card>ul li:last-child {
+    margin-right: 0
+}
+.wag .vnf-card>div {
+    background-color: #dadada;
+    box-sizing: border-box;
+    margin-top: .125rem;
+    padding: .75rem 1.5rem 1.5rem;
+    text-align: center;
+    width: 99.8%
+}
+.wag .vnf-card>div .button-action-toggle {
+    font-size: .75rem
+}
+.wag .vnf-card.vlb .bindings {
+    padding: 1.125rem 1.5rem
+}
+.wag .vnf-card.vlb .bindings em {
+    display: block;
+    margin: 1.063rem 0
+}
+.wag .vnf-card.vlb .bindings img {
+    width: .75rem
+}
+.wag .navpanel.top,
+.wag .navpanel.bottom {
+    background-color: #f1f1f1;
+    height: 38px;
+    overflow: hidden;
+    padding: 0;
+    position: relative
+}
+.wag .navpanel.top .tilt,
+.wag .navpanel.bottom .tilt {
+    background-color: #dadada;
+    height: 38px;
+    position: absolute;
+    left: 0;
+    top: -25px;
+    transform: rotate(1.4deg);
+    width: 100%
+}
+.wag .navpanel.top:before,
+.wag .navpanel.bottom:before {
+    border: 0
+}
+.wag .navpanel.top:after {
+    border-right: 48px solid #ccc;
+    border-top: 38px solid #dadada
+}
+.wag .navpanel.bottom {
+    transform: scaleY(-1)
+}
+.wag .navpanel.bottom:after {
+    border-left: 48px solid #dadada;
+    border-top: 38px solid #ccc;
+    transform: scaleY(-1)
+}
+.wag .navpanel.right {
+    background-color: #ccc;
+    width: 48px;
+    align-items: center;
+    display: flex;
+    justify-content: center
+}
+.wag #map {
+    height: 295px
+}
+.wag .wag-marker {
+    width: 20px;
+    height: 20px;
+    border: 1px solid #088;
+    border-radius: 10px;
+    background-color: #0FF;
+    opacity: .5
+}
+.viewport-dash {
+    position: relative
+}
+.viewport-dash .vim-link {
+    display: block;
+    height: 133px;
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    width: 100%
+}
+.viewport-dash .vnf-link {
+    display: block;
+    height: 100%;
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 133px
+}
+.viewport-dash .so-link {
+    display: block;
+    height: 133px;
+    position: absolute;
+    top: 0;
+    right: 0;
+    width: 100%
+}
+.viewport-dash .platform-link {
+    margin-bottom: 20px;
+    flex: 1 100%
+}
+.viewport-dash .platform-link .button-half-border:before,
+.viewport-dash .platform-link .button-half-border:after {
+    background: #f1f1f1;
+    content: '';
+    display: block;
+    height: 10px;
+    position: absolute;
+    top: 0;
+    width: 4px
+}
+.viewport-dash .platform-link a:link {
+    color: #000;
+    text-decoration: none
+}
+.viewport-dash .platform-link a:visited {
+    color: #000;
+    text-decoration: none
+}
+.viewport-dash .platform-link a:hover {
+    color: #000;
+    text-decoration: none
+}
+.viewport-dash .platform-link a:active {
+    color: #000;
+    text-decoration: none
+}
+.viewport-vim {
+    position: relative
+}
+.viewport-vim .dash-link {
+    height: 40px;
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%
+}
+.viewport-vnf {
+    position: relative
+}
+.viewport-vnf .dash-link {
+    height: 100%;
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 40px
+}
+
+.login-cntnr {
+    width: 100%;
+    height: 100%;
+    text-align: center;
+    font-family: roboto-thin, Helvetica, Arial, sans-serif;
+    font-size: 20px
+}
+.login-cntnr .logo {
+    width: 154px;
+    height: 102px;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 150px;
+    margin-bottom: 20px;
+    background-size: 154px 102px;
+    background-image: url(./img/header-logo.png)
+}
+.login-cntnr .riftio {
+    margin-bottom: 40px;
+    font-size: 1.625rem;
+    font-weight: 400;
+}
+.login-cntnr input {
+    width: 525px;
+    padding-left: 25px
+}
+.login-cntnr input,
+.login-cntnr .sign-in {
+    min-width: 0;
+    width: 550px;
+    height: 65px;
+    min-width: auto;
+    margin-bottom: 40px;
+    box-shadow: inset 0 1px 2px rgba(0, 0, 0, .39), 0 -1px 1px #fff, 0 1px 0 #fff;
+    font-size: 20px
+}
+.login-cntnr .sign-in {
+    display: inline-block;
+    // height: 45px;
+    // padding-top: 20px;
+    -webkit-box-shadow: 4px 4px 1px 0 #d9d9d9;
+    -moz-box-shadow: 4px 4px 1px 0 #d9d9d9;
+    box-shadow: 4px 4px 1px 0 #d9d9d9;
+    background-color: #333;
+    color: #fff;
+    text-decoration: none
+}
+.login-cntnr .create-account {
+    font-size: 18px;
+    color: #393939
+}
+.login-cntnr .create-account a {
+    font-weight: 700
+}
+
diff --git a/skyquake/framework/style/fonts/Roboto-Light-webfont.ttf b/skyquake/framework/style/fonts/Roboto-Light-webfont.ttf
new file mode 100755 (executable)
index 0000000..664e1b2
Binary files /dev/null and b/skyquake/framework/style/fonts/Roboto-Light-webfont.ttf differ
diff --git a/skyquake/framework/style/fonts/Roboto-Regular-webfont.eot b/skyquake/framework/style/fonts/Roboto-Regular-webfont.eot
new file mode 100755 (executable)
index 0000000..9b5e8e4
Binary files /dev/null and b/skyquake/framework/style/fonts/Roboto-Regular-webfont.eot differ
diff --git a/skyquake/framework/style/fonts/Roboto-Regular-webfont.svg b/skyquake/framework/style/fonts/Roboto-Regular-webfont.svg
new file mode 100755 (executable)
index 0000000..de7d77f
--- /dev/null
@@ -0,0 +1,621 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="robotoregular" horiz-adv-x="1164" >
+<font-face units-per-em="2048" ascent="1638" descent="-410" />
+<missing-glyph horiz-adv-x="509" />
+<glyph unicode="&#xfb01;" horiz-adv-x="1140" d="M28 936v146h170v117q0 182 106.5 282t295.5 100q67 0 132 -15.5t153 -45.5l-34 -160q-53 21 -113 36t-123 15q-117 0 -168.5 -52t-51.5 -160v-117h215v-146h-215v-936h-197v936h-170zM783 0v1082h198v-1082h-198z" />
+<glyph horiz-adv-x="2048" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="509" />
+<glyph unicode=" "  horiz-adv-x="509" />
+<glyph unicode="&#x09;" horiz-adv-x="509" />
+<glyph unicode="&#xa0;" horiz-adv-x="509" />
+<glyph unicode="!" horiz-adv-x="539" d="M171 0v204h198v-204h-198zM171 478v978h197v-978h-197z" />
+<glyph unicode="&#x22;" horiz-adv-x="668" d="M80 1040l1 240v280h197v-270l-101 -250h-97zM389 1040l1 248v272h197v-270l-101 -250h-97z" />
+<glyph unicode="#" horiz-adv-x="1276" d="M70 410v140h264l68 348h-256v142h284l82 416h151l-82 -416h255l82 416h151l-82 -416h199v-142h-226l-68 -348h219v-140h-247l-80 -410h-152l80 410h-255l-80 -410h-151l80 410h-236zM485 550h255l68 348h-255z" />
+<glyph unicode="$" horiz-adv-x="1153" d="M114 424l2 5h190q0 -154 77.5 -219.5t190.5 -65.5q129 0 201.5 61.5t72.5 170.5q0 89 -64 153t-210 114q-202 61 -305 163t-103 272q0 165 94.5 269t260.5 125v221h158v-222q168 -24 260.5 -143.5t92.5 -320.5h-196q0 136 -63 220t-175 84q-118 0 -176.5 -61.5 t-58.5 -168.5q0 -97 60.5 -157t218.5 -114q205 -66 304 -164.5t99 -267.5q0 -172 -103 -273.5t-283 -120.5v-192h-157v191q-172 18 -282 125.5t-106 315.5z" />
+<glyph unicode="%" horiz-adv-x="1498" d="M104 1099v77q0 127 82 214t219 87t219 -86.5t82 -214.5v-77q0 -127 -81.5 -213t-217.5 -86q-138 0 -220.5 86t-82.5 213zM250 1099q0 -74 40.5 -125.5t116.5 -51.5q73 0 113 51t40 126v77q0 74 -40.5 126.5t-114.5 52.5q-75 0 -115 -52.5t-40 -126.5v-77zM349 177 l711 1138l109 -67l-711 -1138zM809 279v78q0 127 82 213.5t219 86.5q136 0 218.5 -86.5t82.5 -213.5v-78q0 -128 -82 -214t-217 -86q-138 0 -220.5 86t-82.5 214zM955 279q0 -75 40.5 -126.5t116.5 -51.5q73 0 113 51.5t40 126.5v78q0 74 -41 126t-114 52q-74 0 -114.5 -52 t-40.5 -126v-78z" />
+<glyph unicode="&#x26;" horiz-adv-x="1276" d="M64 392q0 122 70.5 213.5t210.5 183.5q-78 99 -116 176.5t-38 159.5q0 169 97.5 260.5t268.5 91.5q158 0 257 -91t99 -219q0 -98 -52.5 -169.5t-155.5 -146.5l-109 -80l340 -409q41 65 64 144t23 167h176q0 -132 -39 -244t-113 -201l185 -223l-2 -5h-229l-85 102 q-80 -60 -177 -91.5t-201 -31.5q-217 0 -345.5 115t-128.5 298zM261 392q0 -113 71 -186t206 -73q72 0 142 24.5t132 70.5l-361 435l-40 -29q-91 -68 -120.5 -130t-29.5 -112zM388 1127q0 -53 27 -110.5t81 -125.5l138 95q57 38 77.5 82.5t20.5 98.5q0 61 -48.5 108 t-126.5 47q-81 0 -125 -56.5t-44 -138.5z" />
+<glyph unicode="'" horiz-adv-x="359" d="M80 1055l1 265v240h197v-223l-101 -282h-97z" />
+<glyph unicode="(" horiz-adv-x="679" d="M132 582v9q0 394 159 673t334 372l6 -1l38 -116q-137 -107 -238.5 -343t-101.5 -583v-13q0 -347 101 -583t239 -352l-38 -108h-6q-175 93 -334 371.5t-159 673.5z" />
+<glyph unicode=")" horiz-adv-x="687" d="M6 -355q135 105 237.5 345.5t102.5 589.5v13q0 342 -105.5 583.5t-234.5 351.5l38 108h6q174 -93 333.5 -372t159.5 -673v-9q0 -395 -159.5 -673.5t-333.5 -371.5h-6z" />
+<glyph unicode="*" horiz-adv-x="884" d="M28 1071l49 154l296 -111l-10 342h161l-10 -348l293 110l48 -156l-302 -89l193 -270l-131 -96l-181 287l-176 -279l-132 93l198 274z" />
+<glyph unicode="+" horiz-adv-x="1162" d="M78 605v178h402v423h197v-423h399v-178h-399v-459h-197v459h-402z" />
+<glyph unicode="," horiz-adv-x="404" d="M48 -258l70 316v163h197v-173l-150 -306h-117z" />
+<glyph unicode="-" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="." horiz-adv-x="548" d="M161 0v202h197v-202h-197z" />
+<glyph unicode="/" horiz-adv-x="850" d="M16 -125l608 1581h167l-607 -1581h-168z" />
+<glyph unicode="0" horiz-adv-x="1154" d="M113 555v345q0 278 124.5 427.5t338.5 149.5q215 0 339.5 -149.5t124.5 -427.5v-345q0 -279 -123.5 -427.5t-338.5 -148.5t-340 149t-125 427zM310 515q0 -189 69 -285.5t199 -96.5t197.5 96t67.5 286v427q0 189 -68.5 284.5t-198.5 95.5t-198 -95.5t-68 -284.5v-427z " />
+<glyph unicode="1" horiz-adv-x="1153" d="M186 1260v142l495 54v-1456h-197v1264z" />
+<glyph unicode="2" horiz-adv-x="1153" d="M97 1033q-5 188 125 316t360 128q196 0 312.5 -114.5t116.5 -291.5q0 -119 -70.5 -238.5t-197.5 -256.5l-383 -417l2 -5h700v-154h-944v135l477 530q128 143 173.5 227t45.5 172q0 109 -63.5 183.5t-168.5 74.5q-151 0 -222.5 -77.5t-71.5 -217.5h-189z" />
+<glyph unicode="3" horiz-adv-x="1153" d="M100 378l3 6h188q0 -115 70.5 -183t193.5 -68q125 0 196 68t71 201q0 135 -63 199t-199 64h-172v154h172q131 0 185.5 65.5t54.5 182.5q0 125 -62 190t-183 65q-115 0 -184.5 -67.5t-69.5 -179.5h-189l-2 6q-5 165 119.5 280.5t325.5 115.5q202 0 322 -107.5t120 -306.5 q0 -90 -54.5 -179.5t-163.5 -136.5q131 -43 185.5 -135t54.5 -206q0 -199 -130.5 -313t-333.5 -114q-199 0 -329.5 107.5t-125.5 291.5z" />
+<glyph unicode="4" horiz-adv-x="1153" d="M55 336v111l642 1009h208v-966h201v-154h-201v-336h-196v336h-654zM265 490h444v683l-6 1l-19 -50z" />
+<glyph unicode="5" horiz-adv-x="1153" d="M157 377l2 6h178q0 -119 68.5 -184.5t177.5 -65.5q125 0 194 88t69 241q0 140 -70 230t-193 90q-116 0 -168 -35t-76 -107l-164 17l84 799h729v-175h-562l-48 -409q46 34 102.5 56.5t130.5 24.5q201 2 316.5 -131t115.5 -358q0 -219 -117.5 -352t-342.5 -133 q-185 0 -308 101t-118 297z" />
+<glyph unicode="6" horiz-adv-x="1153" d="M132 571v278q0 280 156 454t387 174q75 0 148.5 -17t121.5 -43l-42 -151q-49 25 -102.5 40.5t-125.5 15.5q-156 0 -251.5 -125t-95.5 -326v-23q64 56 146.5 87.5t177.5 31.5q195 0 311 -135t116 -342q0 -226 -123.5 -368.5t-329.5 -142.5q-214 0 -354 155t-140 437z M328 552q0 -201 85 -310t213 -109q121 0 188.5 102.5t67.5 254.5q0 144 -72.5 237t-201.5 93q-101 0 -172 -41t-108 -109v-118z" />
+<glyph unicode="7" horiz-adv-x="1153" d="M77 1301v155h985v-155q-264 -314 -356.5 -556.5t-133.5 -587.5l-16 -157h-197l16 157q42 344 163 615t331 529h-792z" />
+<glyph unicode="8" horiz-adv-x="1153" d="M102 394q0 123 74 217t200 138q-109 42 -171 127.5t-62 199.5q0 192 118.5 296.5t313.5 104.5q192 0 313.5 -104.5t121.5 -296.5q0 -114 -64 -199.5t-173 -127.5q126 -44 201.5 -138t75.5 -217q0 -202 -131.5 -308.5t-341.5 -106.5q-214 0 -344.5 106.5t-130.5 308.5z M299 398q0 -124 76 -194.5t202 -70.5q123 0 200 71t77 194q0 120 -79 197t-200 77q-123 0 -199.5 -77t-76.5 -197zM340 1072q0 -111 65.5 -178t171.5 -67q104 0 170 67t66 178q0 108 -67.5 179t-170.5 71q-105 0 -170 -68.5t-65 -181.5z" />
+<glyph unicode="9" horiz-adv-x="1153" d="M83 978q0 219 131.5 359t319.5 140q228 0 359.5 -142.5t131.5 -419.5v-347q0 -285 -142.5 -437t-371.5 -152q-77 0 -156.5 14.5t-142.5 44.5l30 151q59 -31 122.5 -43.5t146.5 -12.5q144 0 230.5 109t86.5 324v66q-49 -71 -122.5 -107.5t-163.5 -36.5q-211 0 -335 130.5 t-124 359.5zM280 978q0 -150 70.5 -243t191.5 -93q109 0 181.5 47t104.5 120v126q0 191 -73.5 289t-214.5 98q-108 0 -184 -96.5t-76 -247.5z" />
+<glyph unicode=":" horiz-adv-x="517" d="M161 0v202h197v-202h-197zM161 876v202h197v-202h-197z" />
+<glyph unicode=";" horiz-adv-x="525" d="M99 -258l70 316v163h197v-173l-150 -306h-117zM162 876v202h197v-202h-197z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1040" d="M71 466v149l816 378v-201l-559 -233l-85 -18v-6l85 -19l559 -228v-201z" />
+<glyph unicode="=" horiz-adv-x="1153" d="M152 407v164h834v-164h-834zM152 823v164h834v-164h-834z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1072" d="M136 87v196l598 238l85 17v6l-85 20l-598 234v195l856 -378v-149z" />
+<glyph unicode="?" horiz-adv-x="974" d="M61 1122q-3 161 113.5 258t296.5 97q197 0 306 -100.5t109 -280.5q0 -129 -70.5 -236t-186.5 -219q-54 -54 -65.5 -97t-11.5 -134h-197q1 145 25 201t126 148q99 117 141 180t42 152q0 106 -56.5 163t-161.5 57q-91 0 -155 -49.5t-64 -145.5h-188zM353 0v208h206v-208 h-206z" />
+<glyph unicode="@" horiz-adv-x="1833" d="M114 478q19 423 249 688t602 265q379 0 581.5 -250t185.5 -679q-9 -214 -120 -368.5t-332 -154.5q-73 0 -126 41.5t-76 117.5q-50 -80 -122 -119.5t-168 -39.5q-125 0 -194 120.5t-51 316.5q23 259 137.5 415.5t279.5 156.5q105 0 169 -26t139 -80l-4 -4h6l-51 -585 q-9 -110 21.5 -151.5t81.5 -41.5q123 0 197 113.5t82 288.5q16 382 -144 595.5t-496 213.5q-308 0 -495.5 -231t-202.5 -602q-18 -376 150 -594.5t482 -218.5q88 0 178.5 21.5t152.5 56.5l38 -107q-67 -42 -170.5 -65.5t-202.5 -23.5q-380 0 -587.5 249.5t-189.5 681.5z M720 416q-11 -142 21.5 -216t106.5 -74q64 0 117 24.5t97 87.5q-1 12 -0.5 25.5t2.5 29.5l47 538q-26 12 -54.5 19t-59.5 7q-125 0 -191 -109.5t-86 -331.5z" />
+<glyph unicode="A" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6z" />
+<glyph unicode="B" horiz-adv-x="1309" d="M180 0v1456h475q228 0 357 -98.5t129 -295.5q0 -97 -62 -173.5t-163 -113.5q132 -28 207.5 -129t75.5 -235q0 -200 -129.5 -305.5t-351.5 -105.5h-538zM377 154h341q134 0 209 66.5t75 188.5q0 128 -62.5 201t-192.5 73h-370v-529zM377 837h319q110 0 179 60.5t69 168.5 q0 118 -74.5 176.5t-214.5 58.5h-278v-464z" />
+<glyph unicode="C" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5q247 1 393 -131q142 -128 142 -337v-12l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6v-11q0 -198 -144 -332q-148 -138 -391 -138 q-247 0 -402.5 175t-155.5 444z" />
+<glyph unicode="D" horiz-adv-x="1349" d="M180 0v1456h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447zM377 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-1147z" />
+<glyph unicode="E" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966z" />
+<glyph unicode="F" horiz-adv-x="1193" d="M180 0v1456h963v-155h-766v-502h664v-155h-664v-644h-197z" />
+<glyph unicode="G" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432z" />
+<glyph unicode="H" horiz-adv-x="1461" d="M180 0v1456h197v-658h707v658h197v-1456h-197v643h-707v-643h-197z" />
+<glyph unicode="I" horiz-adv-x="579" d="M190 0v1456h198v-1456h-198z" />
+<glyph unicode="J" horiz-adv-x="1130" d="M66 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 107q-119 102 -119 293v16z" />
+<glyph unicode="K" horiz-adv-x="1317" d="M180 0v1456h197v-644h152l521 644h218l3 -5l-565 -699l606 -747l-3 -5h-235l-527 657h-170v-657h-197z" />
+<glyph unicode="L" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886z" />
+<glyph unicode="M" horiz-adv-x="1799" d="M180 0v1456h252l464 -1183h6l464 1183h252v-1456h-197v576l20 592l-5 1l-472 -1169h-131l-470 1166l-5 -1l19 -589v-576h-197z" />
+<glyph unicode="N" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197z" />
+<glyph unicode="O" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261z" />
+<glyph unicode="P" horiz-adv-x="1312" d="M180 0v1456h557q233 0 362 -120t129 -316q0 -199 -129 -317.5t-362 -118.5h-360v-584h-197zM377 738h360q148 0 221 79.5t73 200.5t-73.5 202t-220.5 81h-360v-563z" />
+<glyph unicode="Q" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -142 -50 -263t-140 -205l247 -233l-135 -129l-276 257q-56 -23 -116.5 -34.5t-124.5 -11.5q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5 t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128t-102.5 -328v-261z" />
+<glyph unicode="R" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515z" />
+<glyph unicode="S" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 381 -131q137 -127 136 -292v-12l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -386 118q-163 115 -162 305v11z" />
+<glyph unicode="T" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467z" />
+<glyph unicode="U" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5z" />
+<glyph unicode="V" horiz-adv-x="1295" d="M22 1456h214l376 -1094l33 -115h6l33 115l376 1094h213l-541 -1456h-169z" />
+<glyph unicode="W" horiz-adv-x="1809" d="M54 1456h196l222 -952l27 -182l6 -1l39 183l267 952h174l269 -952l40 -187h6l29 187l217 952h197l-351 -1456h-176l-287 1010l-26 131h-6l-25 -131l-292 -1010h-176z" />
+<glyph unicode="X" horiz-adv-x="1295" d="M66 0l472 734l-462 722h236l338 -568l340 568h238l-462 -722l472 -734h-235l-349 578l-350 -578h-238z" />
+<glyph unicode="Y" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525z" />
+<glyph unicode="Z" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036z" />
+<glyph unicode="[" horiz-adv-x="552" d="M143 -312v1976h385v-155h-188v-1666h188v-155h-385z" />
+<glyph unicode="\" horiz-adv-x="846" d="M39 1456h186l608 -1581h-186z" />
+<glyph unicode="]" horiz-adv-x="552" d="M11 -157h189v1666h-189v155h386v-1976h-386v155z" />
+<glyph unicode="^" horiz-adv-x="856" d="M61 729l299 727h134l298 -727h-181l-166 419l-16 70h-6l-16 -70l-163 -419h-183z" />
+<glyph unicode="_" horiz-adv-x="931" d="M4 0h923v-154h-923v154z" />
+<glyph unicode="`" horiz-adv-x="641" d="M82 1471l3 6h230l175 -266h-158z" />
+<glyph unicode="a" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6v11q0 111 112 205q118 98 303 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="b" d="M143 0v1560h197v-606q51 72 126.5 110t176.5 38q200 0 312 -160t112 -421v-21q0 -234 -112.5 -377.5t-309.5 -143.5q-107 0 -186 41.5t-131 122.5l-24 -143h-161zM340 309q38 -80 99.5 -125t155.5 -45q139 0 207 99t68 262v21q0 186 -68.5 303.5t-208.5 117.5 q-91 0 -153.5 -44.5t-99.5 -119.5v-469z" />
+<glyph unicode="c" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q191 0 311 -112q117 -108 116 -265v-10l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6v-10q-1 -134 -125 -238 q-130 -108 -301 -109q-236 0 -361 154t-125 387z" />
+<glyph unicode="d" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v595h197v-1560h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505q-38 67 -98.5 106.5t-145.5 39.5 q-142 0 -209.5 -117t-67.5 -304v-21z" />
+<glyph unicode="e" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="f" horiz-adv-x="707" d="M56 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169z" />
+<glyph unicode="g" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="h" d="M143 0v1560h197v-623q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197z" />
+<glyph unicode="i" horiz-adv-x="516" d="M159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197z" />
+<glyph unicode="j" horiz-adv-x="530" d="M-66 -419l14 155q14 -5 40 -8.5t43 -3.5q65 0 103.5 44t38.5 143v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM167 1363v197h197v-197h-197z" />
+<glyph unicode="k" horiz-adv-x="1050" d="M144 0v1560h197v-904h126l296 426h236l-370 -492l423 -590h-232l-351 499h-128v-499h-197z" />
+<glyph unicode="l" horiz-adv-x="516" d="M159 0v1560h197v-1560h-197z" />
+<glyph unicode="m" horiz-adv-x="1790" d="M143 0v1082h176l14 -142q53 77 134.5 119.5t189.5 42.5t185.5 -50t116.5 -150q51 92 135 146t196 54q165 0 261 -113.5t96 -341.5v-647h-197v649q0 160 -55 226.5t-164 66.5q-101 0 -163.5 -70t-73.5 -177v-8v-687h-198v649q0 152 -56.5 222.5t-162.5 70.5 q-90 0 -148 -37t-89 -104v-801h-197z" />
+<glyph unicode="n" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197z" />
+<glyph unicode="o" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="p" d="M143 -416v1498h151l31 -140q53 78 132 119t184 41q201 0 312.5 -159.5t111.5 -421.5v-21q0 -234 -112 -377.5t-309 -143.5q-100 0 -175.5 33.5t-128.5 100.5v-529h-197zM340 275q37 -67 97 -104.5t147 -37.5q140 0 212 102.5t72 264.5v21q0 184 -72.5 302.5t-213.5 118.5 q-85 0 -145 -38.5t-97 -105.5v-523z" />
+<glyph unicode="q" d="M98 500v21q0 261 111.5 421t312.5 160q99 0 174 -37.5t127 -109.5l29 127h150v-1498h-197v518q-52 -61 -123 -92t-162 -31q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67.5 -265.5t207.5 -101.5q81 0 138.5 36t96.5 101v546q-39 61 -96.5 96t-136.5 35 q-141 0 -209 -119.5t-68 -306.5v-21z" />
+<glyph unicode="r" horiz-adv-x="702" d="M143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="s" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 301 -97q107 -93 106 -224v-12l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105q-113 100 -113 232v13z" />
+<glyph unicode="t" horiz-adv-x="708" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172z" />
+<glyph unicode="u" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352z" />
+<glyph unicode="v" horiz-adv-x="1030" d="M46 1082h202l256 -763l17 -76h6l19 76l249 763h201l-398 -1082h-149z" />
+<glyph unicode="w" horiz-adv-x="1550" d="M45 1082h196l179 -688l23 -131h6l28 131l216 688h158l217 -688l31 -146h6l29 146l170 688h196l-314 -1082h-159l-209 659l-45 184l-6 -1l-43 -183l-206 -659h-159z" />
+<glyph unicode="x" horiz-adv-x="1030" d="M46 0l361 547l-351 535h227l227 -399l230 399h230l-351 -535l361 -547h-226l-240 409l-240 -409h-228z" />
+<glyph unicode="y" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113z" />
+<glyph unicode="z" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860z" />
+<glyph unicode="{" horiz-adv-x="696" d="M63 543v147q106 0 157.5 61.5t51.5 174.5v206q0 171 82 290.5t277 174.5l40 -117q-110 -35 -156 -125.5t-46 -222.5v-206q0 -105 -42.5 -185t-127.5 -125q85 -46 127.5 -126.5t42.5 -183.5v-205q0 -132 46 -221.5t156 -125.5l-40 -118q-195 55 -277 175t-82 290v205 q0 112 -51.5 174.5t-157.5 62.5z" />
+<glyph unicode="|" horiz-adv-x="507" d="M175 -270v1726h158v-1726h-158z" />
+<glyph unicode="}" horiz-adv-x="696" d="M21 -246q109 36 156 125.5t47 221.5v205q0 107 45 187t139 123q-94 41 -139 121t-45 189v206q0 132 -47 222.5t-156 125.5l41 117q194 -55 276.5 -174.5t82.5 -290.5v-206q0 -113 50.5 -174.5t158.5 -61.5v-147q-108 0 -158.5 -62.5t-50.5 -174.5v-205q0 -170 -82.5 -290 t-276.5 -175z" />
+<glyph unicode="~" horiz-adv-x="1391" d="M128 474q0 136 85.5 232.5t217.5 96.5q88 0 163 -34.5t160 -104.5q58 -51 106 -74t100 -23q66 0 114.5 57t48.5 134l141 -18q0 -137 -87 -238t-217 -101q-90 0 -163.5 33t-158.5 107q-59 48 -108 72t-99 24q-67 0 -114.5 -53t-47.5 -128z" />
+<glyph unicode="&#xa1;" horiz-adv-x="507" d="M144 -374v978h197v-978h-197zM144 876v206h197v-206h-197z" />
+<glyph unicode="&#xa2;" horiz-adv-x="1122" d="M107 520v42q0 199 95 344.5t276 183.5v228h198v-223q157 -24 252.5 -130.5t92.5 -250.5l-2 -5h-179q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h178l3 -6q3 -122 -98 -223t-247 -126v-232 h-198v236q-182 36 -276.5 182t-94.5 347z" />
+<glyph unicode="&#xa3;" horiz-adv-x="1194" d="M70 615v155h158l-10 270q0 204 112 320.5t300 116.5q200 0 310 -104.5t106 -276.5l-2 -6h-190q0 118 -63 175t-161 57q-99 0 -157 -74.5t-58 -207.5l10 -270h418v-155h-413l6 -149q0 -90 -15.5 -171.5t-44.5 -140.5h735l-1 -154h-976v154h10q48 13 72 111t24 201l-6 149 h-164z" />
+<glyph unicode="&#xa4;" horiz-adv-x="1456" d="M104 112l138 140q-50 76 -76.5 166.5t-26.5 189.5q0 102 28.5 196t82.5 172l-146 149l139 139l143 -146q74 55 163 85.5t185 30.5q97 0 186 -31t164 -87l146 149l140 -140l-150 -153q52 -78 80.5 -170.5t28.5 -193.5q0 -98 -26.5 -187.5t-74.5 -165.5l142 -143l-140 -139 l-133 135q-77 -62 -169.5 -95t-193.5 -33t-193.5 32.5t-167.5 93.5l-130 -132zM321 608q0 -188 120.5 -320.5t292.5 -132.5q170 0 290.5 132.5t120.5 320.5q0 186 -120.5 318t-290.5 132q-172 0 -292.5 -132t-120.5 -318z" />
+<glyph unicode="&#xa5;" horiz-adv-x="1243" d="M30 1456h226l359 -663l360 663h224l-418 -718h312v-155h-383v-135h383v-155h-383v-293h-197v293h-375v155h375v135h-375v155h311z" />
+<glyph unicode="&#xa6;" horiz-adv-x="499" d="M145 -270v792h197v-792h-197zM145 698v758h197v-758h-197z" />
+<glyph unicode="&#xa7;" horiz-adv-x="1259" d="M94 551q0 91 47 161.5t134 111.5q-68 50 -102 119.5t-34 166.5q0 166 134 266.5t358 100.5q233 0 363 -111.5t126 -313.5l-3 -6h-188q0 118 -79 197t-219 79q-145 0 -220 -59.5t-75 -150.5q0 -99 67 -148.5t278 -107.5q244 -69 355.5 -159.5t111.5 -265.5q0 -94 -48 -164 t-135 -110q69 -51 104 -119t35 -166q0 -172 -133 -269.5t-358 -97.5q-221 0 -372 102.5t-146 322.5l2 6l188 2q0 -143 96.5 -210.5t231.5 -67.5q137 0 215.5 59.5t78.5 150.5t-72 141.5t-276 113.5q-239 63 -352 156t-113 270zM291 553q0 -100 68 -151.5t278 -110.5 q56 -17 93 -28t70 -23q72 20 112 69.5t40 118.5q0 91 -73.5 144.5t-275.5 116.5q-47 12 -88.5 24.5t-77.5 27.5q-73 -19 -109.5 -69t-36.5 -119z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1021" d="M170 1256v200h219v-200h-219zM640 1256v200h219v-200h-219z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1604" d="M88 729q0 315 207 531t503 216q295 0 502 -216t207 -531q0 -316 -207.5 -533t-501.5 -217q-296 0 -503 217t-207 533zM209 729q0 -265 171.5 -447t417.5 -182q245 0 417 182t172 447q0 263 -172 444t-417 181q-246 0 -417.5 -181t-171.5 -444zM436 669v119q0 173 94 280 t254 107q157 0 245.5 -79t84.5 -228l-2 -6h-146q0 95 -45.5 138.5t-136.5 43.5q-94 0 -145 -70.5t-51 -184.5v-120q0 -117 51 -187t145 -70q91 0 136 43t45 141h146l2 -6q4 -151 -84 -229.5t-245 -78.5q-160 0 -254 106.5t-94 280.5z" />
+<glyph unicode="&#xaa;" horiz-adv-x="917" d="M120 920q0 110 84.5 170t245.5 60h139v52q0 63 -30 97t-88 34q-67 0 -103.5 -27t-36.5 -76l-162 13l-1 6q-6 98 78.5 163t224.5 65q134 0 212 -71t78 -205v-314q0 -50 6 -94t20 -87h-174q-8 21 -13 45t-8 50q-33 -47 -89.5 -78t-133.5 -31q-119 0 -184 61t-65 167z M293 924q0 -45 29 -69t89 -24q51 0 105.5 30t72.5 65v110h-138q-75 0 -116.5 -33t-41.5 -79z" />
+<glyph unicode="&#xab;" horiz-adv-x="966" d="M98 507v19l295 389h148l-255 -399l255 -398h-148zM432 507v19l295 389h148l-255 -399l255 -398h-148z" />
+<glyph unicode="&#xac;" horiz-adv-x="1137" d="M127 637v165h835v-427h-198v262h-637z" />
+<glyph unicode="&#xad;" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="&#xae;" horiz-adv-x="1604" d="M88 729q0 315 207 531t503 216q295 0 502 -216t207 -531q0 -316 -207.5 -533t-501.5 -217q-296 0 -503 217t-207 533zM209 729q0 -266 171.5 -447.5t417.5 -181.5q244 0 416 182t172 447q0 264 -171.5 444.5t-416.5 180.5q-246 0 -417.5 -180.5t-171.5 -444.5zM504 316 v850h280q152 0 238.5 -65.5t86.5 -191.5q0 -62 -33 -109t-96 -78q66 -26 95.5 -79t29.5 -128v-56q0 -41 3.5 -73.5t13.5 -53.5v-16h-153q-9 21 -11 61.5t-2 82.5v54q0 72 -33.5 106t-110.5 34h-159v-338h-149zM653 784h152q65 1 110.5 32.5t45.5 87.5q0 73 -39.5 102.5 t-137.5 29.5h-131v-252z" />
+<glyph unicode="&#xaf;" horiz-adv-x="950" d="M123 1310v146h721v-146h-721z" />
+<glyph unicode="&#xb0;" horiz-adv-x="763" d="M128 1216q0 106 76 183.5t181 77.5q103 0 177.5 -77.5t74.5 -183.5q0 -108 -74 -182.5t-178 -74.5q-106 0 -181.5 74.5t-75.5 182.5zM259 1216q0 -55 36.5 -91t89.5 -36q52 0 87.5 36t35.5 91t-36 92.5t-87 37.5q-53 0 -89.5 -37.5t-36.5 -92.5z" />
+<glyph unicode="&#xb1;" horiz-adv-x="1097" d="M99 702v154h381v411h177v-411h358v-154h-358v-413h-177v413h-381zM136 4v155h835v-155h-835z" />
+<glyph unicode="&#xb2;" horiz-adv-x="868" d="M119 1240q-6 99 78 169t225 70q135 0 211 -64t76 -180q0 -80 -44.5 -136t-160.5 -161l-153 -135l2 -6h361v-130h-592v130l302 262q69 60 91 97.5t22 79.5q0 50 -28.5 81t-86.5 31q-67 0 -103.5 -32t-36.5 -82h-161z" />
+<glyph unicode="&#xb3;" horiz-adv-x="876" d="M112 882l1 6h163q0 -46 37.5 -74.5t100.5 -28.5q72 0 114 29.5t42 77.5q0 62 -36.5 90.5t-109.5 28.5h-132v126h132q67 0 99.5 28.5t32.5 80.5q0 43 -36.5 72t-105.5 29q-56 0 -90.5 -24t-34.5 -64h-162l-2 6q-6 94 78.5 153.5t210.5 59.5q145 0 229 -59.5t84 -169.5 q0 -55 -35.5 -100.5t-97.5 -71.5q70 -23 108 -71t38 -116q0 -111 -90 -173t-236 -62q-127 0 -217.5 58t-84.5 169z" />
+<glyph unicode="&#xb4;" horiz-adv-x="654" d="M131 1211l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xb5;" d="M153 -416v1498h196v-642q2 -178 57.5 -242.5t155.5 -64.5q98 0 158.5 36t92.5 106v807h197v-1082h-177l-9 108q-44 -63 -107.5 -96t-146.5 -33q-72 0 -126.5 16.5t-94.5 51.5v-463h-196z" />
+<glyph unicode="&#xb6;" horiz-adv-x="1006" d="M63 988q0 207 129.5 337.5t362.5 130.5h281v-1456h-197v520h-84q-233 0 -362.5 129.5t-129.5 338.5z" />
+<glyph unicode="&#xb7;" horiz-adv-x="540" d="M161 624v212h198v-212h-198z" />
+<glyph unicode="&#xb8;" horiz-adv-x="509" d="M119 -326q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#xb9;" horiz-adv-x="557" d="M95 1320v134l301 23v-812h-174v655h-127z" />
+<glyph unicode="&#xba;" horiz-adv-x="933" d="M120 1025v117q0 148 94 241.5t251 93.5q158 0 252 -93.5t94 -241.5v-117q0 -149 -93.5 -241.5t-250.5 -92.5q-158 0 -252.5 92.5t-94.5 241.5zM293 1025q0 -88 44 -140.5t130 -52.5q83 0 127.5 53t44.5 140v117q0 84 -45 137.5t-129 53.5t-128 -53.5t-44 -137.5v-117z " />
+<glyph unicode="&#xbb;" horiz-adv-x="966" d="M110 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148zM456 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148z" />
+<glyph unicode="&#xbc;" horiz-adv-x="1595" d="M184 1319v134l301 23v-812h-174v655h-127zM339 185l711 1138l109 -67l-711 -1138zM785 254l422 547h173v-519h126v-130h-126v-152h-170v152h-417zM967 282h243v310l-6 1l-13 -22z" />
+<glyph unicode="&#xbd;" horiz-adv-x="1708" d="M184 1319v134l301 23v-812h-174v655h-127zM352 185l711 1138l109 -67l-711 -1138zM930 573q-6 99 78 169t225 70q135 0 211 -64t76 -180q0 -80 -44.5 -136t-160.5 -161l-153 -135l2 -6h361v-130h-592v130l302 262q69 60 91 97.5t22 79.5q0 50 -28.5 81t-86.5 31 q-67 0 -103.5 -32t-36.5 -82h-161z" />
+<glyph unicode="&#xbe;" horiz-adv-x="1781" d="M128 883l1 6h163q0 -46 37.5 -74.5t100.5 -28.5q72 0 114 29.5t42 77.5q0 62 -36.5 90.5t-109.5 28.5h-132v126h132q67 0 99.5 28.5t32.5 80.5q0 43 -36.5 72t-105.5 29q-56 0 -90.5 -24t-34.5 -64h-162l-2 6q-6 94 78.5 153.5t210.5 59.5q145 0 229 -59.5t84 -169.5 q0 -55 -35.5 -100.5t-97.5 -71.5q70 -23 108 -71t38 -116q0 -111 -90 -173t-236 -62q-127 0 -217.5 58t-84.5 169zM522 185l711 1138l109 -67l-711 -1138zM974 254l422 547h173v-519h126v-130h-126v-152h-170v152h-417zM1156 282h243v310l-6 1l-13 -22z" />
+<glyph unicode="&#xbf;" horiz-adv-x="1013" d="M114 -13q0 127 70 233.5t187 220.5q53 53 65 96t12 135h197q-2 -146 -26 -202t-125 -147q-100 -118 -141.5 -181t-41.5 -150q0 -106 56 -163t162 -57q90 0 154.5 49.5t64.5 145.5h188l3 -6q2 -161 -114.5 -258t-295.5 -97q-198 0 -306.5 100.5t-108.5 280.5zM441 874v209 h206v-209h-206z" />
+<glyph unicode="&#xc0;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM378 1820l3 6h230l175 -266h-158zM420 540h490l-240 663h-6z" />
+<glyph unicode="&#xc1;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM613 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xc2;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM356 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM420 540h490l-240 663h-6z" />
+<glyph unicode="&#xc3;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM316 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM420 540h490l-240 663h-6z " />
+<glyph unicode="&#xc4;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM319 1605v200h219v-200h-219zM420 540h490l-240 663h-6zM789 1605v200h219v-200h-219z" />
+<glyph unicode="&#xc5;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM457 1734q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54q-87 0 -147.5 54t-60.5 140zM560 1734q0 -43 31 -73.5t74 -30.5q42 0 72 29.5 t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1922" d="M-20 0l880 1456h967v-155h-691l20 -466h590v-155h-584l22 -526h705v-154h-895l-15 350h-557l-202 -350h-240zM525 529h447l-31 710l-5 2z" />
+<glyph unicode="&#xc7;" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM581 -334 q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#xc8;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM303 1820l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xc9;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM538 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xca;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM322 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xcb;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM284 1605v200h219v-200h-219zM754 1605v200h219v-200h-219z" />
+<glyph unicode="&#xcc;" horiz-adv-x="579" d="M-34 1820l3 6h230l175 -266h-158zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#xcd;" horiz-adv-x="579" d="M190 0v1456h198v-1456h-198zM199 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xce;" horiz-adv-x="579" d="M-15 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#xcf;" horiz-adv-x="579" d="M-53 1605v200h219v-200h-219zM190 0v1456h198v-1456h-198zM417 1605v200h219v-200h-219z" />
+<glyph unicode="&#xd0;" horiz-adv-x="1379" d="M42 663v155h168v638h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447v663h-168zM407 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-483h276v-155h-276v-509z" />
+<glyph unicode="&#xd1;" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM381 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#xd2;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM373 1841l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xd3;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM608 1577l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xd4;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM392 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xd5;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM351 1649q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#xd6;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM354 1626v200h219v-200h-219zM824 1626v200h219v-200h-219z" />
+<glyph unicode="&#xd7;" horiz-adv-x="1096" d="M88 351l327 334l-327 334l126 126l326 -333l327 333l126 -126l-328 -334l328 -334l-126 -126l-327 332l-326 -332z" />
+<glyph unicode="&#xd8;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q94 0 178.5 -25.5t156.5 -71.5l81 137h149l-132 -221q77 -84 119.5 -197t42.5 -242v-259q0 -267 -165.5 -443t-429.5 -176q-85 0 -160.5 20.5t-139.5 60.5l-91 -154h-149l139 234q-84 84 -128.5 202t-44.5 256zM310 598 q0 -85 19 -158t54 -125l6 -1l544 916q-50 41 -112 63t-134 22q-172 0 -274.5 -128t-102.5 -328v-261zM475 208q44 -34 97 -51t115 -17q183 0 290.5 127.5t107.5 330.5v261q0 75 -16.5 142t-46.5 117l-6 1z" />
+<glyph unicode="&#xd9;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM372 1820l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xda;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM607 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xdb;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM391 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xdc;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM353 1605v200h219v-200h-219zM823 1605v200h219v-200h-219z" />
+<glyph unicode="&#xdd;" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM535 1555l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xde;" horiz-adv-x="1209" d="M163 0v1456h197v-293h269q232 0 362 -118t130 -307q0 -190 -130 -307.5t-362 -117.5h-269v-313h-197zM360 467h269q147 0 220.5 78t73.5 191q0 114 -73.5 193.5t-220.5 79.5h-269v-542z" />
+<glyph unicode="&#xdf;" horiz-adv-x="1221" d="M137 0v1082q0 223 117.5 348t300.5 125q161 0 262 -86t101 -253q0 -118 -64.5 -228t-64.5 -167q0 -82 173.5 -224t173.5 -281q0 -167 -104.5 -252t-282.5 -85q-84 0 -172.5 20.5t-125.5 50.5l44 159q43 -28 108 -52t126 -24q108 0 159 47.5t51 125.5q0 84 -173.5 227.5 t-173.5 289.5q0 80 70.5 190.5t70.5 186.5q0 93 -51 147t-117 54q-104 0 -168 -83.5t-64 -235.5v-1082h-196z" />
+<glyph unicode="&#xe0;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM230 1498l3 6h230l175 -266h-158zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#xe1;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM465 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xe2;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM249 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#xe3;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM208 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55 t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#xe4;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM211 1283v200h219v-200h-219zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM681 1283v200h219v-200h-219z" />
+<glyph unicode="&#xe5;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM346 1412q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54q-87 0 -147.5 54t-60.5 140z M449 1412q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="&#xe6;" horiz-adv-x="1729" d="M58 304q0 158 115 244.5t335 86.5h229v85q0 106 -51.5 166.5t-149.5 60.5q-103 0 -164 -55t-61 -133l-188 18l-2 6q-5 138 109.5 228.5t305.5 90.5q114 0 201.5 -40.5t137.5 -117.5q64 75 151.5 116.5t188.5 41.5q214 0 329.5 -130t115.5 -358v-119h-709l-2 -5 q1 -159 79.5 -258t233.5 -99q103 0 169.5 27.5t144.5 78.5l67 -138q-53 -44 -147 -83t-234 -39q-136 0 -240 48.5t-170 138.5q-56 -79 -167.5 -133t-271.5 -54q-170 0 -262.5 87t-92.5 238zM255 300q0 -74 50 -120.5t147 -46.5q76 0 159 43.5t126 100.5v216h-227 q-120 0 -187.5 -56t-67.5 -137zM953 645l2 -5h508v31q0 122 -60 199t-188 77q-113 0 -182 -84.5t-80 -217.5z" />
+<glyph unicode="&#xe7;" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM440 -334q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#xe8;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM233 1499l3 6h230l175 -266h-158zM307 654l2 -5 h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#xe9;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM468 1235l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xea;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM252 1280v26l246 237h120l248 -238v-25h-161 l-147 148l-146 -148h-160zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#xeb;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM214 1284v200h219v-200h-219zM307 654l2 -5h499 v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5zM684 1284v200h219v-200h-219z" />
+<glyph unicode="&#xec;" horiz-adv-x="515" d="M-71 1477l3 6h230l175 -266h-158zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#xed;" horiz-adv-x="515" d="M153 0v1082h197v-1082h-197zM162 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xee;" horiz-adv-x="515" d="M-52 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#xef;" horiz-adv-x="515" d="M-90 1262v200h219v-200h-219zM153 0v1082h197v-1082h-197zM380 1262v200h219v-200h-219z" />
+<glyph unicode="&#xf0;" horiz-adv-x="1202" d="M72 466q0 228 138 370t351 142q90 0 169.5 -37t131.5 -97l4 5q-9 109 -51.5 197t-110.5 154l-290 -165l-77 102l256 146q-39 22 -80.5 39t-85.5 31l60 164q79 -19 151 -52t135 -79l218 125l77 -102l-195 -112q95 -104 147 -241.5t52 -300.5v-220q0 -245 -144 -400.5 t-359 -155.5q-218 0 -357.5 140t-139.5 347zM269 466q0 -132 82 -232.5t222 -100.5q133 0 217.5 114t84.5 288v148q-35 59 -115.5 99.5t-198.5 40.5q-131 0 -211.5 -104t-80.5 -253z" />
+<glyph unicode="&#xf1;" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM231 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32 q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#xf2;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM257 1498l3 6h230l175 -266h-158zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#xf3;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z M492 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xf4;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM276 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22 q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#xf5;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM235 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5 t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#xf6;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM238 1283v200h219v-200h-219zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22zM708 1283v200h219v-200h-219z" />
+<glyph unicode="&#xf7;" horiz-adv-x="1170" d="M71 597v188h998v-188h-998zM472 180v203h198v-203h-198zM472 999v203h198v-203h-198z" />
+<glyph unicode="&#xf8;" d="M97 529v22q0 240 130 395.5t353 155.5q56 0 107.5 -11t97.5 -31l74 149h129l-104 -211q88 -74 135 -190t47 -257v-22q0 -242 -130 -396t-354 -154q-51 0 -97 8.5t-88 24.5l-72 -147h-129l100 204q-96 71 -147.5 191t-51.5 269zM294 529q0 -91 20 -166.5t61 -123.5h6 l332 674q-29 16 -62.5 25t-70.5 9q-141 0 -213.5 -113t-72.5 -283v-22zM469 156q24 -12 52 -17.5t61 -5.5q141 0 214 112t73 284v22q0 80 -17.5 150.5t-49.5 117.5h-6z" />
+<glyph unicode="&#xf9;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM255 1477l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xfa;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM490 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xfb;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM274 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xfc;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM236 1262v200h219v-200h-219zM706 1262v200h219v-200h-219z" />
+<glyph unicode="&#xfd;" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM424 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xfe;" horiz-adv-x="1186" d="M153 -416v1976h197v-598q53 68 128 104t173 36q201 0 312.5 -159.5t111.5 -421.5v-21q0 -234 -112 -377.5t-309 -143.5q-100 0 -175.5 33.5t-128.5 100.5v-529h-197zM350 275q37 -67 97 -104.5t147 -37.5q140 0 212 102.5t72 264.5v21q0 184 -72.5 302.5t-213.5 118.5 q-85 0 -145 -38.5t-97 -105.5v-523z" />
+<glyph unicode="&#xff;" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM170 1262v200h219v-200h-219zM640 1262v200h219v-200h-219z" />
+<glyph unicode="&#x152;" horiz-adv-x="1960" d="M104 576v304q0 265 154.5 431t403.5 166q69 0 140.5 -6t150.5 -15h907v-155h-758v-471h667v-155h-667v-521h769v-154h-918q-92 -10 -157 -15.5t-132 -5.5q-249 0 -404.5 166t-155.5 431zM301 576q0 -214 97 -328t266 -114q61 0 122 4.5t119 13.5v1151q-61 8 -122 13.5 t-121 5.5q-169 0 -265 -113.5t-96 -326.5v-306z" />
+<glyph unicode="&#x153;" horiz-adv-x="1854" d="M97 529v22q0 240 130 395.5t353 155.5q130 0 230 -54.5t164 -152.5q65 97 161.5 152t204.5 55q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-131 0 -232.5 52.5t-166.5 148.5 q-64 -96 -163 -148.5t-226 -52.5q-224 0 -354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22zM1085 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5 t-86 -209.5z" />
+<glyph unicode="&#x178;" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM281 1604v200h219v-200h-219zM751 1604v200h219v-200h-219z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="979" d="M171 1252v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="979" d="M135 1275q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#x2000;" horiz-adv-x="966" />
+<glyph unicode="&#x2001;" horiz-adv-x="1932" />
+<glyph unicode="&#x2002;" horiz-adv-x="966" />
+<glyph unicode="&#x2003;" horiz-adv-x="1932" />
+<glyph unicode="&#x2004;" horiz-adv-x="644" />
+<glyph unicode="&#x2005;" horiz-adv-x="483" />
+<glyph unicode="&#x2006;" horiz-adv-x="322" />
+<glyph unicode="&#x2007;" horiz-adv-x="322" />
+<glyph unicode="&#x2008;" horiz-adv-x="241" />
+<glyph unicode="&#x2009;" horiz-adv-x="386" />
+<glyph unicode="&#x200a;" horiz-adv-x="107" />
+<glyph unicode="&#x2010;" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="&#x2011;" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="&#x2012;" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="&#x2013;" horiz-adv-x="1416" d="M169 648v155h1086v-155h-1086z" />
+<glyph unicode="&#x2014;" horiz-adv-x="1660" d="M141 648v155h1336v-155h-1336z" />
+<glyph unicode="&#x2018;" horiz-adv-x="418" d="M80 1020v184l160 356h97l-60 -362v-178h-197z" />
+<glyph unicode="&#x2019;" horiz-adv-x="418" d="M80 1021l60 343v196h197v-193l-160 -346h-97z" />
+<glyph unicode="&#x201a;" horiz-adv-x="417" d="M80 -255l60 263v241h197v-223l-160 -281h-97z" />
+<glyph unicode="&#x201c;" horiz-adv-x="744" d="M80 1020v184l160 356h97l-60 -362v-178h-197zM409 1020v184l160 356h97l-60 -362v-178h-197z" />
+<glyph unicode="&#x201d;" horiz-adv-x="752" d="M80 1021l60 343v196h197v-193l-160 -346h-97zM417 1021l60 343v196h197v-193l-160 -346h-97z" />
+<glyph unicode="&#x201e;" horiz-adv-x="726" d="M80 -239l60 325v194h197v-184l-160 -335h-97zM388 -239l60 333v186h197v-184l-160 -335h-97z" />
+<glyph unicode="&#x2022;" horiz-adv-x="695" d="M137 733v60q0 88 56 144t150 56q95 0 151.5 -56t56.5 -144v-60q0 -89 -56 -143.5t-151 -54.5t-151 55t-56 143z" />
+<glyph unicode="&#x2026;" horiz-adv-x="1380" d="M161 0v202h197v-202h-197zM604 0v202h197v-202h-197zM1024 0v202h197v-202h-197z" />
+<glyph unicode="&#x202f;" horiz-adv-x="386" />
+<glyph unicode="&#x2039;" horiz-adv-x="615" d="M108 541v19l295 389h148l-255 -399l255 -398h-148z" />
+<glyph unicode="&#x203a;" horiz-adv-x="615" d="M88 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148z" />
+<glyph unicode="&#x205f;" horiz-adv-x="483" />
+<glyph unicode="&#x20ac;" horiz-adv-x="1088" d="M79 481v155h146v136h-146v155h146v15q0 244 141.5 389.5t372.5 145.5q59 0 117.5 -8t124.5 -23l-19 -159q-54 16 -110.5 25.5t-112.5 9.5q-146 0 -231.5 -103t-85.5 -275v-17h492v-155h-492v-136h492v-155h-485l-2 -5q-4 -138 81.5 -240.5t232.5 -102.5q57 0 113 8.5 t108 25.5l19 -157q-56 -15 -117.5 -23t-122.5 -8q-231 0 -373.5 144.5t-142.5 357.5h-146z" />
+<glyph unicode="&#x2122;" horiz-adv-x="1284" d="M103 1374v82h384v-82h-145v-455h-94v455h-145zM565 919v537h116l161 -390h6l162 390h110v-537h-93v343l-6 2l-150 -345h-51l-156 359l-6 -2v-357h-93z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1080" d="M0 0v1080h1080v-1080h-1080z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="1223" d="M56 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169zM866 0v1560h197v-1560h-197z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1847" d="M56 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169zM735 936v146h170v117q0 182 106.5 282t295.5 100q67 0 132 -15.5t153 -45.5l-34 -160 q-53 21 -113 36t-123 15q-117 0 -168.5 -52t-51.5 -160v-117h215v-146h-215v-936h-197v936h-170zM1490 0v1082h198v-1082h-198z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1930" d="M56 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169zM763 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5 l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169zM1573 0v1560h197v-1560h-197z" />
+<hkern u1="&#x22;" u2="w" k="-11" />
+<hkern u1="&#x27;" u2="w" k="-11" />
+<hkern u1="&#x28;" u2="&#x178;" k="-22" />
+<hkern u1="&#x28;" u2="&#xdd;" k="-22" />
+<hkern u1="&#x28;" u2="Y" k="-22" />
+<hkern u1="&#x28;" u2="W" k="-37" />
+<hkern u1="&#x28;" u2="V" k="-20" />
+<hkern u1="A" u2="w" k="33" />
+<hkern u1="A" u2="t" k="17" />
+<hkern u1="A" u2="&#x3f;" k="80" />
+<hkern u1="C" u2="&#x7d;" k="17" />
+<hkern u1="C" u2="]" k="12" />
+<hkern u1="C" u2="&#x29;" k="26" />
+<hkern u1="D" u2="&#xc6;" k="33" />
+<hkern u1="E" u2="w" k="22" />
+<hkern u1="E" u2="f" k="18" />
+<hkern u1="F" u2="&#x2026;" k="273" />
+<hkern u1="F" u2="&#x201e;" k="273" />
+<hkern u1="F" u2="&#x201a;" k="273" />
+<hkern u1="F" u2="&#x153;" k="21" />
+<hkern u1="F" u2="&#xff;" k="24" />
+<hkern u1="F" u2="&#xfd;" k="24" />
+<hkern u1="F" u2="&#xfc;" k="22" />
+<hkern u1="F" u2="&#xfb;" k="22" />
+<hkern u1="F" u2="&#xfa;" k="22" />
+<hkern u1="F" u2="&#xf9;" k="22" />
+<hkern u1="F" u2="&#xf6;" k="21" />
+<hkern u1="F" u2="&#xf5;" k="21" />
+<hkern u1="F" u2="&#xf4;" k="21" />
+<hkern u1="F" u2="&#xf3;" k="21" />
+<hkern u1="F" u2="&#xf2;" k="21" />
+<hkern u1="F" u2="&#xeb;" k="21" />
+<hkern u1="F" u2="&#xea;" k="21" />
+<hkern u1="F" u2="&#xe9;" k="21" />
+<hkern u1="F" u2="&#xe8;" k="21" />
+<hkern u1="F" u2="&#xe7;" k="21" />
+<hkern u1="F" u2="&#xe5;" k="34" />
+<hkern u1="F" u2="&#xe4;" k="34" />
+<hkern u1="F" u2="&#xe3;" k="34" />
+<hkern u1="F" u2="&#xe2;" k="34" />
+<hkern u1="F" u2="&#xe1;" k="34" />
+<hkern u1="F" u2="&#xe0;" k="34" />
+<hkern u1="F" u2="&#xc5;" k="59" />
+<hkern u1="F" u2="&#xc4;" k="59" />
+<hkern u1="F" u2="&#xc3;" k="59" />
+<hkern u1="F" u2="&#xc2;" k="59" />
+<hkern u1="F" u2="&#xc1;" k="59" />
+<hkern u1="F" u2="&#xc0;" k="59" />
+<hkern u1="F" u2="y" k="24" />
+<hkern u1="F" u2="v" k="24" />
+<hkern u1="F" u2="u" k="22" />
+<hkern u1="F" u2="r" k="26" />
+<hkern u1="F" u2="q" k="21" />
+<hkern u1="F" u2="o" k="21" />
+<hkern u1="F" u2="g" k="21" />
+<hkern u1="F" u2="e" k="21" />
+<hkern u1="F" u2="d" k="21" />
+<hkern u1="F" u2="c" k="21" />
+<hkern u1="F" u2="a" k="34" />
+<hkern u1="F" u2="T" k="-20" />
+<hkern u1="F" u2="A" k="59" />
+<hkern u1="F" u2="&#x3a;" k="273" />
+<hkern u1="F" u2="&#x2e;" k="273" />
+<hkern u1="F" u2="&#x2c;" k="273" />
+<hkern u1="K" u2="w" k="63" />
+<hkern u1="L" u2="w" k="52" />
+<hkern u1="O" u2="&#xc6;" k="33" />
+<hkern u1="P" u2="&#xc6;" k="293" />
+<hkern u1="P" u2="t" k="-14" />
+<hkern u1="Q" u2="&#x178;" k="35" />
+<hkern u1="Q" u2="&#xdd;" k="35" />
+<hkern u1="Q" u2="Y" k="35" />
+<hkern u1="Q" u2="W" k="20" />
+<hkern u1="Q" u2="V" k="28" />
+<hkern u1="Q" u2="T" k="33" />
+<hkern u1="R" u2="&#x178;" k="48" />
+<hkern u1="R" u2="&#xdd;" k="48" />
+<hkern u1="R" u2="Y" k="48" />
+<hkern u1="R" u2="V" k="19" />
+<hkern u1="R" u2="T" k="50" />
+<hkern u1="T" u2="&#xf8;" k="95" />
+<hkern u1="T" u2="&#xe6;" k="84" />
+<hkern u1="T" u2="&#xc6;" k="188" />
+<hkern u1="T" u2="&#xbb;" k="147" />
+<hkern u1="T" u2="&#xab;" k="151" />
+<hkern u1="T" u2="w" k="47" />
+<hkern u1="T" u2="r" k="65" />
+<hkern u1="V" u2="&#x7d;" k="-19" />
+<hkern u1="V" u2="r" k="30" />
+<hkern u1="V" u2="]" k="-17" />
+<hkern u1="V" u2="&#x29;" k="-20" />
+<hkern u1="W" u2="&#x7d;" k="-14" />
+<hkern u1="W" u2="r" k="21" />
+<hkern u1="W" u2="]" k="-12" />
+<hkern u1="W" u2="&#x29;" k="-15" />
+<hkern u1="Y" u2="&#x2022;" k="45" />
+<hkern u1="Y" u2="&#xf8;" k="64" />
+<hkern u1="Y" u2="&#xe6;" k="63" />
+<hkern u1="Y" u2="&#xc6;" k="96" />
+<hkern u1="Y" u2="&#xbb;" k="51" />
+<hkern u1="Y" u2="&#xab;" k="82" />
+<hkern u1="Y" u2="&#x7d;" k="-19" />
+<hkern u1="Y" u2="t" k="22" />
+<hkern u1="Y" u2="r" k="40" />
+<hkern u1="Y" u2="f" k="22" />
+<hkern u1="Y" u2="]" k="-18" />
+<hkern u1="Y" u2="&#x2a;" k="49" />
+<hkern u1="Y" u2="&#x29;" k="-20" />
+<hkern u1="Y" u2="&#x26;" k="30" />
+<hkern u1="Z" u2="w" k="27" />
+<hkern u1="[" u2="&#xdc;" k="18" />
+<hkern u1="[" u2="&#xdb;" k="18" />
+<hkern u1="[" u2="&#xda;" k="18" />
+<hkern u1="[" u2="&#xd9;" k="18" />
+<hkern u1="[" u2="U" k="18" />
+<hkern u1="[" u2="J" k="18" />
+<hkern u1="f" u2="&#x201d;" k="-16" />
+<hkern u1="f" u2="&#x201c;" k="-16" />
+<hkern u1="f" u2="&#x2019;" k="-16" />
+<hkern u1="f" u2="&#x2018;" k="-16" />
+<hkern u1="f" u2="&#x153;" k="24" />
+<hkern u1="f" u2="&#xeb;" k="24" />
+<hkern u1="f" u2="&#xea;" k="24" />
+<hkern u1="f" u2="&#xe9;" k="24" />
+<hkern u1="f" u2="&#xe8;" k="24" />
+<hkern u1="f" u2="&#xe7;" k="24" />
+<hkern u1="f" u2="&#x7d;" k="-19" />
+<hkern u1="f" u2="q" k="24" />
+<hkern u1="f" u2="g" k="24" />
+<hkern u1="f" u2="e" k="24" />
+<hkern u1="f" u2="d" k="24" />
+<hkern u1="f" u2="c" k="24" />
+<hkern u1="f" u2="]" k="-18" />
+<hkern u1="f" u2="&#x29;" k="-20" />
+<hkern u1="f" u2="&#x27;" k="-16" />
+<hkern u1="f" u2="&#x22;" k="-16" />
+<hkern u1="k" u2="&#x153;" k="20" />
+<hkern u1="k" u2="&#xeb;" k="20" />
+<hkern u1="k" u2="&#xea;" k="20" />
+<hkern u1="k" u2="&#xe9;" k="20" />
+<hkern u1="k" u2="&#xe8;" k="20" />
+<hkern u1="k" u2="&#xe7;" k="20" />
+<hkern u1="k" u2="q" k="20" />
+<hkern u1="k" u2="g" k="20" />
+<hkern u1="k" u2="e" k="20" />
+<hkern u1="k" u2="d" k="20" />
+<hkern u1="k" u2="c" k="20" />
+<hkern u1="r" u2="w" k="-17" />
+<hkern u1="r" u2="t" k="-17" />
+<hkern u1="r" u2="f" k="-15" />
+<hkern u1="v" u2="f" k="-13" />
+<hkern u1="w" u2="&#x2026;" k="124" />
+<hkern u1="w" u2="&#x201e;" k="124" />
+<hkern u1="w" u2="&#x201a;" k="124" />
+<hkern u1="w" u2="&#x3a;" k="124" />
+<hkern u1="w" u2="&#x2e;" k="124" />
+<hkern u1="w" u2="&#x2c;" k="124" />
+<hkern u1="y" u2="f" k="-13" />
+<hkern u1="&#x7b;" u2="&#xdc;" k="20" />
+<hkern u1="&#x7b;" u2="&#xdb;" k="20" />
+<hkern u1="&#x7b;" u2="&#xda;" k="20" />
+<hkern u1="&#x7b;" u2="&#xd9;" k="20" />
+<hkern u1="&#x7b;" u2="U" k="20" />
+<hkern u1="&#x7b;" u2="J" k="20" />
+<hkern u1="&#xc0;" u2="w" k="33" />
+<hkern u1="&#xc0;" u2="t" k="17" />
+<hkern u1="&#xc0;" u2="&#x3f;" k="80" />
+<hkern u1="&#xc1;" u2="w" k="33" />
+<hkern u1="&#xc1;" u2="t" k="17" />
+<hkern u1="&#xc1;" u2="&#x3f;" k="80" />
+<hkern u1="&#xc2;" u2="w" k="33" />
+<hkern u1="&#xc2;" u2="t" k="17" />
+<hkern u1="&#xc2;" u2="&#x3f;" k="80" />
+<hkern u1="&#xc3;" u2="w" k="33" />
+<hkern u1="&#xc3;" u2="t" k="17" />
+<hkern u1="&#xc3;" u2="&#x3f;" k="80" />
+<hkern u1="&#xc4;" u2="w" k="33" />
+<hkern u1="&#xc4;" u2="t" k="17" />
+<hkern u1="&#xc4;" u2="&#x3f;" k="80" />
+<hkern u1="&#xc5;" u2="w" k="33" />
+<hkern u1="&#xc5;" u2="t" k="17" />
+<hkern u1="&#xc5;" u2="&#x3f;" k="80" />
+<hkern u1="&#xc7;" u2="&#x7d;" k="17" />
+<hkern u1="&#xc7;" u2="]" k="12" />
+<hkern u1="&#xc7;" u2="&#x29;" k="26" />
+<hkern u1="&#xc8;" u2="w" k="22" />
+<hkern u1="&#xc8;" u2="f" k="18" />
+<hkern u1="&#xc9;" u2="w" k="22" />
+<hkern u1="&#xc9;" u2="f" k="18" />
+<hkern u1="&#xca;" u2="w" k="22" />
+<hkern u1="&#xca;" u2="f" k="18" />
+<hkern u1="&#xcb;" u2="w" k="22" />
+<hkern u1="&#xcb;" u2="f" k="18" />
+<hkern u1="&#xd0;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd2;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd3;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd4;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd5;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd6;" u2="&#xc6;" k="33" />
+<hkern u1="&#xdd;" u2="&#x2022;" k="45" />
+<hkern u1="&#xdd;" u2="&#xf8;" k="64" />
+<hkern u1="&#xdd;" u2="&#xe6;" k="63" />
+<hkern u1="&#xdd;" u2="&#xc6;" k="96" />
+<hkern u1="&#xdd;" u2="&#xbb;" k="51" />
+<hkern u1="&#xdd;" u2="&#xab;" k="82" />
+<hkern u1="&#xdd;" u2="&#x7d;" k="-19" />
+<hkern u1="&#xdd;" u2="t" k="22" />
+<hkern u1="&#xdd;" u2="r" k="40" />
+<hkern u1="&#xdd;" u2="f" k="22" />
+<hkern u1="&#xdd;" u2="]" k="-18" />
+<hkern u1="&#xdd;" u2="&#x2a;" k="49" />
+<hkern u1="&#xdd;" u2="&#x29;" k="-20" />
+<hkern u1="&#xdd;" u2="&#x26;" k="30" />
+<hkern u1="&#xfd;" u2="f" k="-13" />
+<hkern u1="&#xff;" u2="f" k="-13" />
+<hkern u1="&#x178;" u2="&#x2022;" k="45" />
+<hkern u1="&#x178;" u2="&#xf8;" k="64" />
+<hkern u1="&#x178;" u2="&#xe6;" k="63" />
+<hkern u1="&#x178;" u2="&#xc6;" k="96" />
+<hkern u1="&#x178;" u2="&#xbb;" k="51" />
+<hkern u1="&#x178;" u2="&#xab;" k="82" />
+<hkern u1="&#x178;" u2="&#x7d;" k="-19" />
+<hkern u1="&#x178;" u2="t" k="22" />
+<hkern u1="&#x178;" u2="r" k="40" />
+<hkern u1="&#x178;" u2="f" k="22" />
+<hkern u1="&#x178;" u2="]" k="-18" />
+<hkern u1="&#x178;" u2="&#x2a;" k="49" />
+<hkern u1="&#x178;" u2="&#x29;" k="-20" />
+<hkern u1="&#x178;" u2="&#x26;" k="30" />
+<hkern u1="&#x2018;" u2="w" k="-11" />
+<hkern u1="&#x2019;" u2="w" k="-11" />
+<hkern u1="&#x201c;" u2="w" k="-11" />
+<hkern u1="&#x201d;" u2="w" k="-11" />
+<hkern g1="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="282" />
+<hkern g1="B"  g2="T"  k="27" />
+<hkern g1="B"  g2="V"  k="24" />
+<hkern g1="B"  g2="Y,Yacute,Ydieresis"         k="55" />
+<hkern g1="C,Ccedilla"         g2="T"  k="29" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="21" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="T"  k="27" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="V"  k="22" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="Y,Yacute,Ydieresis"         k="43" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="121" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="X"  k="22" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="Z"  k="23" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="19" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="19" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="T"  k="-20" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="u,ugrave,uacute,ucircumflex,udieresis"      k="17" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="v,y,yacute,ydieresis"       k="26" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="-18" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="T"  k="29" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="Y,Yacute,Ydieresis"         k="28" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="X"  k="-17" />
+<hkern g1="J,U,Ugrave,Uacute,Ucircumflex,Udieresis"    g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="22" />
+<hkern g1="K"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="26" />
+<hkern g1="K"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="27" />
+<hkern g1="K"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="23" />
+<hkern g1="K"  g2="v,y,yacute,ydieresis"       k="40" />
+<hkern g1="K"  g2="hyphen,uni00AD,endash,emdash"       k="162" />
+<hkern g1="K"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="31" />
+<hkern g1="L"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="255" />
+<hkern g1="L"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="-19" />
+<hkern g1="L"  g2="T"  k="206" />
+<hkern g1="L"  g2="V"  k="205" />
+<hkern g1="L"  g2="Y,Yacute,Ydieresis"         k="278" />
+<hkern g1="L"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="14" />
+<hkern g1="L"  g2="v,y,yacute,ydieresis"       k="123" />
+<hkern g1="L"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="25" />
+<hkern g1="L"  g2="U,Ugrave,Uacute,Ucircumflex,Udieresis"      k="24" />
+<hkern g1="L"  g2="W"  k="93" />
+<hkern g1="P"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="177" />
+<hkern g1="P"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="11" />
+<hkern g1="P"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="13" />
+<hkern g1="P"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="13" />
+<hkern g1="P"  g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="402" />
+<hkern g1="P"  g2="X"  k="50" />
+<hkern g1="P"  g2="Z"  k="35" />
+<hkern g1="P"  g2="v,y,yacute,ydieresis"       k="-15" />
+<hkern g1="T"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="108" />
+<hkern g1="T"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="83" />
+<hkern g1="T"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="89" />
+<hkern g1="T"  g2="m,n,p,ntilde"       k="89" />
+<hkern g1="T"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="79" />
+<hkern g1="T"  g2="s"  k="76" />
+<hkern g1="T"  g2="T"  k="-16" />
+<hkern g1="T"  g2="V"  k="-16" />
+<hkern g1="T"  g2="Y,Yacute,Ydieresis"         k="-16" />
+<hkern g1="T"  g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="257" />
+<hkern g1="T"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="65" />
+<hkern g1="T"  g2="v,y,yacute,ydieresis"       k="81" />
+<hkern g1="T"  g2="hyphen,uni00AD,endash,emdash"       k="271" />
+<hkern g1="T"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="28" />
+<hkern g1="T"  g2="W"  k="-15" />
+<hkern g1="T"  g2="S"  k="16" />
+<hkern g1="T"  g2="x"  k="77" />
+<hkern g1="T"  g2="z"  k="60" />
+<hkern g1="V"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="75" />
+<hkern g1="V"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="46" />
+<hkern g1="V"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="44" />
+<hkern g1="V"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="46" />
+<hkern g1="V"  g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="215" />
+<hkern g1="V"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="28" />
+<hkern g1="V"  g2="v,y,yacute,ydieresis"       k="11" />
+<hkern g1="V"  g2="hyphen,uni00AD,endash,emdash"       k="154" />
+<hkern g1="V"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="13" />
+<hkern g1="W"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="43" />
+<hkern g1="W"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="33" />
+<hkern g1="W"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="31" />
+<hkern g1="W"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="31" />
+<hkern g1="W"  g2="T"  k="-14" />
+<hkern g1="W"  g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="142" />
+<hkern g1="W"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="19" />
+<hkern g1="W"  g2="hyphen,uni00AD,endash,emdash"       k="60" />
+<hkern g1="X"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="26" />
+<hkern g1="X"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="21" />
+<hkern g1="X"  g2="V"  k="-14" />
+<hkern g1="X"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="21" />
+<hkern g1="X"  g2="v,y,yacute,ydieresis"       k="31" />
+<hkern g1="X"  g2="hyphen,uni00AD,endash,emdash"       k="153" />
+<hkern g1="X"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="25" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="148" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="63" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="65" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="m,n,p,ntilde"       k="40" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="65" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="s"  k="58" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="T"  k="-17" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="V"  k="-18" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="Y,Yacute,Ydieresis"         k="-18" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="230" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="X"  k="-13" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="u,ugrave,uacute,ucircumflex,udieresis"      k="39" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="v,y,yacute,ydieresis"       k="20" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="hyphen,uni00AD,endash,emdash"       k="150" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="29" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="U,Ugrave,Uacute,Ucircumflex,Udieresis"      k="96" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="W"  k="-17" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="S"  k="16" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="x"  k="23" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="z"  k="30" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="J"  k="96" />
+<hkern g1="Z"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="-13" />
+<hkern g1="Z"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="21" />
+<hkern g1="Z"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="21" />
+<hkern g1="Z"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="19" />
+<hkern g1="Z"  g2="v,y,yacute,ydieresis"       k="27" />
+<hkern g1="Z"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="26" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="17" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         g2="v,y,yacute,ydieresis"       k="15" />
+<hkern g1="b,p,thorn"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="29" />
+<hkern g1="b,p,thorn"  g2="v,y,yacute,ydieresis"       k="11" />
+<hkern g1="b,p,thorn"  g2="x"  k="15" />
+<hkern g1="b,p,thorn"  g2="z"  k="15" />
+<hkern g1="c,ccedilla"         g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="11" />
+<hkern g1="e,egrave,eacute,ecircumflex,edieresis"      g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="14" />
+<hkern g1="e,egrave,eacute,ecircumflex,edieresis"      g2="v,y,yacute,ydieresis"       k="13" />
+<hkern g1="h,m,n,ntilde"       g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="16" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="20" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="v,y,yacute,ydieresis"       k="15" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="x"  k="21" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="z"  k="16" />
+<hkern g1="r"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="-16" />
+<hkern g1="r"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="19" />
+<hkern g1="r"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="20" />
+<hkern g1="r"  g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="172" />
+<hkern g1="r"  g2="v,y,yacute,ydieresis"       k="-18" />
+<hkern g1="v,y,yacute,ydieresis"       g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="-15" />
+<hkern g1="v,y,yacute,ydieresis"       g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="15" />
+<hkern g1="v,y,yacute,ydieresis"       g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="13" />
+<hkern g1="v,y,yacute,ydieresis"       g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="15" />
+<hkern g1="v,y,yacute,ydieresis"       g2="comma,period,colon,quotesinglbase,quotedblbase,ellipsis"    k="165" />
+<hkern g1="x"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="20" />
+<hkern g1="x"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="39" />
+<hkern g1="z"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="16" />
+<hkern g1="z"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="16" />
+</font>
+</defs></svg> 
\ No newline at end of file
diff --git a/skyquake/framework/style/fonts/Roboto-Regular-webfont.ttf b/skyquake/framework/style/fonts/Roboto-Regular-webfont.ttf
new file mode 100755 (executable)
index 0000000..44dd78d
Binary files /dev/null and b/skyquake/framework/style/fonts/Roboto-Regular-webfont.ttf differ
diff --git a/skyquake/framework/style/fonts/Roboto-Regular-webfont.woff b/skyquake/framework/style/fonts/Roboto-Regular-webfont.woff
new file mode 100755 (executable)
index 0000000..bfa05d5
Binary files /dev/null and b/skyquake/framework/style/fonts/Roboto-Regular-webfont.woff differ
diff --git a/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.eot b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.eot
new file mode 100755 (executable)
index 0000000..bbc67d8
Binary files /dev/null and b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.eot differ
diff --git a/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.svg b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.svg
new file mode 100755 (executable)
index 0000000..417a2a9
--- /dev/null
@@ -0,0 +1,643 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="roboto_condensedbold" horiz-adv-x="995" >
+<font-face units-per-em="2048" ascent="1638" descent="-410" />
+<missing-glyph horiz-adv-x="449" />
+<glyph unicode="&#xfb01;" horiz-adv-x="1107" d="M18 876v206h133v70q0 207 112 318t316 111q70 0 138.5 -15t153.5 -44l-40 -232q-65 22 -115.5 34t-118.5 12q-80 0 -121 -47t-41 -137v-70h173v-206h-173v-876h-284v876h-133zM716 0v1082h285v-1082h-285z" />
+<glyph horiz-adv-x="2048" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="449" />
+<glyph horiz-adv-x="16" />
+<glyph unicode="&#x9;" horiz-adv-x="16" />
+<glyph unicode=" "  horiz-adv-x="449" />
+<glyph unicode="&#x09;" horiz-adv-x="449" />
+<glyph unicode="&#xa0;" horiz-adv-x="449" />
+<glyph unicode="!" horiz-adv-x="506" d="M112 506v950h285v-950h-285zM115 0v258h280v-258h-280z" />
+<glyph unicode="&#x22;" horiz-adv-x="602" d="M51 1046v514h198v-263l-74 -251h-124zM351 1046l1 247v267h196v-263l-74 -251h-123z" />
+<glyph unicode="#" horiz-adv-x="1034" d="M44 410v166h209l43 298h-189v166h213l61 416h172l-60 -416h136l60 416h173l-60 -416h186v-166h-210l-43 -298h189v-166h-213l-59 -410h-173l59 410h-136l-59 -410h-173l59 410h-185zM426 576h136l43 298h-136z" />
+<glyph unicode="$" horiz-adv-x="1019" d="M79 456h284q0 -135 44 -193.5t115 -58.5q63 0 96 49t33 128q0 84 -33 133t-115 96q-194 86 -285.5 183t-91.5 279q0 166 93.5 274t250.5 127v212h144v-215q149 -28 236.5 -148.5t87.5 -313.5h-284q0 117 -35 180t-92 63q-59 0 -88 -50t-29 -130q0 -76 32.5 -125 t117.5 -97q192 -91 283.5 -189t91.5 -277q0 -171 -92 -275.5t-248 -123.5v-199h-145v199q-161 20 -266 135t-105 337z" />
+<glyph unicode="%" horiz-adv-x="1356" d="M90 1099v77q0 129 74.5 215t209.5 86q137 0 211 -85.5t74 -215.5v-77q0 -130 -74 -214.5t-209 -84.5q-136 0 -211 85t-75 214zM276 1099q0 -57 26 -96.5t74 -39.5q46 0 71.5 39t25.5 97v77q0 58 -26 98t-73 40t-72.5 -40.5t-25.5 -97.5v-77zM283 184l601 1138l134 -74 l-601 -1138zM700 280v77q0 128 75 214t210 86q137 0 211 -85.5t74 -214.5v-77q0 -130 -74 -215t-209 -85q-136 0 -211.5 85t-75.5 215zM887 280q0 -56 28.5 -97t71.5 -40q55 -1 76 36t21 101v77q0 57 -26 97t-73 40q-48 0 -73 -40t-25 -97v-77z" />
+<glyph unicode="&#x26;" horiz-adv-x="1221" d="M59 388q0 118 57.5 203.5t175.5 178.5q-62 94 -92 170.5t-30 156.5q0 171 98.5 275.5t262.5 104.5q142 0 232.5 -98.5t90.5 -238.5q0 -97 -43.5 -177.5t-117.5 -139.5l-81 -65l230 -304l6 1q27 52 42.5 117.5t15.5 138.5h208q0 -138 -29.5 -252.5t-92.5 -203.5l194 -255 h-322l-64 84q-75 -53 -152.5 -79t-166.5 -26q-193 0 -307.5 113t-114.5 296zM345 406q0 -87 43.5 -143.5t109.5 -56.5q44 0 88 12t85 37l-259 344l-7 -6q-35 -48 -47.5 -93.5t-12.5 -93.5zM423 1100q0 -41 17.5 -84t52.5 -94l59 44q50 36 67 73.5t17 82.5q0 50 -29.5 88.5 t-76.5 38.5q-52 0 -79.5 -42.5t-27.5 -106.5z" />
+<glyph unicode="'" horiz-adv-x="302" d="M52 1275v285h190v-272l-66 -281h-123z" />
+<glyph unicode="(" horiz-adv-x="633" d="M109 567v24q0 384 131 658.5t297 356.5h6l50 -143q-105 -98 -177.5 -317.5t-72.5 -552.5v-28q0 -333 72 -552t178 -319l-50 -141h-6q-166 82 -297 355t-131 659z" />
+<glyph unicode=")" horiz-adv-x="632" d="M38 -306q104 98 177 318t73 553v28q0 332 -73.5 553t-176.5 319l52 141h6q169 -80 306 -361t137 -654v-24q0 -375 -137 -654.5t-306 -359.5h-6z" />
+<glyph unicode="*" horiz-adv-x="825" d="M31 1058l53 173l260 -127l-19 352h178l-19 -358l253 125l53 -175l-268 -93l176 -269l-144 -107l-149 294l-150 -285l-143 103l183 275z" />
+<glyph unicode="+" d="M54 556v254h307v396h269v-396h306v-254h-306v-410h-269v410h-307z" />
+<glyph unicode="," horiz-adv-x="459" d="M47 -309l59 319v231h252v-239l-145 -311h-166z" />
+<glyph unicode="-" horiz-adv-x="748" d="M120 511v228h497v-228h-497z" />
+<glyph unicode="." horiz-adv-x="543" d="M124 0v258h281v-258h-281z" />
+<glyph unicode="/" horiz-adv-x="646" d="M-12 -125l432 1581h206l-434 -1581h-204z" />
+<glyph unicode="0" horiz-adv-x="1014" d="M80 571v313q0 290 115.5 441.5t310.5 151.5t311 -151.5t116 -441.5v-313q0 -291 -115.5 -441.5t-309.5 -150.5q-196 0 -312 150.5t-116 441.5zM364 548q0 -178 37 -259.5t104 -75.5h6q66 -6 102 75t36 260v361q0 176 -37 257t-103 76h-6q-67 5 -103 -76t-36 -257v-361z " />
+<glyph unicode="1" horiz-adv-x="1019" d="M128 1153v205l554 99v-1457h-284v1159z" />
+<glyph unicode="2" horiz-adv-x="1019" d="M64 1004q-4 198 112 335.5t312 137.5q200 0 312 -116t112 -316q0 -134 -62.5 -248t-208.5 -298l-190 -272h492v-227h-860v193l397 503q79 112 113.5 195t34.5 151q0 93 -36 150t-104 57q-70 0 -107.5 -69t-37.5 -181h-277z" />
+<glyph unicode="3" horiz-adv-x="1019" d="M58 394l2 6h276q0 -84 44 -139t109 -55q74 0 117.5 55.5t43.5 148.5q0 116 -42.5 169.5t-125.5 53.5h-142v220h142q76 0 113 54t37 151q0 85 -37 138t-106 53q-56 0 -96.5 -47t-40.5 -123h-275l-2 6q-5 173 113.5 282.5t292.5 109.5q198 0 316 -108.5t118 -306.5 q0 -99 -51 -183.5t-140 -131.5q102 -42 156 -130.5t54 -210.5q0 -199 -127.5 -313t-326.5 -114q-175 0 -301 107.5t-121 307.5z" />
+<glyph unicode="4" horiz-adv-x="1019" d="M53 496l497 960h284v-910h126v-228h-126v-318h-283v318h-483zM311 546h240v503l-6 1l-15 -27z" />
+<glyph unicode="5" horiz-adv-x="1019" d="M86 393l2 5l276 15q0 -98 40 -152.5t105 -54.5q75 0 109 71.5t34 187.5q0 129 -38 204t-116 75q-59 0 -91 -32t-44 -85l-253 17l72 812h712v-233h-480l-31 -343q31 31 77.5 51.5t97.5 22.5q182 3 279.5 -125.5t97.5 -361.5q0 -208 -110.5 -348t-315.5 -140 q-174 0 -300.5 111.5t-122.5 302.5z" />
+<glyph unicode="6" horiz-adv-x="1019" d="M80 563v300q0 283 144.5 448.5t369.5 165.5q71 0 129.5 -15.5t119.5 -46.5l-48 -215q-53 23 -97.5 34.5t-102.5 11.5q-104 0 -166.5 -94.5t-59.5 -267.5l4 -4q39 45 100 71t136 26q165 0 257.5 -139t92.5 -356q0 -218 -119 -360.5t-307 -142.5q-202 0 -327.5 156 t-125.5 428zM364 560q0 -171 45.5 -263t123.5 -92q64 0 103 81.5t39 195.5q0 121 -40 196t-103 75q-59 0 -101 -20.5t-67 -57.5v-115z" />
+<glyph unicode="7" horiz-adv-x="1019" d="M55 1228v228h886v-228q-197 -253 -261.5 -486.5t-93.5 -601.5l-13 -140h-285l14 140q27 327 116.5 598t250.5 490h-614z" />
+<glyph unicode="8" horiz-adv-x="1019" d="M83 398q0 117 56 207.5t155 139.5q-87 47 -136 131t-49 194q0 193 110 300t290 107t290.5 -107t110.5 -300q0 -110 -49.5 -194t-135.5 -131q98 -50 154 -140t56 -207q0 -203 -117 -311t-308 -108t-309 108.5t-118 310.5zM368 419q0 -100 38 -156.5t104 -56.5 q64 0 102.5 56.5t38.5 156.5q0 98 -39 155.5t-103 57.5q-65 0 -103 -57.5t-38 -155.5zM395 1056q0 -92 29.5 -144.5t85.5 -52.5t85 52t29 145q0 89 -29.5 141t-85.5 52t-85 -51t-29 -142z" />
+<glyph unicode="9" horiz-adv-x="1019" d="M75 957q0 219 120.5 369.5t304.5 150.5q191 0 311 -154.5t120 -430.5v-356q0 -256 -136.5 -406.5t-345.5 -150.5q-62 0 -131 16t-128 46l32 212q55 -24 108.5 -35.5t118.5 -11.5q86 0 142.5 82t56.5 230v56q-40 -58 -93.5 -88t-113.5 -30q-171 0 -268.5 134.5 t-97.5 366.5zM358 957q0 -131 35 -209t102 -78q50 0 88.5 24.5t64.5 66.5v166q0 158 -40 239t-105 77h-6q-61 4 -100 -82.5t-39 -203.5z" />
+<glyph unicode=":" horiz-adv-x="540" d="M127 0v258h281v-258h-281zM127 823v258h281v-258h-281z" />
+<glyph unicode=";" horiz-adv-x="516" d="M89 -309l59 319v231h252v-239l-145 -311h-166zM118 823v258h281v-258h-281z" />
+<glyph unicode="&#x3c;" horiz-adv-x="898" d="M48 430v230l739 364v-270l-482 -209v-6l482 -203v-271z" />
+<glyph unicode="=" horiz-adv-x="1023" d="M120 323v229h772v-229h-772zM120 756v228h772v-228h-772z" />
+<glyph unicode="&#x3e;" horiz-adv-x="909" d="M106 65v269l487 209v6l-487 206v269l745 -364v-230z" />
+<glyph unicode="?" horiz-adv-x="898" d="M25 1075q-3 197 111 299.5t299 102.5q200 0 314.5 -115.5t114.5 -312.5q0 -125 -64 -231.5t-160 -178.5q-51 -46 -68.5 -94.5t-17.5 -131.5h-284q1 136 39.5 202t147.5 159q56 55 89 121.5t33 152.5q0 92 -37.5 146t-106.5 54q-53 0 -92 -46.5t-40 -132.5h-276zM271 0 v247h281v-247h-281z" />
+<glyph unicode="@" horiz-adv-x="1615" d="M56 478q15 428 226 682t558 254q342 0 526 -241t170 -657q-8 -219 -115.5 -378t-321.5 -159q-72 0 -123.5 44.5t-72.5 126.5q-38 -85 -93.5 -126.5t-129.5 -41.5q-128 0 -196.5 119t-50.5 315q22 252 127.5 404t255.5 152q106 0 171 -26t142 -80l-3 -4h5l-46 -569 q-5 -97 10 -132t41 -28l6 -1q96 -5 154.5 105t66.5 279q13 350 -119 546.5t-408 196.5q-266 0 -422 -210.5t-168 -570.5q-16 -352 126 -557.5t407 -205.5q75 0 155 19.5t138 49.5l35 -148q-60 -42 -151.5 -65.5t-179.5 -23.5q-353 0 -544.5 249t-175.5 682zM649 416 q-8 -127 15.5 -194t75.5 -67q46 0 83.5 28.5t66.5 103.5v6l39 496q-19 5 -37.5 8.5t-37.5 3.5q-95 0 -142.5 -95t-62.5 -290z" />
+<glyph unicode="A" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM439 538h268l-131 515h-6z" />
+<glyph unicode="B" horiz-adv-x="1136" d="M110 0v1456h429q225 0 351.5 -100t126.5 -298q0 -104 -46 -184.5t-138 -120.5q115 -27 170 -117t55 -211q0 -209 -119.5 -317t-342.5 -108h-486zM395 227h201q90 0 134.5 50t44.5 149q0 104 -38 160t-122 56h-220v-415zM395 841h157q87 2 133.5 50.5t46.5 139.5 q0 102 -48 149.5t-145 47.5h-144v-387z" />
+<glyph unicode="C" horiz-adv-x="1088" d="M74 510v435q0 253 130.5 392.5t349.5 139.5q232 0 350.5 -124t122.5 -367l-3 -6h-274q1 17 1 33q0 118 -40 173q-45 63 -157 63q-96 0 -147 -75t-51 -227v-437q0 -154 54.5 -229t159.5 -75q104 0 144 60q36 53 36 172q0 15 -1 31h274l3 -6v-8q0 -234 -114 -354 q-116 -122 -342 -122t-361 138.5t-135 392.5z" />
+<glyph unicode="D" horiz-adv-x="1151" d="M110 0v1456h440q224 0 370 -169.5t146 -436.5v-245q0 -267 -146 -436t-370 -169h-440zM395 227h139q119 0 183.5 103.5t64.5 274.5v247q0 170 -64.5 273t-183.5 103h-139v-1001z" />
+<glyph unicode="E" horiz-adv-x="1008" d="M110 0v1456h858v-228h-573v-362h489v-227h-489v-412h575v-227h-860z" />
+<glyph unicode="F" horiz-adv-x="1016" d="M110 0v1456h866v-228h-581v-396h494v-227h-494v-605h-285z" />
+<glyph unicode="G" horiz-adv-x="1179" d="M81 506v444q0 251 136.5 389t361.5 138q242 0 363 -118.5t126 -339.5l-2 -6h-267q-3 123 -54.5 179.5t-157.5 56.5q-104 0 -163 -73.5t-59 -223.5v-446q0 -153 59.5 -226.5t173.5 -73.5q85 0 125.5 23t66.5 68v261h-192v200h476v-542q-59 -94 -177 -165.5t-299 -71.5 q-234 0 -375.5 137t-141.5 390z" />
+<glyph unicode="H" horiz-adv-x="1241" d="M110 0v1456h285v-626h452v626h284v-1456h-284v603h-452v-603h-285z" />
+<glyph unicode="I" horiz-adv-x="534" d="M125 0v1456h283v-1456h-283z" />
+<glyph unicode="J" horiz-adv-x="1015" d="M57 421l3 6h277q0 -115 40.5 -168t104.5 -53q58 0 99.5 63t41.5 175v1012h283v-1012q0 -214 -120.5 -339.5t-303.5 -125.5q-198 0 -314 112q-111 108 -111 316v14z" />
+<glyph unicode="K" horiz-adv-x="1137" d="M110 0v1456h285v-592h92l284 592h349l-397 -665l430 -791h-346l-288 605h-124v-605h-285z" />
+<glyph unicode="L" horiz-adv-x="959" d="M110 0v1456h285v-1229h532v-227h-817z" />
+<glyph unicode="M" horiz-adv-x="1481" d="M105 0v1456h369l261 -1069h6l264 1069h371v-1456h-283v423l24 566l-6 1l-278 -990h-189l-275 982l-6 -1l25 -558v-423h-283z" />
+<glyph unicode="N" horiz-adv-x="1241" d="M110 0v1456h285l445 -930l6 2v928h283v-1456h-283l-445 931l-6 -2v-929h-285z" />
+<glyph unicode="O" horiz-adv-x="1166" d="M75 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -256 -139 -400t-370 -144t-369 144t-138 400zM357 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5t-169 79.5q-112 0 -168 -79t-56 -236v-410z" />
+<glyph unicode="P" horiz-adv-x="1158" d="M110 0v1456h506q218 0 344 -129t126 -338q0 -210 -126.5 -338.5t-343.5 -128.5h-221v-522h-285zM395 750h221q91 0 139 67t48 170q0 104 -47.5 172.5t-139.5 68.5h-221v-478z" />
+<glyph unicode="Q" horiz-adv-x="1241" d="M81 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -113 -29 -206t-82 -161l216 -237l-176 -150l-224 249q-49 -19 -102.5 -29t-111.5 -10q-231 0 -369 144t-138 400zM363 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5 t-169 79.5q-112 0 -168 -79t-56 -236v-410z" />
+<glyph unicode="R" horiz-adv-x="1162" d="M111 0v1455h475q215 0 337.5 -113.5t122.5 -315.5q0 -114 -51 -196.5t-149 -131.5q112 -38 161.5 -126t49.5 -220v-103q0 -60 14 -128.5t49 -99.5v-21h-294q-35 32 -44 104t-9 147v99q0 109 -44.5 169t-127.5 60h-206v-579h-284zM395 806h190q87 0 132 53t45 151 q0 100 -45 159t-131 59h-191v-422z" />
+<glyph unicode="S" horiz-adv-x="1109" d="M72 449l2 6h277q0 -135 57 -194t172 -59q90 0 133.5 48t43.5 130q0 85 -44 134.5t-155 97.5q-227 79 -340.5 179.5t-113.5 281.5q0 179 132 291.5t337 112.5q208 1 338 -125q126 -122 126 -306v-11l-2 -6h-276q0 100 -50 162t-141 62q-85 0 -132.5 -51.5t-47.5 -129.5 q0 -72 53 -118.5t184 -103.5q207 -70 311.5 -177.5t104.5 -290.5q0 -189 -126 -296t-335 -107q-208 -1 -360 121q-148 118 -148 335v14z" />
+<glyph unicode="T" horiz-adv-x="994" d="M29 1228v228h938v-228h-328v-1228h-284v1228h-326z" />
+<glyph unicode="U" horiz-adv-x="1176" d="M94 465v991h284v-991q0 -133 55 -196t155 -63q103 0 157 60t54 199v991h283v-991q0 -233 -136.5 -359.5t-357.5 -126.5t-357.5 127t-136.5 359z" />
+<glyph unicode="V" horiz-adv-x="1129" d="M9 1456h299l241 -1084l11 -56h6l11 53l243 1087h299l-407 -1456h-296z" />
+<glyph unicode="W" horiz-adv-x="1548" d="M21 1456h276l157 -929h6l210 929h204l213 -929h6l157 929h276l-281 -1456h-265l-205 892h-6l-203 -892h-264z" />
+<glyph unicode="X" horiz-adv-x="1127" d="M27 0l362 734l-353 722h327l195 -509h6l198 509h329l-353 -722l377 -734h-343l-204 520h-6l-204 -520h-331z" />
+<glyph unicode="Y" horiz-adv-x="1124" d="M7 1456h311l240 -624h6l243 624h309l-416 -938v-518h-284v536z" />
+<glyph unicode="Z" horiz-adv-x="998" d="M60 1229v227h876v-138l-550 -1091h559v-227h-879v143l546 1086h-552z" />
+<glyph unicode="[" horiz-adv-x="530" d="M106 -339v2034h399v-217h-112v-1601h112v-216h-399z" />
+<glyph unicode="\" horiz-adv-x="758" d="M0 1456h280l515 -1581h-282z" />
+<glyph unicode="]" horiz-adv-x="530" d="M21 -123h114v1601h-114v217h399v-2034h-399v216z" />
+<glyph unicode="^" horiz-adv-x="785" d="M38 729l253 727h206l253 -727h-219l-134 422l-2 8h-6l-1 -8l-131 -422h-219z" />
+<glyph unicode="_" horiz-adv-x="793" d="M8 0h775v-220h-775v220z" />
+<glyph unicode="`" horiz-adv-x="629" d="M73 1471l3 6h298l175 -266h-230z" />
+<glyph unicode="a" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6v12q1 133 105 228q110 99 288 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5 t-133.5 -39.5q-134 0 -214.5 88t-80.5 235zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107q-65 0 -94 -45t-29 -114z" />
+<glyph unicode="b" d="M92 0v1560h284v-570q38 54 89.5 83t116.5 29q176 0 267 -135.5t91 -361.5v-147q0 -219 -90.5 -349t-265.5 -130q-76 0 -132.5 35t-96.5 102l-17 -116h-246zM376 281q20 -37 53.5 -55.5t80.5 -18.5q86 0 116.5 63.5t30.5 187.5v147q0 127 -31.5 198t-116.5 71 q-46 0 -79 -23t-54 -65v-505z" />
+<glyph unicode="c" horiz-adv-x="910" d="M52 470v139q0 216 112 354.5t321 138.5q175 0 279 -113q101 -110 101 -294v-11l-2 -5h-259q0 88 -29.5 141.5t-89.5 53.5q-85 0 -117 -72t-32 -193v-139q0 -124 32 -194t119 -70q58 0 87.5 43t29.5 124h258l3 -6v-9q-1 -164 -105 -270q-108 -109 -273 -109 q-210 0 -322.5 137t-112.5 354z" />
+<glyph unicode="d" d="M54 514v21q0 255 94 411t265 156q63 0 114 -30t91 -86v574h284v-1560h-247l-19 118q-42 -68 -97.5 -103.5t-126.5 -35.5q-171 0 -264.5 146.5t-93.5 388.5zM338 514q0 -145 33.5 -226t113.5 -81q44 0 77 20.5t56 59.5v492q-23 45 -56 70t-75 25q-79 0 -114 -93t-35 -246 v-21z" />
+<glyph unicode="e" horiz-adv-x="938" d="M69 451v152q0 219 111.5 359t308.5 140q190 0 294 -127t104 -346v-174h-535v-4q0 -107 48.5 -176t146.5 -69q80 0 130 18t119 60l72 -181q-56 -54 -149.5 -89t-205.5 -35q-204 0 -324 134t-120 338zM353 645h255v40q0 90 -28 139.5t-91 49.5q-68 0 -100 -62t-36 -167z " />
+<glyph unicode="f" horiz-adv-x="647" d="M23 876v206h133v120q0 182 94 280.5t264 98.5q33 0 66 -5.5t76 -15.5l-24 -218q-20 4 -38.5 7t-43.5 3q-54 0 -82 -39t-28 -111v-120h174v-206h-174v-876h-284v876h-133z" />
+<glyph unicode="g" horiz-adv-x="994" d="M54 458v133q0 229 94.5 370t266.5 141q72 0 127 -36.5t96 -104.5l18 121h247v-1061q0 -213 -123.5 -335.5t-338.5 -122.5q-70 0 -149 22.5t-147 60.5l50 219q57 -32 116 -48t128 -16q90 0 135 56.5t45 164.5v62q-40 -52 -91 -78.5t-115 -26.5q-171 0 -265 131.5 t-94 347.5zM338 458q0 -118 34 -184.5t114 -66.5q44 0 77.5 18t55.5 53v512q-22 40 -54.5 62t-76.5 22q-80 0 -115 -77.5t-35 -205.5v-133z" />
+<glyph unicode="h" d="M84 0v1560h284v-607q42 71 101 110t130 39q144 0 226 -114.5t82 -353.5v-634h-285v636q0 134 -31.5 186t-98.5 52q-40 0 -71 -17.5t-53 -48.5v-808h-284z" />
+<glyph unicode="i" horiz-adv-x="495" d="M105 0v1082h284v-1082h-284zM105 1343v217h284v-217h-284z" />
+<glyph unicode="j" horiz-adv-x="487" d="M-73 -419l12 223q22 -6 40 -9t40 -3q44 0 67.5 44t23.5 131v1115h285v-1115q0 -194 -90 -299t-250 -105q-35 0 -64 4.5t-64 13.5zM105 1343v217h284v-217h-284z" />
+<glyph unicode="k" horiz-adv-x="963" d="M92 0v1560h284v-886h47l183 408h327l-282 -487l329 -595h-325l-227 450h-52v-450h-284z" />
+<glyph unicode="l" horiz-adv-x="495" d="M105 0v1560h284v-1560h-284z" />
+<glyph unicode="m" horiz-adv-x="1507" d="M93 0v1082h265l11 -138q43 76 108 117t149 41q82 0 143 -43.5t93 -132.5q42 84 108 130t154 46q134 0 211.5 -110.5t77.5 -337.5v-654h-285v654q0 125 -27 172.5t-84 47.5q-41 0 -73 -24t-53 -66q1 -19 2 -37.5t1 -38.5v-708h-283v654q0 124 -27.5 172t-85.5 48 q-39 0 -69.5 -19.5t-52.5 -54.5v-800h-283z" />
+<glyph unicode="n" d="M87 0v1082h265l12 -149q45 80 110.5 124.5t144.5 44.5q135 0 212.5 -104t77.5 -327v-671h-285v671q0 112 -31.5 157.5t-97.5 45.5q-38 0 -70 -20t-54 -55v-799h-284z" />
+<glyph unicode="o" d="M58 473v134q0 218 115.5 356.5t323.5 138.5t324 -138.5t116 -356.5v-134q0 -220 -116 -357t-323 -137q-209 0 -324.5 137t-115.5 357zM341 473q0 -125 35 -196t122 -71q84 0 119.5 71.5t35.5 195.5v134q0 122 -35.5 194.5t-120.5 72.5t-120.5 -73t-35.5 -194v-134z" />
+<glyph unicode="p" d="M92 -416v1498h263l10 -107q39 61 92.5 94t123.5 33q171 0 265 -140.5t94 -370.5v-133q0 -216 -94 -347.5t-263 -131.5q-66 0 -117.5 26.5t-89.5 78.5v-500h-284zM376 278q20 -36 52.5 -54t79.5 -18q79 0 113.5 67t34.5 185v133q0 128 -36 205.5t-113 77.5 q-45 0 -78 -22.5t-53 -63.5v-510z" />
+<glyph unicode="q" d="M54 458v133q0 229 94 370t265 141q71 0 125.5 -35.5t95.5 -101.5l20 117h247v-1498h-285v499q-39 -51 -89.5 -77.5t-114.5 -26.5q-170 0 -264 131.5t-94 347.5zM338 458q0 -119 33.5 -185.5t113.5 -66.5q44 0 77 18t54 53v515q-21 39 -53 60.5t-76 21.5q-79 0 -114 -77.5 t-35 -205.5v-133z" />
+<glyph unicode="r" horiz-adv-x="655" d="M92 0v1082h265l11 -145l5 -2q26 78 72.5 122.5t108.5 44.5q19 0 40.5 -3.5t37.5 -8.5l-29 -267l-107 3q-45 0 -74.5 -22t-45.5 -62v-742h-284z" />
+<glyph unicode="s" horiz-adv-x="888" d="M39 334l2 6h260q2 -86 40 -124t105 -38q57 0 87 28t30 77q0 46 -36 79.5t-138 82.5q-163 61 -244.5 138t-81.5 200q0 132 104.5 225.5t276.5 93.5q180 0 287 -96q103 -93 103 -234v-11l-3 -6h-274q0 68 -28 108t-86 40q-46 0 -78 -31t-32 -75q0 -48 32 -77.5t139 -80.5 q170 -58 252 -137.5t82 -208.5q0 -138 -110 -226t-289 -88q-187 0 -296 109q-104 104 -104 234v12z" />
+<glyph unicode="t" horiz-adv-x="648" d="M18 876v206h128v269h284v-269h150v-206h-150v-543q0 -66 19 -94.5t52 -28.5q26 0 44 2.5t40 8.5l22 -216q-45 -14 -86 -20t-93 -6q-137 0 -209.5 84.5t-72.5 268.5v544h-128z" />
+<glyph unicode="u" d="M85 428v654h284v-656q0 -115 28 -167t83 -52q47 0 82.5 17.5t60.5 51.5v806h285v-1082h-250l-17 125q-44 -71 -106.5 -108.5t-141.5 -37.5q-145 0 -226.5 109.5t-81.5 339.5z" />
+<glyph unicode="v" horiz-adv-x="909" d="M15 1082h297l127 -674l13 -82h6l14 82l125 674h297l-300 -1082h-278z" />
+<glyph unicode="w" horiz-adv-x="1280" d="M24 1082h265l101 -616h6l151 616h184l151 -614l6 1l101 613h263l-222 -1082h-237l-151 583h-6l-151 -583h-237z" />
+<glyph unicode="x" horiz-adv-x="909" d="M16 0l275 547l-268 535h319l109 -341h6l114 341h320l-268 -535l276 -547h-319l-119 351h-6l-119 -351h-320z" />
+<glyph unicode="y" horiz-adv-x="909" d="M5 1082h305l130 -638l2 -11l158 649h304l-365 -1245q-41 -117 -109.5 -195.5t-209.5 -78.5q-35 0 -62 6t-72 18l33 212q17 -3 24.5 -4.5t16.5 -1.5q62 0 93.5 32.5t45.5 85.5l25 80z" />
+<glyph unicode="z" horiz-adv-x="883" d="M65 0v169l412 685h-400v228h730v-165l-416 -690h423v-227h-749z" />
+<glyph unicode="{" horiz-adv-x="586" d="M44 514v202q69 0 103 55t34 154v207q0 171 71 290.5t238 174.5l53 -157q-62 -31 -86 -109.5t-24 -198.5v-207q0 -104 -41 -184.5t-124 -125.5q82 -46 123.5 -126.5t41.5 -183.5v-206q0 -120 23.5 -198t86.5 -109l-53 -158q-167 55 -238 175t-71 290v206q0 98 -34 153.5 t-103 55.5z" />
+<glyph unicode="|" horiz-adv-x="467" d="M153 -270v1726h163v-1726h-163z" />
+<glyph unicode="}" horiz-adv-x="586" d="M42 -208q62 31 87 109t25 198v206q0 104 41 184.5t126 125.5q-85 44 -126 124.5t-41 185.5v207q0 120 -25 198.5t-87 109.5l53 157q166 -55 237.5 -174.5t71.5 -290.5v-207q0 -100 33.5 -154.5t105.5 -54.5v-202q-72 0 -105.5 -55t-33.5 -154v-206q0 -170 -71.5 -290 t-237.5 -175z" />
+<glyph unicode="~" horiz-adv-x="1121" d="M89 444q0 165 74.5 273t193.5 108q69 0 132.5 -33.5t125.5 -98.5q37 -46 66 -65.5t63 -19.5q37 0 64.5 52.5t27.5 128.5l194 -28q0 -164 -76.5 -273.5t-193.5 -109.5q-71 0 -131.5 32t-124.5 102q-40 45 -68 64.5t-63 19.5q-38 0 -64.5 -51.5t-26.5 -126.5z" />
+<glyph unicode="&#xa1;" horiz-adv-x="534" d="M125 -374v949h285v-949h-285zM128 821v261h280v-261h-280z" />
+<glyph unicode="&#xa2;" horiz-adv-x="1031" d="M89 470v139q0 189 87.5 321t252.5 163v225h184v-225q136 -29 215 -137.5t79 -276.5h-266q0 88 -29.5 141.5t-89.5 53.5q-85 0 -117 -72t-32 -193v-139q0 -124 32 -194t119 -70q58 0 87.5 43t29.5 124h266q0 -149 -81 -252.5t-213 -131.5v-234h-184v233q-166 30 -253 161 t-87 321z" />
+<glyph unicode="&#xa3;" horiz-adv-x="1055" d="M92 591v225h122l-7 209q0 211 105 331.5t282 120.5q188 0 293 -113t102 -297l-3 -6h-276q0 96 -34 142t-83 46q-48 0 -74.5 -58.5t-26.5 -165.5l8 -209h280v-225h-270l3 -82q0 -78 -29.5 -151t-83.5 -131h600v-227h-855v227h8q36 12 54 94.5t18 171.5l-3 98h-130z" />
+<glyph unicode="&#xa4;" horiz-adv-x="1257" d="M74 110l122 140q-45 76 -68.5 167t-23.5 191q0 103 25.5 196.5t73.5 172.5l-129 150l130 137l123 -142q65 54 142.5 83t161.5 29t161.5 -30t143.5 -84l125 145l132 -138l-133 -153q46 -78 71.5 -171.5t25.5 -194.5q0 -99 -23.5 -189t-66.5 -166l126 -143l-132 -137 l-114 131q-67 -60 -147.5 -92t-168.5 -32t-168 31.5t-147 90.5l-112 -128zM276 608q0 -189 103 -318.5t252 -129.5q147 0 250 129.5t103 318.5q0 187 -103 316.5t-250 129.5q-149 0 -252 -129.5t-103 -316.5z" />
+<glyph unicode="&#xa5;" horiz-adv-x="1082" d="M22 1456h310l207 -561h6l206 561h310l-318 -719h189v-200h-253v-111h253v-198h-253v-228h-283v228h-271v198h271v111h-271v200h215z" />
+<glyph unicode="&#xa6;" horiz-adv-x="467" d="M108 -270v791h251v-791h-251zM108 698v758h251v-758h-251z" />
+<glyph unicode="&#xa7;" horiz-adv-x="1115" d="M84 533q0 88 36.5 156.5t106.5 113.5q-63 51 -94.5 122t-31.5 171q0 172 123 276.5t329 104.5q210 0 329 -111.5t115 -310.5l-2 -6h-276q0 87 -43.5 143.5t-122.5 56.5q-84 0 -125 -42.5t-41 -108.5q0 -74 43 -112.5t181 -85.5q210 -63 309 -155.5t99 -262.5 q0 -90 -37 -157.5t-105 -110.5q62 -51 93.5 -122t31.5 -171q0 -177 -121.5 -277t-326.5 -100q-201 0 -335 99t-129 317l2 6h276q0 -105 52.5 -149.5t133.5 -44.5q78 0 121 40.5t43 107.5q0 66 -47.5 106t-180.5 89q-208 64 -307 156.5t-99 261.5zM368 564q0 -80 41.5 -121 t177.5 -94q57 -19 67 -22.5l30 -10.5q27 23 41.5 58t14.5 79q0 71 -47.5 116t-177.5 97q-25 7 -49.5 16t-49.5 19q-25 -23 -36.5 -58t-11.5 -79z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1000" d="M143 1258v198h251v-198h-251zM592 1258v198h250v-198h-250z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1433" d="M82 729q0 315 182.5 531t444.5 216q261 0 444.5 -216t183.5 -531q0 -316 -184 -533t-444 -217q-261 0 -444 217t-183 533zM193 729q0 -266 150.5 -448.5t365.5 -181.5q214 -1 364.5 181.5t150.5 448.5q0 264 -150.5 445.5t-364.5 181.5q-215 0 -365.5 -181.5 t-150.5 -445.5zM386 669v119q0 173 83.5 280t226.5 107q140 0 219 -79.5t76 -228.5l-3 -6h-136q0 96 -39 140.5t-117 45.5q-81 -1 -124 -72t-43 -186v-120q0 -118 43 -188.5t124 -70.5q78 0 116.5 43.5t38.5 142.5h136l3 -6q3 -151 -75.5 -229.5t-218.5 -78.5 q-143 0 -226.5 106t-83.5 281z" />
+<glyph unicode="&#xaa;" horiz-adv-x="785" d="M98 920q0 109 72.5 169t212.5 60h106v53q0 65 -22.5 99.5t-66.5 34.5q-51 0 -79 -27.5t-28 -78.5l-150 13l-2 6q-5 98 67.5 163t191.5 65q114 0 182 -71.5t68 -204.5v-314q0 -51 5 -95t17 -86h-162q-7 23 -11.5 47t-6.5 48q-27 -48 -73 -78.5t-110 -30.5 q-100 0 -155.5 61.5t-55.5 166.5zM258 924q0 -46 22.5 -70.5t68.5 -24.5q39 0 82 30t58 66v112h-105q-59 0 -92.5 -33.5t-33.5 -79.5z" />
+<glyph unicode="&#xab;" horiz-adv-x="904" d="M55 507v19l233 389h176l-195 -399l195 -397h-176zM407 507v19l233 389h176l-195 -399l195 -397h-176z" />
+<glyph unicode="&#xac;" horiz-adv-x="972" d="M115 638v163h710v-426h-183v263h-527z" />
+<glyph unicode="&#xad;" horiz-adv-x="748" d="M120 511v228h497v-228h-497z" />
+<glyph unicode="&#xae;" horiz-adv-x="1433" d="M82 729q0 315 183 531t445 216q260 0 443.5 -216t183.5 -531q0 -316 -183.5 -533t-443.5 -217q-262 0 -445 217t-183 533zM194 729q0 -266 150.5 -448.5t365.5 -181.5q214 -1 364 181.5t150 448.5q0 264 -150 445.5t-364 181.5q-215 0 -365.5 -181.5t-150.5 -445.5z M445 316v850h251q134 0 212 -68t78 -193q0 -58 -26 -101.5t-76 -74.5q53 -30 77 -84.5t24 -129.5v-56q0 -42 3 -74t11 -53v-16h-143q-8 21 -9.5 61.5t-1.5 82.5v54q0 73 -29.5 107t-94.5 34h-136v-339h-140zM585 783h112q64 0 107.5 31.5t43.5 89.5q0 74 -34 104t-118 30 h-111v-255z" />
+<glyph unicode="&#xaf;" horiz-adv-x="949" d="M146 1297v160h654v-160h-654z" />
+<glyph unicode="&#xb0;" horiz-adv-x="725" d="M117 1203q0 112 72.5 193t173.5 81q99 0 170.5 -81t71.5 -193q0 -113 -71 -192t-171 -79q-102 0 -174 79t-72 192zM255 1203q0 -55 31.5 -92t76.5 -37q43 0 73.5 36.5t30.5 92.5t-30.5 94t-73.5 38q-45 0 -76.5 -38.5t-31.5 -93.5z" />
+<glyph unicode="&#xb1;" horiz-adv-x="992" d="M87 721v235h281v361h250v-361h279v-235h-279v-382h-250v382h-281zM98 7v230h705v-230h-705z" />
+<glyph unicode="&#xb2;" horiz-adv-x="748" d="M100 1221q-5 107 71.5 182.5t205.5 75.5q126 0 194.5 -64.5t68.5 -182.5q0 -83 -48.5 -149t-155.5 -163l-79 -96l2 -5h286v-152h-539v152l262 254q47 49 60 82.5t13 77.5q0 41 -16.5 67t-53.5 26q-40 0 -59.5 -30.5t-19.5 -80.5h-190z" />
+<glyph unicode="&#xb3;" horiz-adv-x="740" d="M85 895l2 6h191q0 -44 23 -69t69 -25q39 0 64.5 24.5t25.5 70.5q0 51 -27.5 79t-78.5 28h-91v127h91q48 0 70.5 25t22.5 73q0 39 -20.5 65t-60.5 26q-39 0 -58.5 -22.5t-19.5 -55.5h-189l-2 6q-6 102 70.5 163.5t193.5 61.5q131 0 208 -59.5t77 -169.5 q0 -55 -30.5 -100.5t-83.5 -71.5q60 -24 93 -71.5t33 -115.5q0 -112 -77 -173.5t-209 -61.5q-130 0 -211.5 63t-75.5 177z" />
+<glyph unicode="&#xb4;" horiz-adv-x="683" d="M100 1212l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xb5;" horiz-adv-x="1113" d="M120 -416v1498h285v-637q1 -137 33.5 -186.5t100.5 -49.5q52 0 88.5 24t59.5 70v779h284v-1082h-267l-4 51q-35 -36 -78 -54t-93 -18q-36 0 -67 9t-57 26v-430h-285z" />
+<glyph unicode="&#xb6;" horiz-adv-x="951" d="M56 988q0 207 109.5 337.5t306.5 130.5h351v-1456h-286v520h-65q-197 0 -306.5 129.5t-109.5 338.5z" />
+<glyph unicode="&#xb7;" horiz-adv-x="566" d="M140 560v262h278v-262h-278z" />
+<glyph unicode="&#xb8;" horiz-adv-x="493" d="M83 -134l27 141h213l-9 -59q51 -11 86.5 -52.5t35.5 -120.5q0 -108 -80.5 -172.5t-227.5 -64.5l-6 163q34 0 53.5 20.5t19.5 63.5q0 42 -25.5 59t-86.5 22z" />
+<glyph unicode="&#xb9;" horiz-adv-x="513" d="M102 1298v156l303 23v-812h-200v634z" />
+<glyph unicode="&#xba;" horiz-adv-x="811" d="M104 1027v115q0 148 81 241.5t217 93.5t216.5 -93.5t80.5 -241.5v-115q0 -150 -80.5 -242.5t-215.5 -92.5q-137 0 -218 92.5t-81 242.5zM265 1027q0 -89 35 -142.5t103 -53.5q65 0 100 53.5t35 142.5v115q0 85 -35 139.5t-101 54.5q-67 0 -102 -54.5t-35 -139.5v-115z " />
+<glyph unicode="&#xbb;" horiz-adv-x="905" d="M60 152l195 398l-195 399h176l233 -389v-19l-233 -389h-176zM422 152l195 398l-195 399h176l233 -389v-19l-233 -389h-176z" />
+<glyph unicode="&#xbc;" horiz-adv-x="1260" d="M99 1297v156l303 23v-812h-200v634zM199 192l601 1138l134 -74l-601 -1138zM593 264l356 534v3h200v-507h75v-154h-75v-140h-200v140h-343zM794 294h155v253l-6 2l-7 -12z" />
+<glyph unicode="&#xbd;" horiz-adv-x="1317" d="M82 1297v156l303 23v-812h-200v634zM192 192l601 1138l134 -74l-601 -1138zM693 554q-5 107 71.5 182.5t205.5 75.5q126 0 194.5 -64.5t68.5 -182.5q0 -83 -48.5 -149t-155.5 -163l-79 -96l2 -5h286v-152h-539v152l262 254q47 49 60 82.5t13 77.5q0 41 -16.5 67t-53.5 26 q-40 0 -59.5 -30.5t-19.5 -80.5h-190z" />
+<glyph unicode="&#xbe;" horiz-adv-x="1452" d="M71 896l2 6h191q0 -44 23 -69t69 -25q39 0 64.5 24.5t25.5 70.5q0 51 -27.5 79t-78.5 28h-91v127h91q48 0 70.5 25t22.5 73q0 39 -20.5 65t-60.5 26q-39 0 -58.5 -22.5t-19.5 -55.5h-189l-2 6q-6 102 70.5 163.5t193.5 61.5q131 0 208 -59.5t77 -169.5 q0 -55 -30.5 -100.5t-83.5 -71.5q60 -24 93 -71.5t33 -115.5q0 -112 -77 -173.5t-209 -61.5q-130 0 -211.5 63t-75.5 177zM384 192l601 1138l134 -74l-601 -1138zM747 264l356 534v3h200v-507h75v-154h-75v-140h-200v140h-343zM948 294h155v253l-6 2l-7 -12z" />
+<glyph unicode="&#xbf;" horiz-adv-x="909" d="M63 32q0 125 62.5 231t159.5 179q51 44 69 92.5t18 133.5h284q-2 -137 -41 -203t-147 -158q-57 -57 -89.5 -123t-32.5 -151q0 -91 37 -144.5t107 -53.5q52 0 91.5 46t41.5 131h277l2 -6q1 -196 -113.5 -298t-298.5 -102q-200 0 -313.5 115t-113.5 311zM373 834v248h283 v-248h-283z" />
+<glyph unicode="&#xc0;" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM243 1819l3 6h298l175 -266h-230zM439 538h268l-131 515h-6z" />
+<glyph unicode="&#xc1;" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM429 1560l176 266h299l3 -6l-249 -260h-229zM439 538h268l-131 515h-6z" />
+<glyph unicode="&#xc2;" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM244 1591v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217zM439 538h268l-131 515h-6z" />
+<glyph unicode="&#xc3;" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM248 1645q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45q0 -95 -51 -161.5t-130 -66.5q-59 0 -136.5 44t-121.5 44q-27 0 -46 -33t-19 -79zM439 538h268l-131 515 h-6z" />
+<glyph unicode="&#xc4;" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM224 1606v198h251v-198h-251zM439 538h268l-131 515h-6zM673 1606v198h250v-198h-250z" />
+<glyph unicode="&#xc5;" horiz-adv-x="1134" d="M16 0l410 1456h296l409 -1456h-287l-79 309h-384l-78 -309h-287zM381 1739q0 80 56 135t138 55q80 0 135 -55t55 -135q0 -82 -54.5 -134t-135.5 -52q-82 0 -138 52.5t-56 133.5zM439 538h268l-131 515h-6zM489 1739q0 -42 24 -68.5t62 -26.5q37 0 60 26t23 69t-23 70 t-60 27q-38 0 -62 -27t-24 -70z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1656" d="M9 0l639 1456h891v-231h-481l12 -363h400v-230h-392l15 -402h498v-230h-774l-12 339h-329l-136 -339h-331zM573 578h224l-17 497l-6 1z" />
+<glyph unicode="&#xc7;" horiz-adv-x="1088" d="M74 510v435q0 253 130.5 392.5t349.5 139.5q232 0 350.5 -124t122.5 -367l-3 -6h-274q6 143 -39 206t-157 63q-96 0 -147 -75t-51 -227v-437q0 -154 54.5 -229t159.5 -75q103 0 143.5 59.5t35.5 203.5h274l3 -6q2 -240 -114 -362t-342 -122t-361 138.5t-135 392.5z M414 -134l27 141h213l-9 -59q51 -11 86.5 -52.5t35.5 -120.5q0 -108 -80.5 -172.5t-227.5 -64.5l-6 163q34 0 53.5 20.5t19.5 63.5q0 42 -25.5 59t-86.5 22z" />
+<glyph unicode="&#xc8;" horiz-adv-x="1008" d="M110 0v1456h858v-228h-573v-362h489v-227h-489v-412h575v-227h-860zM183 1819l3 6h298l175 -266h-230z" />
+<glyph unicode="&#xc9;" horiz-adv-x="1008" d="M110 0v1456h858v-228h-573v-362h489v-227h-489v-412h575v-227h-860zM369 1560l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xca;" horiz-adv-x="1008" d="M110 0v1456h858v-228h-573v-362h489v-227h-489v-412h575v-227h-860zM184 1591v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217z" />
+<glyph unicode="&#xcb;" horiz-adv-x="1008" d="M110 0v1456h858v-228h-573v-362h489v-227h-489v-412h575v-227h-860zM164 1606v198h251v-198h-251zM613 1606v198h250v-198h-250z" />
+<glyph unicode="&#xcc;" horiz-adv-x="534" d="M-61 1819l3 6h298l175 -266h-230zM125 0v1456h283v-1456h-283z" />
+<glyph unicode="&#xcd;" horiz-adv-x="534" d="M123 1560l176 266h299l3 -6l-249 -260h-229zM125 0v1456h283v-1456h-283z" />
+<glyph unicode="&#xce;" horiz-adv-x="534" d="M-60 1591v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217zM125 0v1456h283v-1456h-283z" />
+<glyph unicode="&#xcf;" horiz-adv-x="534" d="M-80 1606v198h251v-198h-251zM125 0v1456h283v-1456h-283zM369 1606v198h250v-198h-250z" />
+<glyph unicode="&#xd0;" horiz-adv-x="1181" d="M31 655v175h109v626h440q224 0 370 -169.5t146 -436.5v-245q0 -267 -146 -436t-370 -169h-440v655h-109zM425 227h139q119 0 183.5 103.5t64.5 274.5v247q0 170 -64.5 273t-183.5 103h-139v-398h187v-175h-187v-428z" />
+<glyph unicode="&#xd1;" horiz-adv-x="1241" d="M110 0v1456h285l445 -930l6 2v928h283v-1456h-283l-445 931l-6 -2v-929h-285zM294 1645q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45q0 -95 -51 -161.5t-130 -66.5q-59 0 -136.5 44t-121.5 44q-27 0 -46 -33t-19 -79z" />
+<glyph unicode="&#xd2;" horiz-adv-x="1166" d="M75 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -256 -139 -400t-370 -144t-369 144t-138 400zM253 1840l3 6h298l175 -266h-230zM357 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5t-169 79.5q-112 0 -168 -79t-56 -236 v-410z" />
+<glyph unicode="&#xd3;" horiz-adv-x="1166" d="M75 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -256 -139 -400t-370 -144t-369 144t-138 400zM357 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5t-169 79.5q-112 0 -168 -79t-56 -236v-410zM439 1581l176 266h299l3 -6 l-249 -260h-229z" />
+<glyph unicode="&#xd4;" horiz-adv-x="1166" d="M75 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -256 -139 -400t-370 -144t-369 144t-138 400zM254 1612v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217zM357 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5 t-169 79.5q-112 0 -168 -79t-56 -236v-410z" />
+<glyph unicode="&#xd5;" horiz-adv-x="1166" d="M75 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -256 -139 -400t-370 -144t-369 144t-138 400zM258 1666q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45q0 -95 -51 -161.5t-130 -66.5q-59 0 -136.5 44 t-121.5 44q-27 0 -46 -33t-19 -79zM357 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5t-169 79.5q-112 0 -168 -79t-56 -236v-410z" />
+<glyph unicode="&#xd6;" horiz-adv-x="1166" d="M75 523v408q0 255 138 400.5t368 145.5t370 -145.5t140 -400.5v-408q0 -256 -139 -400t-370 -144t-369 144t-138 400zM234 1627v198h251v-198h-251zM357 523q0 -158 57 -237t168 -79q110 0 168 79t58 237v410q0 156 -58 235.5t-169 79.5q-112 0 -168 -79t-56 -236v-410z M683 1627v198h250v-198h-250z" />
+<glyph unicode="&#xd7;" horiz-adv-x="978" d="M57 1000l167 163l262 -302l262 302l166 -163l-275 -316l274 -315l-167 -163l-261 300l-260 -300l-165 163l272 314z" />
+<glyph unicode="&#xd8;" horiz-adv-x="1215" d="M81 523v408q0 255 138 400.5t368 145.5q90 0 168.5 -24t141.5 -69l65 132h129l-106 -216q54 -71 83 -164t29 -205v-408q0 -256 -139 -400t-370 -144q-63 0 -120.5 11t-107.5 34l-57 -117h-127l86 176q-87 70 -134 181.5t-47 258.5zM363 523q0 -54 6 -97.5t19 -70.5l6 -1 l382 781q-28 56 -75.5 84.5t-113.5 28.5q-112 0 -168 -79t-56 -236v-410zM466 241q24 -18 54.5 -26t67.5 -8q110 0 168 79t58 237v410v4l-6 1z" />
+<glyph unicode="&#xd9;" horiz-adv-x="1176" d="M94 465v991h284v-991q0 -133 55 -196t155 -63q103 0 157 60t54 199v991h283v-991q0 -233 -136.5 -359.5t-357.5 -126.5t-357.5 127t-136.5 359zM256 1819l3 6h298l175 -266h-230z" />
+<glyph unicode="&#xda;" horiz-adv-x="1176" d="M94 465v991h284v-991q0 -133 55 -196t155 -63q103 0 157 60t54 199v991h283v-991q0 -233 -136.5 -359.5t-357.5 -126.5t-357.5 127t-136.5 359zM442 1560l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xdb;" horiz-adv-x="1176" d="M94 465v991h284v-991q0 -133 55 -196t155 -63q103 0 157 60t54 199v991h283v-991q0 -233 -136.5 -359.5t-357.5 -126.5t-357.5 127t-136.5 359zM257 1591v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217z" />
+<glyph unicode="&#xdc;" horiz-adv-x="1176" d="M94 465v991h284v-991q0 -133 55 -196t155 -63q103 0 157 60t54 199v991h283v-991q0 -233 -136.5 -359.5t-357.5 -126.5t-357.5 127t-136.5 359zM237 1606v198h251v-198h-251zM686 1606v198h250v-198h-250z" />
+<glyph unicode="&#xdd;" horiz-adv-x="1124" d="M7 1456h311l240 -624h6l243 624h309l-416 -938v-518h-284v536zM425 1559l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xde;" horiz-adv-x="1079" d="M108 0v1456h285v-268h165q223 0 346.5 -124t123.5 -326q0 -203 -123.5 -326.5t-346.5 -123.5h-165v-288h-285zM393 515h165q94 0 139.5 63t45.5 158q0 96 -46 160.5t-139 64.5h-163l-2 2v-448z" />
+<glyph unicode="&#xdf;" horiz-adv-x="1132" d="M119 0v1104q0 223 114 344t315 121q161 0 268 -96t107 -269q0 -105 -42.5 -200.5t-42.5 -168.5q0 -53 118.5 -194t118.5 -282q0 -192 -98.5 -286t-296.5 -94q-66 0 -131 15t-98 40l50 224q32 -23 77 -38t100 -15q53 0 84 38t31 105q0 71 -120 203.5t-120 272.5 q0 94 44 192t44 174q0 63 -35.5 108t-80.5 45q-54 0 -88.5 -65.5t-34.5 -177.5v-1100h-283z" />
+<glyph unicode="&#xe0;" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6q-5 141 104.5 240t288.5 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5t-133.5 -39.5 q-134 0 -214.5 88t-80.5 235zM136 1497l3 6h298l175 -266h-230zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107q-65 0 -94 -45t-29 -114z" />
+<glyph unicode="&#xe1;" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6q-5 141 104.5 240t288.5 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5t-133.5 -39.5 q-134 0 -214.5 88t-80.5 235zM322 1238l176 266h299l3 -6l-249 -260h-229zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107q-65 0 -94 -45t-29 -114z" />
+<glyph unicode="&#xe2;" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6q-5 141 104.5 240t288.5 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5t-133.5 -39.5 q-134 0 -214.5 88t-80.5 235zM137 1269v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107q-65 0 -94 -45t-29 -114z" />
+<glyph unicode="&#xe3;" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6q-5 141 104.5 240t288.5 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5t-133.5 -39.5 q-134 0 -214.5 88t-80.5 235zM141 1323q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45q0 -95 -51 -161.5t-130 -66.5q-59 0 -136.5 44t-121.5 44q-27 0 -46 -33t-19 -79zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107 q-65 0 -94 -45t-29 -114z" />
+<glyph unicode="&#xe4;" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6q-5 141 104.5 240t288.5 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5t-133.5 -39.5 q-134 0 -214.5 88t-80.5 235zM119 1284v198h251v-198h-251zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107q-65 0 -94 -45t-29 -114zM568 1284v198h250v-198h-250z" />
+<glyph unicode="&#xe5;" horiz-adv-x="944" d="M57 302q0 159 102.5 247t304.5 88h107v88q0 79 -28.5 121.5t-85.5 42.5q-48 0 -72 -34t-24 -99l-275 1l-3 6q-5 141 104.5 240t288.5 99q169 0 274.5 -98.5t105.5 -280.5v-438q0 -80 11 -149t34 -136h-282q-12 27 -21.5 59t-14.5 65q-40 -66 -97.5 -105.5t-133.5 -39.5 q-134 0 -214.5 88t-80.5 235zM274 1417q0 80 56 135t138 55q80 0 135 -55t55 -135q0 -82 -54.5 -134t-135.5 -52q-82 0 -138 52.5t-56 133.5zM341 315q0 -54 25 -88t68 -34t79.5 23t57.5 59v199h-107q-65 0 -94 -45t-29 -114zM382 1417q0 -42 24 -68.5t62 -26.5q37 0 60 26 t23 69t-23 70t-60 27q-38 0 -62 -27t-24 -70z" />
+<glyph unicode="&#xe6;" horiz-adv-x="1479" d="M41 317q0 159 110.5 245.5t322.5 86.5h136v56q0 79 -30 124t-83 45q-57 0 -89.5 -37t-32.5 -92l-275 17l-2 6q-5 145 106.5 239.5t295.5 94.5q83 0 153 -23.5t121 -68.5q51 44 118 68t149 24q181 0 285 -131t104 -356v-160h-535q5 -117 51.5 -183t144.5 -66 q77 0 127.5 18.5t115.5 59.5l71 -183q-53 -49 -147.5 -85.5t-200.5 -36.5q-108 0 -192 38t-142 110q-52 -65 -135.5 -106.5t-196.5 -41.5q-168 0 -259 90.5t-91 247.5zM324 313q0 -61 30 -95t92 -34q41 0 88 27t76 65v190h-134q-71 0 -111.5 -44.5t-40.5 -108.5zM896 644 h257v27q0 94 -28 148.5t-84 54.5q-73 0 -106 -60t-39 -170z" />
+<glyph unicode="&#xe7;" horiz-adv-x="910" d="M52 470v139q0 216 112 354.5t321 138.5q176 0 279.5 -113t100.5 -305l-2 -5h-259q0 88 -29.5 141.5t-89.5 53.5q-85 0 -117 -72t-32 -193v-139q0 -124 32 -194t119 -70q58 0 87.5 43t29.5 124h258l3 -6q3 -170 -104.5 -279t-273.5 -109q-210 0 -322.5 137t-112.5 354z M346 -134l27 141h213l-9 -59q51 -11 86.5 -52.5t35.5 -120.5q0 -108 -80.5 -172.5t-227.5 -64.5l-6 163q34 0 53.5 20.5t19.5 63.5q0 42 -25.5 59t-86.5 22z" />
+<glyph unicode="&#xe8;" horiz-adv-x="938" d="M69 451v152q0 219 111.5 359t308.5 140q190 0 294 -127t104 -346v-174h-535v-4q0 -107 48.5 -176t146.5 -69q80 0 130 18t119 60l72 -181q-56 -54 -149.5 -89t-205.5 -35q-204 0 -324 134t-120 338zM135 1498l3 6h298l175 -266h-230zM353 645h255v40q0 90 -28 139.5 t-91 49.5q-68 0 -100 -62t-36 -167z" />
+<glyph unicode="&#xe9;" horiz-adv-x="938" d="M69 451v152q0 219 111.5 359t308.5 140q190 0 294 -127t104 -346v-174h-535v-4q0 -107 48.5 -176t146.5 -69q80 0 130 18t119 60l72 -181q-56 -54 -149.5 -89t-205.5 -35q-204 0 -324 134t-120 338zM321 1239l176 266h299l3 -6l-249 -260h-229zM353 645h255v40 q0 90 -28 139.5t-91 49.5q-68 0 -100 -62t-36 -167z" />
+<glyph unicode="&#xea;" horiz-adv-x="938" d="M69 451v152q0 219 111.5 359t308.5 140q190 0 294 -127t104 -346v-174h-535v-4q0 -107 48.5 -176t146.5 -69q80 0 130 18t119 60l72 -181q-56 -54 -149.5 -89t-205.5 -35q-204 0 -324 134t-120 338zM136 1270v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217z M353 645h255v40q0 90 -28 139.5t-91 49.5q-68 0 -100 -62t-36 -167z" />
+<glyph unicode="&#xeb;" horiz-adv-x="938" d="M69 451v152q0 219 111.5 359t308.5 140q190 0 294 -127t104 -346v-174h-535v-4q0 -107 48.5 -176t146.5 -69q80 0 130 18t119 60l72 -181q-56 -54 -149.5 -89t-205.5 -35q-204 0 -324 134t-120 338zM118 1285v198h251v-198h-251zM353 645h255v40q0 90 -28 139.5t-91 49.5 q-68 0 -100 -62t-36 -167zM567 1285v198h250v-198h-250z" />
+<glyph unicode="&#xec;" horiz-adv-x="513" d="M-73 1476l3 6h298l175 -266h-230zM113 0v1082h285v-1082h-285z" />
+<glyph unicode="&#xed;" horiz-adv-x="513" d="M111 1217l176 266h299l3 -6l-249 -260h-229zM113 0v1082h285v-1082h-285z" />
+<glyph unicode="&#xee;" horiz-adv-x="513" d="M-72 1250v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217zM113 0v1082h285v-1082h-285z" />
+<glyph unicode="&#xef;" horiz-adv-x="513" d="M-92 1263v198h251v-198h-251zM113 0v1082h285v-1082h-285zM357 1263v198h250v-198h-250z" />
+<glyph unicode="&#xf0;" horiz-adv-x="1053" d="M38 466q0 227 113.5 362t313.5 135q59 0 112.5 -19t93.5 -52l4 4q-17 69 -47 130.5t-71 111.5l-181 -119l-72 111l155 101q-30 21 -62 38t-65 31l89 217q72 -21 138.5 -56t125.5 -83l173 112l70 -110l-147 -96q98 -117 152.5 -274.5t54.5 -345.5v-71q0 -270 -137.5 -442 t-342.5 -172q-208 0 -339 139.5t-131 347.5zM322 466q0 -111 51.5 -185.5t137.5 -74.5q90 0 141 108t51 279v70q-28 38 -76.5 62.5t-111.5 24.5q-93 0 -143 -77.5t-50 -206.5z" />
+<glyph unicode="&#xf1;" d="M87 0v1082h265l12 -149q45 80 110.5 124.5t144.5 44.5q135 0 212.5 -104t77.5 -327v-671h-285v671q0 112 -31.5 157.5t-97.5 45.5q-38 0 -70 -20t-54 -55v-799h-284zM170 1323q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45 q0 -95 -51 -161.5t-130 -66.5q-59 0 -136.5 44t-121.5 44q-27 0 -46 -33t-19 -79z" />
+<glyph unicode="&#xf2;" d="M58 473v134q0 218 115.5 356.5t323.5 138.5t324 -138.5t116 -356.5v-134q0 -220 -116 -357t-323 -137q-209 0 -324.5 137t-115.5 357zM165 1497l3 6h298l175 -266h-230zM341 473q0 -125 35 -196t122 -71q84 0 119.5 71.5t35.5 195.5v134q0 122 -35.5 194.5t-120.5 72.5 t-120.5 -73t-35.5 -194v-134z" />
+<glyph unicode="&#xf3;" d="M58 473v134q0 218 115.5 356.5t323.5 138.5t324 -138.5t116 -356.5v-134q0 -220 -116 -357t-323 -137q-209 0 -324.5 137t-115.5 357zM341 473q0 -125 35 -196t122 -71q84 0 119.5 71.5t35.5 195.5v134q0 122 -35.5 194.5t-120.5 72.5t-120.5 -73t-35.5 -194v-134z M351 1238l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xf4;" d="M58 473v134q0 218 115.5 356.5t323.5 138.5t324 -138.5t116 -356.5v-134q0 -220 -116 -357t-323 -137q-209 0 -324.5 137t-115.5 357zM166 1269v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217zM341 473q0 -125 35 -196t122 -71q84 0 119.5 71.5t35.5 195.5 v134q0 122 -35.5 194.5t-120.5 72.5t-120.5 -73t-35.5 -194v-134z" />
+<glyph unicode="&#xf5;" d="M58 473v134q0 218 115.5 356.5t323.5 138.5t324 -138.5t116 -356.5v-134q0 -220 -116 -357t-323 -137q-209 0 -324.5 137t-115.5 357zM170 1323q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45q0 -95 -51 -161.5t-130 -66.5 q-59 0 -136.5 44t-121.5 44q-27 0 -46 -33t-19 -79zM341 473q0 -125 35 -196t122 -71q84 0 119.5 71.5t35.5 195.5v134q0 122 -35.5 194.5t-120.5 72.5t-120.5 -73t-35.5 -194v-134z" />
+<glyph unicode="&#xf6;" d="M58 473v134q0 218 115.5 356.5t323.5 138.5t324 -138.5t116 -356.5v-134q0 -220 -116 -357t-323 -137q-209 0 -324.5 137t-115.5 357zM146 1284v198h251v-198h-251zM341 473q0 -125 35 -196t122 -71q84 0 119.5 71.5t35.5 195.5v134q0 122 -35.5 194.5t-120.5 72.5 t-120.5 -73t-35.5 -194v-134zM595 1284v198h250v-198h-250z" />
+<glyph unicode="&#xf7;" horiz-adv-x="1005" d="M59 577v221h878v-221h-878zM357 167v230h281v-230h-281zM357 971v230h281v-230h-281z" />
+<glyph unicode="&#xf8;" horiz-adv-x="997" d="M58 473v134q0 218 115.5 356.5t323.5 138.5q40 0 78 -6t73 -17l57 138h152l-85 -206q80 -66 122.5 -170.5t42.5 -233.5v-134q0 -220 -116 -357t-323 -137q-40 0 -75.5 5.5t-68.5 14.5l-58 -142h-151l85 206q-85 64 -128.5 170t-43.5 240zM341 473q0 -35 1.5 -62t6.5 -43 l6 -1l203 494q-14 6 -29.5 9.5t-31.5 3.5q-85 0 -120.5 -73t-35.5 -194v-134zM444 215q12 -5 25 -7t29 -2q84 0 119.5 71.5t35.5 195.5v134q0 27 -2 49.5t-4 36.5l-6 1z" />
+<glyph unicode="&#xf9;" d="M85 428v654h284v-656q0 -115 28 -167t83 -52q47 0 82.5 17.5t60.5 51.5v806h285v-1082h-250l-17 125q-44 -71 -106.5 -108.5t-141.5 -37.5q-145 0 -226.5 109.5t-81.5 339.5zM163 1476l3 6h298l175 -266h-230z" />
+<glyph unicode="&#xfa;" d="M85 428v654h284v-656q0 -115 28 -167t83 -52q47 0 82.5 17.5t60.5 51.5v806h285v-1082h-250l-17 125q-44 -71 -106.5 -108.5t-141.5 -37.5q-145 0 -226.5 109.5t-81.5 339.5zM349 1217l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xfb;" d="M85 428v654h284v-656q0 -115 28 -167t83 -52q47 0 82.5 17.5t60.5 51.5v806h285v-1082h-250l-17 125q-44 -71 -106.5 -108.5t-141.5 -37.5q-145 0 -226.5 109.5t-81.5 339.5zM164 1250v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217z" />
+<glyph unicode="&#xfc;" d="M85 428v654h284v-656q0 -115 28 -167t83 -52q47 0 82.5 17.5t60.5 51.5v806h285v-1082h-250l-17 125q-44 -71 -106.5 -108.5t-141.5 -37.5q-145 0 -226.5 109.5t-81.5 339.5zM144 1263v198h251v-198h-251zM593 1263v198h250v-198h-250z" />
+<glyph unicode="&#xfd;" horiz-adv-x="909" d="M5 1082h305l130 -638l2 -11l158 649h304l-365 -1245q-41 -117 -109.5 -195.5t-209.5 -78.5q-35 0 -62 6t-72 18l33 212q17 -3 24.5 -4.5t16.5 -1.5q62 0 93.5 32.5t45.5 85.5l25 80zM307 1217l176 266h299l3 -6l-249 -260h-229z" />
+<glyph unicode="&#xfe;" horiz-adv-x="999" d="M93 -416v1976h284v-570q38 54 89 83t116 29q171 0 265 -140.5t94 -370.5v-133q0 -216 -94 -347.5t-263 -131.5q-66 0 -117.5 26.5t-89.5 78.5v-500h-284zM377 277q20 -35 52.5 -53t79.5 -18q79 0 113.5 67t34.5 185v133q0 128 -36 205.5t-113 77.5q-45 0 -78 -22.5 t-53 -63.5v-511z" />
+<glyph unicode="&#xff;" horiz-adv-x="909" d="M5 1082h305l130 -638l2 -11l158 649h304l-365 -1245q-41 -117 -109.5 -195.5t-209.5 -78.5q-35 0 -62 6t-72 18l33 212q17 -3 24.5 -4.5t16.5 -1.5q62 0 93.5 32.5t45.5 85.5l25 80zM104 1263v198h251v-198h-251zM553 1263v198h250v-198h-250z" />
+<glyph unicode="&#x152;" horiz-adv-x="1709" d="M87 576v304q0 265 146 431t382 166q57 0 116.5 -6t124.5 -15h781v-228h-573v-362h489v-227h-489v-412h575v-227h-783q-76 -10 -130.5 -15.5t-109.5 -5.5q-235 0 -382 166t-147 431zM371 576q0 -179 65 -274.5t180 -95.5q41 0 82 3t81 10v1018q-41 6 -82 9.5t-82 3.5 q-116 0 -180 -95t-64 -273v-306z" />
+<glyph unicode="&#x153;" horiz-adv-x="1571" d="M75 529v22q0 244 115 397.5t323 153.5q92 0 168 -32.5t132 -92.5q53 60 125 92.5t160 32.5q190 0 294 -130.5t104 -355.5v-161h-532q8 -111 56.5 -180t135.5 -69q80 0 131 18t119 60l73 -181q-57 -54 -151 -89t-206 -35q-94 0 -171.5 33t-134.5 95q-56 -63 -132 -95.5 t-170 -32.5q-209 0 -324 152.5t-115 397.5zM359 529q0 -150 34.5 -236t117.5 -81h6q82 -5 117 81.5t35 235.5v22q0 146 -35.5 233.5t-117.5 83.5h-6q-82 4 -116.5 -83.5t-34.5 -233.5v-22zM965 645h253v27q0 95 -28.5 148.5t-91.5 53.5q-61 0 -93 -61.5t-40 -167.5z" />
+<glyph unicode="&#x178;" horiz-adv-x="1124" d="M7 1456h311l240 -624h6l243 624h309l-416 -938v-518h-284v536zM220 1605v198h251v-198h-251zM669 1605v198h250v-198h-250z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="902" d="M118 1252v25l250 237h159l256 -240v-22h-222l-114 134l-112 -134h-217z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="867" d="M110 1272q0 93 51.5 161t129.5 68q46 0 129.5 -44t128.5 -44q27 0 46.5 32.5t19.5 80.5l148 -45q0 -95 -51 -161.5t-130 -66.5q-59 0 -136.5 44t-121.5 44q-27 0 -46 -33t-19 -79z" />
+<glyph unicode="&#x2000;" horiz-adv-x="964" />
+<glyph unicode="&#x2001;" horiz-adv-x="1929" />
+<glyph unicode="&#x2002;" horiz-adv-x="964" />
+<glyph unicode="&#x2003;" horiz-adv-x="1929" />
+<glyph unicode="&#x2004;" horiz-adv-x="643" />
+<glyph unicode="&#x2005;" horiz-adv-x="482" />
+<glyph unicode="&#x2006;" horiz-adv-x="321" />
+<glyph unicode="&#x2007;" horiz-adv-x="321" />
+<glyph unicode="&#x2008;" horiz-adv-x="241" />
+<glyph unicode="&#x2009;" horiz-adv-x="385" />
+<glyph unicode="&#x200a;" horiz-adv-x="107" />
+<glyph unicode="&#x2010;" horiz-adv-x="748" d="M120 511v228h497v-228h-497z" />
+<glyph unicode="&#x2011;" horiz-adv-x="748" d="M120 511v228h497v-228h-497z" />
+<glyph unicode="&#x2012;" horiz-adv-x="748" d="M120 511v228h497v-228h-497z" />
+<glyph unicode="&#x2013;" horiz-adv-x="1212" d="M147 600v230h917v-230h-917z" />
+<glyph unicode="&#x2014;" horiz-adv-x="1430" d="M123 600v230h1128v-230h-1128z" />
+<glyph unicode="&#x2018;" horiz-adv-x="366" d="M41 1023v191l146 346h137l-50 -342v-195h-233z" />
+<glyph unicode="&#x2019;" horiz-adv-x="366" d="M49 1024l49 344v192h234v-192l-146 -344h-137z" />
+<glyph unicode="&#x201a;" horiz-adv-x="367" d="M41 -257l52 267v285h234v-271l-132 -281h-154z" />
+<glyph unicode="&#x201c;" horiz-adv-x="667" d="M41 1023v191l146 346h137l-50 -342v-195h-233zM342 1023v191l146 346h137l-50 -342v-195h-233z" />
+<glyph unicode="&#x201d;" horiz-adv-x="675" d="M43 1024l49 344v192h234v-192l-146 -344h-137zM350 1024l49 344v192h234v-192l-146 -344h-137z" />
+<glyph unicode="&#x201e;" horiz-adv-x="661" d="M41 -217l52 254v263h217v-251l-148 -266h-121zM350 -217l52 261v256h217v-251l-148 -266h-121z" />
+<glyph unicode="&#x2022;" horiz-adv-x="680" d="M126 710v96q0 100 59.5 164t158.5 64q101 0 161 -63.5t60 -164.5v-96q0 -101 -59.5 -163t-159.5 -62t-160 62.5t-60 162.5z" />
+<glyph unicode="&#x2026;" horiz-adv-x="1347" d="M129 0v258h281v-258h-281zM543 0v258h281v-258h-281zM952 0v258h281v-258h-281z" />
+<glyph unicode="&#x202f;" horiz-adv-x="385" />
+<glyph unicode="&#x2039;" horiz-adv-x="563" d="M99 541v19l233 389h176l-195 -399l195 -397h-176z" />
+<glyph unicode="&#x203a;" horiz-adv-x="541" d="M72 152l195 398l-195 399h176l233 -389v-19l-233 -389h-176z" />
+<glyph unicode="&#x205f;" horiz-adv-x="482" />
+<glyph unicode="&#x20ac;" horiz-adv-x="970" d="M65 453v200h121v117h-121v200h121v16q0 204 130 347.5t342 143.5q51 0 100.5 -8t107.5 -23l-20 -232q-45 16 -92.5 25.5t-95.5 9.5q-89 0 -138.5 -78.5t-49.5 -182.5v-18h336v-200h-336v-117h336v-200h-336v-12q0 -97 49.5 -166t139.5 -69q48 0 95.5 8t91.5 25l20 -229 q-50 -15 -102 -23t-105 -8q-212 0 -342.5 134.5t-130.5 327.5v12h-121z" />
+<glyph unicode="&#x2122;" horiz-adv-x="1116" d="M89 1350v106h340v-106h-104v-433h-137v433h-99zM487 914v542h149l89 -360h6l89 360h143v-542h-120v251h-6l-76 -251h-67l-80 266l-6 -1v-265h-121z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1080" d="M0 0v1080h1080v-1080h-1080z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="1142" d="M23 876v206h133v120q0 182 94 280.5t264 98.5q33 0 66 -5.5t76 -15.5l-24 -218q-20 4 -38.5 7t-43.5 3q-54 0 -82 -39t-28 -111v-120h174v-206h-174v-876h-284v876h-133zM752 0v1560h284v-1560h-284z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1754" d="M23 876v206h133v120q0 182 94 280.5t264 98.5q33 0 66 -5.5t76 -15.5l-24 -218q-20 4 -38.5 7t-43.5 3q-54 0 -82 -39t-28 -111v-120h174v-206h-174v-876h-284v876h-133zM665 876v206h133v70q0 207 112 318t316 111q70 0 138.5 -15t153.5 -44l-40 -232q-65 22 -115.5 34 t-118.5 12q-80 0 -121 -47t-41 -137v-70h173v-206h-173v-876h-284v876h-133zM1363 0v1082h285v-1082h-285z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1789" d="M23 876v206h133v120q0 182 94 280.5t264 98.5q33 0 66 -5.5t76 -15.5l-24 -218q-20 4 -38.5 7t-43.5 3q-54 0 -82 -39t-28 -111v-120h174v-206h-174v-876h-284v876h-133zM670 876v206h133v120q0 182 94 280.5t264 98.5q33 0 66 -5.5t76 -15.5l-24 -218q-20 4 -38.5 7 t-43.5 3q-54 0 -82 -39t-28 -111v-120h174v-206h-174v-876h-284v876h-133zM1399 0v1560h284v-1560h-284z" />
+<hkern u1="&#x22;" u2="w" k="-11" />
+<hkern u1="&#x27;" u2="w" k="-11" />
+<hkern u1="&#x28;" u2="&#x178;" k="-22" />
+<hkern u1="&#x28;" u2="&#xdd;" k="-22" />
+<hkern u1="&#x28;" u2="Y" k="-22" />
+<hkern u1="&#x28;" u2="W" k="-18" />
+<hkern u1="&#x28;" u2="V" k="-20" />
+<hkern u1="&#x2f;" u2="&#x2f;" k="224" />
+<hkern u1="A" u2="w" k="33" />
+<hkern u1="A" u2="t" k="17" />
+<hkern u1="A" u2="&#x3f;" k="61" />
+<hkern u1="C" u2="&#x7d;" k="17" />
+<hkern u1="C" u2="]" k="12" />
+<hkern u1="C" u2="&#x29;" k="26" />
+<hkern u1="D" u2="&#xc6;" k="33" />
+<hkern u1="E" u2="w" k="22" />
+<hkern u1="E" u2="f" k="18" />
+<hkern u1="F" u2="&#x2026;" k="234" />
+<hkern u1="F" u2="&#x201e;" k="234" />
+<hkern u1="F" u2="&#x201a;" k="234" />
+<hkern u1="F" u2="&#x153;" k="21" />
+<hkern u1="F" u2="&#xff;" k="24" />
+<hkern u1="F" u2="&#xfd;" k="24" />
+<hkern u1="F" u2="&#xfc;" k="22" />
+<hkern u1="F" u2="&#xfb;" k="22" />
+<hkern u1="F" u2="&#xfa;" k="22" />
+<hkern u1="F" u2="&#xf9;" k="22" />
+<hkern u1="F" u2="&#xf6;" k="21" />
+<hkern u1="F" u2="&#xf5;" k="21" />
+<hkern u1="F" u2="&#xf4;" k="21" />
+<hkern u1="F" u2="&#xf3;" k="21" />
+<hkern u1="F" u2="&#xf2;" k="21" />
+<hkern u1="F" u2="&#xeb;" k="21" />
+<hkern u1="F" u2="&#xea;" k="21" />
+<hkern u1="F" u2="&#xe9;" k="21" />
+<hkern u1="F" u2="&#xe8;" k="21" />
+<hkern u1="F" u2="&#xe7;" k="21" />
+<hkern u1="F" u2="&#xe5;" k="34" />
+<hkern u1="F" u2="&#xe4;" k="34" />
+<hkern u1="F" u2="&#xe3;" k="34" />
+<hkern u1="F" u2="&#xe2;" k="34" />
+<hkern u1="F" u2="&#xe1;" k="34" />
+<hkern u1="F" u2="&#xe0;" k="34" />
+<hkern u1="F" u2="&#xc5;" k="59" />
+<hkern u1="F" u2="&#xc4;" k="59" />
+<hkern u1="F" u2="&#xc3;" k="59" />
+<hkern u1="F" u2="&#xc2;" k="59" />
+<hkern u1="F" u2="&#xc1;" k="59" />
+<hkern u1="F" u2="&#xc0;" k="59" />
+<hkern u1="F" u2="y" k="24" />
+<hkern u1="F" u2="v" k="24" />
+<hkern u1="F" u2="u" k="22" />
+<hkern u1="F" u2="r" k="26" />
+<hkern u1="F" u2="q" k="21" />
+<hkern u1="F" u2="o" k="21" />
+<hkern u1="F" u2="g" k="21" />
+<hkern u1="F" u2="e" k="21" />
+<hkern u1="F" u2="d" k="21" />
+<hkern u1="F" u2="c" k="21" />
+<hkern u1="F" u2="a" k="34" />
+<hkern u1="F" u2="T" k="-20" />
+<hkern u1="F" u2="J" k="264" />
+<hkern u1="F" u2="A" k="59" />
+<hkern u1="F" u2="&#x2e;" k="234" />
+<hkern u1="F" u2="&#x2c;" k="234" />
+<hkern u1="K" u2="w" k="63" />
+<hkern u1="L" u2="w" k="92" />
+<hkern u1="O" u2="&#xc6;" k="33" />
+<hkern u1="P" u2="&#xc6;" k="97" />
+<hkern u1="P" u2="t" k="-14" />
+<hkern u1="Q" u2="&#x178;" k="35" />
+<hkern u1="Q" u2="&#xdd;" k="35" />
+<hkern u1="Q" u2="Y" k="35" />
+<hkern u1="Q" u2="W" k="20" />
+<hkern u1="Q" u2="V" k="28" />
+<hkern u1="Q" u2="T" k="43" />
+<hkern u1="R" u2="&#x178;" k="48" />
+<hkern u1="R" u2="&#xdd;" k="48" />
+<hkern u1="R" u2="Y" k="48" />
+<hkern u1="R" u2="V" k="19" />
+<hkern u1="R" u2="T" k="80" />
+<hkern u1="T" u2="&#xf8;" k="95" />
+<hkern u1="T" u2="&#xe6;" k="114" />
+<hkern u1="T" u2="&#xc6;" k="179" />
+<hkern u1="T" u2="&#xbb;" k="216" />
+<hkern u1="T" u2="&#xab;" k="328" />
+<hkern u1="T" u2="w" k="57" />
+<hkern u1="T" u2="r" k="75" />
+<hkern u1="V" u2="&#x7d;" k="-19" />
+<hkern u1="V" u2="r" k="30" />
+<hkern u1="V" u2="]" k="-17" />
+<hkern u1="V" u2="&#x29;" k="-20" />
+<hkern u1="W" u2="&#x7d;" k="-14" />
+<hkern u1="W" u2="r" k="21" />
+<hkern u1="W" u2="]" k="-12" />
+<hkern u1="W" u2="&#x29;" k="-15" />
+<hkern u1="Y" u2="&#x2022;" k="45" />
+<hkern u1="Y" u2="&#xf8;" k="64" />
+<hkern u1="Y" u2="&#xe6;" k="63" />
+<hkern u1="Y" u2="&#xc6;" k="96" />
+<hkern u1="Y" u2="&#xbb;" k="51" />
+<hkern u1="Y" u2="&#xab;" k="82" />
+<hkern u1="Y" u2="&#x7d;" k="-19" />
+<hkern u1="Y" u2="t" k="22" />
+<hkern u1="Y" u2="r" k="40" />
+<hkern u1="Y" u2="f" k="22" />
+<hkern u1="Y" u2="]" k="-18" />
+<hkern u1="Y" u2="&#x2a;" k="49" />
+<hkern u1="Y" u2="&#x29;" k="-20" />
+<hkern u1="Y" u2="&#x26;" k="30" />
+<hkern u1="Z" u2="w" k="27" />
+<hkern u1="[" u2="&#xdc;" k="18" />
+<hkern u1="[" u2="&#xdb;" k="18" />
+<hkern u1="[" u2="&#xda;" k="18" />
+<hkern u1="[" u2="&#xd9;" k="18" />
+<hkern u1="[" u2="U" k="18" />
+<hkern u1="[" u2="J" k="18" />
+<hkern u1="f" u2="&#x201d;" k="-16" />
+<hkern u1="f" u2="&#x201c;" k="-16" />
+<hkern u1="f" u2="&#x2019;" k="-16" />
+<hkern u1="f" u2="&#x2018;" k="-16" />
+<hkern u1="f" u2="&#x153;" k="24" />
+<hkern u1="f" u2="&#xeb;" k="24" />
+<hkern u1="f" u2="&#xea;" k="24" />
+<hkern u1="f" u2="&#xe9;" k="24" />
+<hkern u1="f" u2="&#xe8;" k="24" />
+<hkern u1="f" u2="&#xe7;" k="24" />
+<hkern u1="f" u2="&#x7d;" k="-19" />
+<hkern u1="f" u2="q" k="24" />
+<hkern u1="f" u2="g" k="24" />
+<hkern u1="f" u2="e" k="24" />
+<hkern u1="f" u2="d" k="24" />
+<hkern u1="f" u2="c" k="24" />
+<hkern u1="f" u2="]" k="-18" />
+<hkern u1="f" u2="&#x29;" k="-20" />
+<hkern u1="f" u2="&#x27;" k="-16" />
+<hkern u1="f" u2="&#x22;" k="-16" />
+<hkern u1="k" u2="&#x153;" k="20" />
+<hkern u1="k" u2="&#xeb;" k="20" />
+<hkern u1="k" u2="&#xea;" k="20" />
+<hkern u1="k" u2="&#xe9;" k="20" />
+<hkern u1="k" u2="&#xe8;" k="20" />
+<hkern u1="k" u2="&#xe7;" k="20" />
+<hkern u1="k" u2="q" k="20" />
+<hkern u1="k" u2="g" k="20" />
+<hkern u1="k" u2="e" k="20" />
+<hkern u1="k" u2="d" k="20" />
+<hkern u1="k" u2="c" k="20" />
+<hkern u1="r" u2="w" k="-17" />
+<hkern u1="r" u2="t" k="-32" />
+<hkern u1="r" u2="f" k="-15" />
+<hkern u1="t" u2="&#xf6;" k="20" />
+<hkern u1="t" u2="&#xf5;" k="20" />
+<hkern u1="t" u2="&#xf4;" k="20" />
+<hkern u1="t" u2="&#xf3;" k="20" />
+<hkern u1="t" u2="&#xf2;" k="20" />
+<hkern u1="t" u2="o" k="20" />
+<hkern u1="v" u2="f" k="-13" />
+<hkern u1="w" u2="&#x2026;" k="124" />
+<hkern u1="w" u2="&#x201e;" k="124" />
+<hkern u1="w" u2="&#x201a;" k="124" />
+<hkern u1="w" u2="&#x2e;" k="124" />
+<hkern u1="w" u2="&#x2c;" k="124" />
+<hkern u1="y" u2="f" k="-13" />
+<hkern u1="&#x7b;" u2="&#xdc;" k="20" />
+<hkern u1="&#x7b;" u2="&#xdb;" k="20" />
+<hkern u1="&#x7b;" u2="&#xda;" k="20" />
+<hkern u1="&#x7b;" u2="&#xd9;" k="20" />
+<hkern u1="&#x7b;" u2="U" k="20" />
+<hkern u1="&#x7b;" u2="J" k="20" />
+<hkern u1="&#xc0;" u2="w" k="33" />
+<hkern u1="&#xc0;" u2="t" k="17" />
+<hkern u1="&#xc0;" u2="&#x3f;" k="61" />
+<hkern u1="&#xc1;" u2="w" k="33" />
+<hkern u1="&#xc1;" u2="t" k="17" />
+<hkern u1="&#xc1;" u2="&#x3f;" k="61" />
+<hkern u1="&#xc2;" u2="w" k="33" />
+<hkern u1="&#xc2;" u2="t" k="17" />
+<hkern u1="&#xc2;" u2="&#x3f;" k="61" />
+<hkern u1="&#xc3;" u2="w" k="33" />
+<hkern u1="&#xc3;" u2="t" k="17" />
+<hkern u1="&#xc3;" u2="&#x3f;" k="61" />
+<hkern u1="&#xc4;" u2="w" k="33" />
+<hkern u1="&#xc4;" u2="t" k="17" />
+<hkern u1="&#xc4;" u2="&#x3f;" k="61" />
+<hkern u1="&#xc5;" u2="w" k="33" />
+<hkern u1="&#xc5;" u2="t" k="17" />
+<hkern u1="&#xc5;" u2="&#x3f;" k="61" />
+<hkern u1="&#xc7;" u2="&#x7d;" k="17" />
+<hkern u1="&#xc7;" u2="]" k="12" />
+<hkern u1="&#xc7;" u2="&#x29;" k="26" />
+<hkern u1="&#xc8;" u2="w" k="22" />
+<hkern u1="&#xc8;" u2="f" k="18" />
+<hkern u1="&#xc9;" u2="w" k="22" />
+<hkern u1="&#xc9;" u2="f" k="18" />
+<hkern u1="&#xca;" u2="w" k="22" />
+<hkern u1="&#xca;" u2="f" k="18" />
+<hkern u1="&#xcb;" u2="w" k="22" />
+<hkern u1="&#xcb;" u2="f" k="18" />
+<hkern u1="&#xd0;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd2;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd3;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd4;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd5;" u2="&#xc6;" k="33" />
+<hkern u1="&#xd6;" u2="&#xc6;" k="33" />
+<hkern u1="&#xdd;" u2="&#x2022;" k="45" />
+<hkern u1="&#xdd;" u2="&#xf8;" k="64" />
+<hkern u1="&#xdd;" u2="&#xe6;" k="63" />
+<hkern u1="&#xdd;" u2="&#xc6;" k="96" />
+<hkern u1="&#xdd;" u2="&#xbb;" k="51" />
+<hkern u1="&#xdd;" u2="&#xab;" k="82" />
+<hkern u1="&#xdd;" u2="&#x7d;" k="-19" />
+<hkern u1="&#xdd;" u2="t" k="22" />
+<hkern u1="&#xdd;" u2="r" k="40" />
+<hkern u1="&#xdd;" u2="f" k="22" />
+<hkern u1="&#xdd;" u2="]" k="-18" />
+<hkern u1="&#xdd;" u2="&#x2a;" k="49" />
+<hkern u1="&#xdd;" u2="&#x29;" k="-20" />
+<hkern u1="&#xdd;" u2="&#x26;" k="30" />
+<hkern u1="&#xfd;" u2="f" k="-13" />
+<hkern u1="&#xff;" u2="f" k="-13" />
+<hkern u1="&#x178;" u2="&#x2022;" k="45" />
+<hkern u1="&#x178;" u2="&#xf8;" k="64" />
+<hkern u1="&#x178;" u2="&#xe6;" k="63" />
+<hkern u1="&#x178;" u2="&#xc6;" k="96" />
+<hkern u1="&#x178;" u2="&#xbb;" k="51" />
+<hkern u1="&#x178;" u2="&#xab;" k="82" />
+<hkern u1="&#x178;" u2="&#x7d;" k="-19" />
+<hkern u1="&#x178;" u2="t" k="22" />
+<hkern u1="&#x178;" u2="r" k="40" />
+<hkern u1="&#x178;" u2="f" k="22" />
+<hkern u1="&#x178;" u2="]" k="-18" />
+<hkern u1="&#x178;" u2="&#x2a;" k="49" />
+<hkern u1="&#x178;" u2="&#x29;" k="-20" />
+<hkern u1="&#x178;" u2="&#x26;" k="30" />
+<hkern u1="&#x2018;" u2="w" k="-11" />
+<hkern u1="&#x2019;" u2="w" k="-11" />
+<hkern u1="&#x201c;" u2="w" k="-11" />
+<hkern u1="&#x201d;" u2="w" k="-11" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="170" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="120" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="12" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="11" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="T"  k="129" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="U,Ugrave,Uacute,Ucircumflex,Udieresis"      k="17" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="V"  k="87" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="W"  k="69" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="Y,Yacute,Ydieresis"         k="94" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="u,ugrave,uacute,ucircumflex,udieresis"      k="11" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="v,y,yacute,ydieresis"       k="50" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         g2="z"  k="-12" />
+<hkern g1="B"  g2="T"  k="27" />
+<hkern g1="B"  g2="V"  k="24" />
+<hkern g1="B"  g2="Y,Yacute,Ydieresis"         k="55" />
+<hkern g1="C,Ccedilla"         g2="T"  k="29" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="21" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="T"  k="27" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="V"  k="22" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="Y,Yacute,Ydieresis"         k="43" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="102" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="X"  k="22" />
+<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis"         g2="Z"  k="23" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="19" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="19" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="T"  k="-20" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="u,ugrave,uacute,ucircumflex,udieresis"      k="17" />
+<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis"      g2="v,y,yacute,ydieresis"       k="26" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="-18" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="T"  k="29" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="Y,Yacute,Ydieresis"         k="28" />
+<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde"         g2="X"  k="-17" />
+<hkern g1="J,U,Ugrave,Uacute,Ucircumflex,Udieresis"    g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="22" />
+<hkern g1="K"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="26" />
+<hkern g1="K"  g2="m,n,p,ntilde"       k="23" />
+<hkern g1="K"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="27" />
+<hkern g1="K"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="31" />
+<hkern g1="K"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="23" />
+<hkern g1="K"  g2="v,y,yacute,ydieresis"       k="40" />
+<hkern g1="K"  g2="hyphen,uni00AD,endash,emdash"       k="64" />
+<hkern g1="L"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="138" />
+<hkern g1="L"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="-19" />
+<hkern g1="L"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="65" />
+<hkern g1="L"  g2="T"  k="275" />
+<hkern g1="L"  g2="U,Ugrave,Uacute,Ucircumflex,Udieresis"      k="54" />
+<hkern g1="L"  g2="V"  k="175" />
+<hkern g1="L"  g2="W"  k="143" />
+<hkern g1="L"  g2="Y,Yacute,Ydieresis"         k="239" />
+<hkern g1="L"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="44" />
+<hkern g1="L"  g2="v,y,yacute,ydieresis"       k="133" />
+<hkern g1="P"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="138" />
+<hkern g1="P"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="11" />
+<hkern g1="P"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="13" />
+<hkern g1="P"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="13" />
+<hkern g1="P"  g2="v,y,yacute,ydieresis"       k="-15" />
+<hkern g1="P"  g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="324" />
+<hkern g1="P"  g2="X"  k="31" />
+<hkern g1="P"  g2="Z"  k="26" />
+<hkern g1="P"  g2="J"  k="200" />
+<hkern g1="T"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="79" />
+<hkern g1="T"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="113" />
+<hkern g1="T"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="99" />
+<hkern g1="T"  g2="m,n,p,ntilde"       k="109" />
+<hkern g1="T"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="99" />
+<hkern g1="T"  g2="s"  k="116" />
+<hkern g1="T"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="28" />
+<hkern g1="T"  g2="T"  k="-16" />
+<hkern g1="T"  g2="V"  k="-16" />
+<hkern g1="T"  g2="W"  k="-15" />
+<hkern g1="T"  g2="Y,Yacute,Ydieresis"         k="-16" />
+<hkern g1="T"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="95" />
+<hkern g1="T"  g2="v,y,yacute,ydieresis"       k="72" />
+<hkern g1="T"  g2="z"  k="60" />
+<hkern g1="T"  g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="218" />
+<hkern g1="T"  g2="hyphen,uni00AD,endash,emdash"       k="232" />
+<hkern g1="T"  g2="J"  k="240" />
+<hkern g1="T"  g2="S"  k="16" />
+<hkern g1="T"  g2="x"  k="77" />
+<hkern g1="V"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="75" />
+<hkern g1="V"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="46" />
+<hkern g1="V"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="44" />
+<hkern g1="V"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="46" />
+<hkern g1="V"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="13" />
+<hkern g1="V"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="28" />
+<hkern g1="V"  g2="v,y,yacute,ydieresis"       k="11" />
+<hkern g1="V"  g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="225" />
+<hkern g1="V"  g2="hyphen,uni00AD,endash,emdash"       k="37" />
+<hkern g1="W"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="43" />
+<hkern g1="W"  g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="33" />
+<hkern g1="W"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="31" />
+<hkern g1="W"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="31" />
+<hkern g1="W"  g2="T"  k="-14" />
+<hkern g1="W"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="19" />
+<hkern g1="W"  g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="123" />
+<hkern g1="W"  g2="hyphen,uni00AD,endash,emdash"       k="60" />
+<hkern g1="X"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="26" />
+<hkern g1="X"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="21" />
+<hkern g1="X"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="25" />
+<hkern g1="X"  g2="V"  k="-14" />
+<hkern g1="X"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="21" />
+<hkern g1="X"  g2="v,y,yacute,ydieresis"       k="31" />
+<hkern g1="X"  g2="hyphen,uni00AD,endash,emdash"       k="46" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="94" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="73" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="65" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="m,n,p,ntilde"       k="40" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="65" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="s"  k="58" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="29" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="T"  k="-17" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="U,Ugrave,Uacute,Ucircumflex,Udieresis"      k="96" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="V"  k="-18" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="W"  k="-17" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="Y,Yacute,Ydieresis"         k="-18" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="u,ugrave,uacute,ucircumflex,udieresis"      k="39" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="v,y,yacute,ydieresis"       k="20" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="z"  k="30" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="211" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="X"  k="-13" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="hyphen,uni00AD,endash,emdash"       k="52" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="J"  k="96" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="S"  k="16" />
+<hkern g1="Y,Yacute,Ydieresis"         g2="x"  k="23" />
+<hkern g1="Z"  g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring"         k="-13" />
+<hkern g1="Z"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="21" />
+<hkern g1="Z"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="21" />
+<hkern g1="Z"  g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE"      k="26" />
+<hkern g1="Z"  g2="u,ugrave,uacute,ucircumflex,udieresis"      k="19" />
+<hkern g1="Z"  g2="v,y,yacute,ydieresis"       k="27" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="67" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         g2="v,y,yacute,ydieresis"       k="15" />
+<hkern g1="b,p,thorn"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="29" />
+<hkern g1="b,p,thorn"  g2="v,y,yacute,ydieresis"       k="11" />
+<hkern g1="b,p,thorn"  g2="z"  k="15" />
+<hkern g1="b,p,thorn"  g2="x"  k="15" />
+<hkern g1="c,ccedilla"         g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="11" />
+<hkern g1="e,egrave,eacute,ecircumflex,edieresis"      g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="14" />
+<hkern g1="e,egrave,eacute,ecircumflex,edieresis"      g2="v,y,yacute,ydieresis"       k="13" />
+<hkern g1="h,m,n,ntilde"       g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="16" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="20" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="v,y,yacute,ydieresis"       k="15" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="z"  k="16" />
+<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis"       g2="x"  k="21" />
+<hkern g1="r"  g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="-16" />
+<hkern g1="r"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="19" />
+<hkern g1="r"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="20" />
+<hkern g1="r"  g2="v,y,yacute,ydieresis"       k="-18" />
+<hkern g1="r"  g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="123" />
+<hkern g1="v,y,yacute,ydieresis"       g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright"       k="-15" />
+<hkern g1="v,y,yacute,ydieresis"       g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring"         k="15" />
+<hkern g1="v,y,yacute,ydieresis"       g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="13" />
+<hkern g1="v,y,yacute,ydieresis"       g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="15" />
+<hkern g1="v,y,yacute,ydieresis"       g2="comma,period,quotesinglbase,quotedblbase,ellipsis"  k="107" />
+<hkern g1="x"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="20" />
+<hkern g1="x"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="20" />
+<hkern g1="z"  g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe"  k="16" />
+<hkern g1="z"  g2="o,ograve,oacute,ocircumflex,otilde,odieresis"       k="16" />
+</font>
+</defs></svg> 
\ No newline at end of file
diff --git a/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.ttf b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.ttf
new file mode 100755 (executable)
index 0000000..87256d3
Binary files /dev/null and b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.ttf differ
diff --git a/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.woff b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.woff
new file mode 100755 (executable)
index 0000000..235c963
Binary files /dev/null and b/skyquake/framework/style/fonts/RobotoCondensed-Bold-webfont.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-Black.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-Black.otf.woff
new file mode 100755 (executable)
index 0000000..d08a984
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-Black.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-BlackIt.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-BlackIt.otf.woff
new file mode 100755 (executable)
index 0000000..1061185
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-BlackIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-Bold.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-Bold.otf.woff
new file mode 100755 (executable)
index 0000000..cf96099
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-Bold.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-BoldIt.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-BoldIt.otf.woff
new file mode 100755 (executable)
index 0000000..e8702f9
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-BoldIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-ExtraLight.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-ExtraLight.otf.woff
new file mode 100755 (executable)
index 0000000..54e6b36
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-ExtraLight.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-ExtraLightIt.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-ExtraLightIt.otf.woff
new file mode 100755 (executable)
index 0000000..c57443c
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-ExtraLightIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-It.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-It.otf.woff
new file mode 100755 (executable)
index 0000000..cc67c99
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-It.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-Light.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-Light.otf.woff
new file mode 100755 (executable)
index 0000000..c62373f
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-Light.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-LightIt.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-LightIt.otf.woff
new file mode 100755 (executable)
index 0000000..c4cd646
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-LightIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-Medium.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-Medium.otf.woff
new file mode 100755 (executable)
index 0000000..826a854
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-Medium.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-MediumIt.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-MediumIt.otf.woff
new file mode 100755 (executable)
index 0000000..5c538de
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-MediumIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-Regular.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-Regular.otf.woff
new file mode 100755 (executable)
index 0000000..395436e
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-Regular.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-Semibold.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-Semibold.otf.woff
new file mode 100755 (executable)
index 0000000..83ec113
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-Semibold.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceCodePro-SemiboldIt.otf.woff b/skyquake/framework/style/fonts/SourceCodePro-SemiboldIt.otf.woff
new file mode 100755 (executable)
index 0000000..be0bd90
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceCodePro-SemiboldIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-Black.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-Black.otf.woff
new file mode 100755 (executable)
index 0000000..f1a663a
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-Black.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-BlackIt.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-BlackIt.otf.woff
new file mode 100755 (executable)
index 0000000..1d7dfbd
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-BlackIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-Bold.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-Bold.otf.woff
new file mode 100755 (executable)
index 0000000..6700893
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-Bold.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-BoldIt.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-BoldIt.otf.woff
new file mode 100755 (executable)
index 0000000..d5e4a0f
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-BoldIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-ExtraLight.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-ExtraLight.otf.woff
new file mode 100755 (executable)
index 0000000..559b740
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-ExtraLight.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-ExtraLightIt.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-ExtraLightIt.otf.woff
new file mode 100755 (executable)
index 0000000..e8fbeb8
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-ExtraLightIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-It.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-It.otf.woff
new file mode 100755 (executable)
index 0000000..4b8af41
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-It.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-Light.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-Light.otf.woff
new file mode 100755 (executable)
index 0000000..10490ec
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-Light.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-LightIt.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-LightIt.otf.woff
new file mode 100755 (executable)
index 0000000..13532d7
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-LightIt.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-Regular.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-Regular.otf.woff
new file mode 100755 (executable)
index 0000000..04739e7
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-Regular.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-Semibold.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-Semibold.otf.woff
new file mode 100755 (executable)
index 0000000..17d744d
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-Semibold.otf.woff differ
diff --git a/skyquake/framework/style/fonts/SourceSansPro-SemiboldIt.otf.woff b/skyquake/framework/style/fonts/SourceSansPro-SemiboldIt.otf.woff
new file mode 100755 (executable)
index 0000000..a5b5e1e
Binary files /dev/null and b/skyquake/framework/style/fonts/SourceSansPro-SemiboldIt.otf.woff differ
diff --git a/skyquake/framework/style/icons/svg-sprite-action-symbol.svg b/skyquake/framework/style/icons/svg-sprite-action-symbol.svg
new file mode 100755 (executable)
index 0000000..e2497d9
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_3d_rotation_24px"><path d="M7.52 21.48A10.487 10.487 0 0 1 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32zm.89-6.52c-.19 0-.37-.03-.52-.08a1.07 1.07 0 0 1-.4-.24.99.99 0 0 1-.26-.37c-.06-.14-.09-.3-.09-.47h-1.3c0 .36.07.68.21.95.14.27.33.5.56.69.24.18.51.32.82.41.3.1.62.15.96.15.37 0 .72-.05 1.03-.15.32-.1.6-.25.83-.44s.42-.43.55-.72c.13-.29.2-.61.2-.97 0-.19-.02-.38-.07-.56a1.67 1.67 0 0 0-.23-.51c-.1-.16-.24-.3-.4-.43-.17-.13-.37-.23-.61-.31a2.098 2.098 0 0 0 .89-.75c.1-.15.17-.3.22-.46.05-.16.07-.32.07-.48 0-.36-.06-.68-.18-.96a1.78 1.78 0 0 0-.51-.69c-.2-.19-.47-.33-.77-.43C9.1 8.05 8.76 8 8.39 8c-.36 0-.69.05-1 .16-.3.11-.57.26-.79.45-.21.19-.38.41-.51.67-.12.26-.18.54-.18.85h1.3c0-.17.03-.32.09-.45s.14-.25.25-.34c.11-.09.23-.17.38-.22.15-.05.3-.08.48-.08.4 0 .7.1.89.31.19.2.29.49.29.86 0 .18-.03.34-.08.49a.87.87 0 0 1-.25.37c-.11.1-.25.18-.41.24-.16.06-.36.09-.58.09H7.5v1.03h.77c.22 0 .42.02.6.07s.33.13.45.23c.12.11.22.24.29.4.07.16.1.35.1.57 0 .41-.12.72-.35.93-.23.23-.55.33-.95.33zm8.55-5.92c-.32-.33-.7-.59-1.14-.77-.43-.18-.92-.27-1.46-.27H12v8h2.3c.55 0 1.06-.09 1.51-.27.45-.18.84-.43 1.16-.76.32-.33.57-.73.74-1.19.17-.47.26-.99.26-1.57v-.4c0-.58-.09-1.1-.26-1.57-.18-.47-.43-.87-.75-1.2zm-.39 3.16c0 .42-.05.79-.14 1.13-.1.33-.24.62-.43.85-.19.23-.43.41-.71.53-.29.12-.62.18-.99.18h-.91V9.12h.97c.72 0 1.27.23 1.64.69.38.46.57 1.12.57 1.99v.4zM12 0l-.66.03 3.81 3.81 1.33-1.33c3.27 1.55 5.61 4.72 5.96 8.48h1.5C23.44 4.84 18.29 0 12 0z"/></symbol><symbol viewBox="0 0 24 24" id="ic_accessibility_24px"><path d="M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_accessible_24px"><circle cx="12" cy="4" r="2"/><path d="M19 13v-2c-1.54.02-3.09-.75-4.07-1.83l-1.29-1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3-1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0-1.1-.9-2-2-2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16-1.52 2-2.83 2-1.66 0-3-1.34-3-3 0-1.31.84-2.41 2-2.83V12.1a5 5 0 1 0 5.9 5.9h-2.07z"/></symbol><symbol viewBox="0 0 24 24" id="ic_account_balance_24px"><path d="M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_account_balance_wallet_24px"><path d="M21 18v1c0 1.1-.9 2-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14c1.1 0 2 .9 2 2v1h-9a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_account_box_24px"><path d="M3 5v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5a2 2 0 0 0-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_account_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2a7.2 7.2 0 0 1-6-3.22c.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08a7.2 7.2 0 0 1-6 3.22z"/></symbol><symbol viewBox="0 0 24 24" id="ic_add_shopping_cart_24px"><path d="M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z"/></symbol><symbol viewBox="0 0 24 24" id="ic_alarm_24px"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9a9 9 0 0 0 0-18zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_alarm_add_24px"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9a9 9 0 0 0 0-18zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_alarm_off_24px"><path d="M12 6c3.87 0 7 3.13 7 7 0 .84-.16 1.65-.43 2.4l1.52 1.52c.58-1.19.91-2.51.91-3.92a9 9 0 0 0-9-9c-1.41 0-2.73.33-3.92.91L9.6 6.43C10.35 6.16 11.16 6 12 6zm10-.28l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM2.92 2.29L1.65 3.57 2.98 4.9l-1.11.93 1.42 1.42 1.11-.94.8.8A8.964 8.964 0 0 0 3 13c0 4.97 4.02 9 9 9 2.25 0 4.31-.83 5.89-2.2l2.2 2.2 1.27-1.27L3.89 3.27l-.97-.98zm13.55 16.1C15.26 19.39 13.7 20 12 20c-3.87 0-7-3.13-7-7 0-1.7.61-3.26 1.61-4.47l9.86 9.86zM8.02 3.28L6.6 1.86l-.86.71 1.42 1.42.86-.71z"/></symbol><symbol viewBox="0 0 24 24" id="ic_alarm_on_24px"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9a9 9 0 0 0 0-18zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-1.46-5.47L8.41 12.4l-1.06 1.06 3.18 3.18 6-6-1.06-1.06-4.93 4.95z"/></symbol><symbol viewBox="0 0 24 24" id="ic_all_out_24px"><path d="M16.21 4.16l4 4v-4zm4 12l-4 4h4zm-12 4l-4-4v4zm-4-12l4-4h-4zm12.95-.95c-2.73-2.73-7.17-2.73-9.9 0s-2.73 7.17 0 9.9 7.17 2.73 9.9 0 2.73-7.16 0-9.9zm-1.1 8.8c-2.13 2.13-5.57 2.13-7.7 0s-2.13-5.57 0-7.7 5.57-2.13 7.7 0 2.13 5.57 0 7.7z" fill="#010101"/></symbol><symbol viewBox="0 0 24 24" id="ic_android_24px"><path d="M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48A5.84 5.84 0 0 0 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31A5.983 5.983 0 0 0 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_announcement_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_aspect_ratio_24px"><path d="M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assessment_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assignment_24px"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assignment_ind_24px"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assignment_late_24px"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-6 15h-2v-2h2v2zm0-4h-2V8h2v6zm-1-9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assignment_return_24px"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm4 12h-4v3l-5-5 5-5v3h4v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assignment_returned_24px"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 15l-5-5h3V9h4v4h3l-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assignment_turned_in_24px"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-2 14l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_autorenew_24px"><path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8A5.87 5.87 0 0 1 6 12c0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"/></symbol><symbol viewBox="0 0 24 24" id="ic_backup_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_book_24px"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_bookmark_24px"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_bookmark_border_24px"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_bug_report_24px"><path d="M20 8h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_build_24px"><path d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cached_24px"><path d="M19 8l-4 4h3c0 3.31-2.69 6-6 6a5.87 5.87 0 0 1-2.8-.7l-1.46 1.46A7.93 7.93 0 0 0 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46A7.93 7.93 0 0 0 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_camera_enhance_24px"><path d="M9 3L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2h-3.17L15 3H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-1l1.25-2.75L16 13l-2.75-1.25L12 9l-1.25 2.75L8 13l2.75 1.25z"/></symbol><symbol viewBox="0 0 24 24" id="ic_card_giftcard_24px"><path d="M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68A3.01 3.01 0 0 0 9 2C7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_card_membership_24px"><path d="M20 2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h4v5l4-2 4 2v-5h4c1.11 0 2-.89 2-2V4c0-1.11-.89-2-2-2zm0 13H4v-2h16v2zm0-5H4V4h16v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_card_travel_24px"><path d="M20 6h-3V4c0-1.11-.89-2-2-2H9c-1.11 0-2 .89-2 2v2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zM9 4h6v2H9V4zm11 15H4v-2h16v2zm0-5H4V8h3v2h2V8h6v2h2V8h3v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_change_history_24px"><path d="M12 7.77L18.39 18H5.61L12 7.77M12 4L2 20h20L12 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_check_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_chrome_reader_mode_24px"><path d="M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_class_24px"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_code_24px"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_compare_arrows_24px"><path d="M9.01 14H2v2h7.01v3L13 15l-3.99-4v3zm5.98-1v-3H22V8h-7.01V5L11 9l3.99 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_copyright_24px"><path d="M10.08 10.86c.05-.33.16-.62.3-.87s.34-.46.59-.62c.24-.15.54-.22.91-.23.23.01.44.05.63.13.2.09.38.21.52.36s.25.33.34.53.13.42.14.64h1.79c-.02-.47-.11-.9-.28-1.29s-.4-.73-.7-1.01-.66-.5-1.08-.66-.88-.23-1.39-.23c-.65 0-1.22.11-1.7.34s-.88.53-1.2.92-.56.84-.71 1.36S8 11.29 8 11.87v.27c0 .58.08 1.12.23 1.64s.39.97.71 1.35.72.69 1.2.91 1.05.34 1.7.34c.47 0 .91-.08 1.32-.23s.77-.36 1.08-.63.56-.58.74-.94.29-.74.3-1.15h-1.79c-.01.21-.06.4-.15.58s-.21.33-.36.46-.32.23-.52.3c-.19.07-.39.09-.6.1-.36-.01-.66-.08-.89-.23-.25-.16-.45-.37-.59-.62s-.25-.55-.3-.88-.08-.67-.08-1v-.27c0-.35.03-.68.08-1.01zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_credit_card_24px"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_dashboard_24px"><path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_date_range_24px"><path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_delete_24px"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_delete_forever_24px"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.13-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_description_24px"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_dns_24px"><path d="M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_done_24px"><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_done_all_24px"><path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"/></symbol><symbol viewBox="0 0 24 24" id="ic_donut_large_24px"><path d="M11 5.08V2c-5 .5-9 4.81-9 10s4 9.5 9 10v-3.08c-3-.48-6-3.4-6-6.92s3-6.44 6-6.92zM18.97 11H22c-.47-5-4-8.53-9-9v3.08C16 5.51 18.54 8 18.97 11zM13 18.92V22c5-.47 8.53-4 9-9h-3.03c-.43 3-2.97 5.49-5.97 5.92z"/></symbol><symbol viewBox="0 0 24 24" id="ic_donut_small_24px"><path d="M11 9.16V2c-5 .5-9 4.79-9 10s4 9.5 9 10v-7.16c-1-.41-2-1.52-2-2.84s1-2.43 2-2.84zM14.86 11H22c-.48-4.75-4-8.53-9-9v7.16c1 .3 1.52.98 1.86 1.84zM13 14.84V22c5-.47 8.52-4.25 9-9h-7.14c-.34.86-.86 1.54-1.86 1.84z"/></symbol><symbol viewBox="0 0 24 24" id="ic_eject_24px"><path d="M5 17h14v2H5zm7-12L5.33 15h13.34z"/></symbol><symbol viewBox="0 0 24 24" id="ic_euro_symbol_24px"><path d="M15 18.5A6.48 6.48 0 0 1 9.24 15H15v-2H8.58c-.05-.33-.08-.66-.08-1s.03-.67.08-1H15V9H9.24A6.49 6.49 0 0 1 15 5.5c1.61 0 3.09.59 4.23 1.57L21 5.3A8.955 8.955 0 0 0 15 3c-3.92 0-7.24 2.51-8.48 6H3v2h3.06a8.262 8.262 0 0 0 0 2H3v2h3.52c1.24 3.49 4.56 6 8.48 6 2.31 0 4.41-.87 6-2.3l-1.78-1.77c-1.13.98-2.6 1.57-4.22 1.57z"/></symbol><symbol viewBox="0 0 24 24" id="ic_event_24px"><path d="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_event_seat_24px"><path d="M4 18v3h3v-3h10v3h3v-6H4zm15-8h3v3h-3zM2 10h3v3H2zm15 3H7V5c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exit_to_app_24px"><path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5a2 2 0 0 0-2 2v4h2V5h14v14H5v-4H3v4a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_explore_24px"><path d="M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z"/></symbol><symbol viewBox="0 0 24 24" id="ic_extension_24px"><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5a2.5 2.5 0 0 0-5 0V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5a2.7 2.7 0 0 1 2.7-2.7 2.7 2.7 0 0 1 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5a2.5 2.5 0 0 0 0-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_face_24px"><path d="M9 11.75a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5zm6 0a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37a9.974 9.974 0 0 0 10.41 3.97c.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_favorite_24px"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></symbol><symbol viewBox="0 0 24 24" id="ic_favorite_border_24px"><path d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"/></symbol><symbol viewBox="0 0 24 24" id="ic_feedback_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_find_in_page_24px"><path d="M20 19.59V8l-6-6H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c.45 0 .85-.15 1.19-.4l-4.43-4.43c-.8.52-1.74.83-2.76.83-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-.31 1.96-.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_find_replace_24px"><path d="M11 6c1.38 0 2.63.56 3.54 1.46L12 10h6V4l-2.05 2.05A6.976 6.976 0 0 0 11 4c-3.53 0-6.43 2.61-6.92 6H6.1A5 5 0 0 1 11 6zm5.64 9.14A6.89 6.89 0 0 0 17.92 12H15.9a5 5 0 0 1-4.9 4c-1.38 0-2.63-.56-3.54-1.46L10 12H4v6l2.05-2.05A6.976 6.976 0 0 0 11 18c1.55 0 2.98-.51 4.14-1.36L20 21.49 21.49 20l-4.85-4.86z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fingerprint_24px"><path d="M17.81 4.47c-.08 0-.16-.02-.23-.06C15.66 3.42 14 3 12.01 3c-1.98 0-3.86.47-5.57 1.41a.51.51 0 0 1-.68-.2.506.506 0 0 1 .2-.68C7.82 2.52 9.86 2 12.01 2c2.13 0 3.99.47 6.03 1.52.25.13.34.43.21.67a.49.49 0 0 1-.44.28zM3.5 9.72a.5.5 0 0 1-.41-.79c.99-1.4 2.25-2.5 3.75-3.27C9.98 4.04 14 4.03 17.15 5.65c1.5.77 2.76 1.86 3.75 3.25a.5.5 0 0 1-.12.7.5.5 0 0 1-.7-.12 9.388 9.388 0 0 0-3.39-2.94c-2.87-1.47-6.54-1.47-9.4.01-1.36.7-2.5 1.7-3.4 2.96-.08.14-.23.21-.39.21zm6.25 12.07a.47.47 0 0 1-.35-.15c-.87-.87-1.34-1.43-2.01-2.64-.69-1.23-1.05-2.73-1.05-4.34 0-2.97 2.54-5.39 5.66-5.39s5.66 2.42 5.66 5.39c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-2.42-2.09-4.39-4.66-4.39-2.57 0-4.66 1.97-4.66 4.39 0 1.44.32 2.77.93 3.85.64 1.15 1.08 1.64 1.85 2.42.19.2.19.51 0 .71-.11.1-.24.15-.37.15zm7.17-1.85c-1.19 0-2.24-.3-3.1-.89-1.49-1.01-2.38-2.65-2.38-4.39 0-.28.22-.5.5-.5s.5.22.5.5c0 1.41.72 2.74 1.94 3.56.71.48 1.54.71 2.54.71.24 0 .64-.03 1.04-.1.27-.05.53.13.58.41.05.27-.13.53-.41.58-.57.11-1.07.12-1.21.12zM14.91 22c-.04 0-.09-.01-.13-.02-1.59-.44-2.63-1.03-3.72-2.1a7.297 7.297 0 0 1-2.17-5.22c0-1.62 1.38-2.94 3.08-2.94 1.7 0 3.08 1.32 3.08 2.94 0 1.07.93 1.94 2.08 1.94s2.08-.87 2.08-1.94c0-3.77-3.25-6.83-7.25-6.83-2.84 0-5.44 1.58-6.61 4.03-.39.81-.59 1.76-.59 2.8 0 .78.07 2.01.67 3.61.1.26-.03.55-.29.64-.26.1-.55-.04-.64-.29a11.14 11.14 0 0 1-.73-3.96c0-1.2.23-2.29.68-3.24 1.33-2.79 4.28-4.6 7.51-4.6 4.55 0 8.25 3.51 8.25 7.83 0 1.62-1.38 2.94-3.08 2.94s-3.08-1.32-3.08-2.94c0-1.07-.93-1.94-2.08-1.94s-2.08.87-2.08 1.94c0 1.71.66 3.31 1.87 4.51.95.94 1.86 1.46 3.27 1.85.27.07.42.35.35.61-.05.23-.26.38-.47.38z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flight_land_24px"><path d="M2.5 19h19v2h-19zm7.18-5.73l4.35 1.16 5.31 1.42c.8.21 1.62-.26 1.84-1.06.21-.8-.26-1.62-1.06-1.84l-5.31-1.42-2.76-9.02L10.12 2v8.28L5.15 8.95l-.93-2.32-1.45-.39v5.17l1.6.43 5.31 1.43z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flight_takeoff_24px"><path d="M2.5 19h19v2h-19zm19.57-9.36c-.21-.8-1.04-1.28-1.84-1.06L14.92 10l-6.9-6.43-1.93.51 4.14 7.17-4.97 1.33-1.97-1.54-1.45.39 1.82 3.16.77 1.33 1.6-.43 5.31-1.42 4.35-1.16L21 11.49c.81-.23 1.28-1.05 1.07-1.85z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flip_to_back_24px"><path d="M9 7H7v2h2V7zm0 4H7v2h2v-2zm0-8a2 2 0 0 0-2 2h2V3zm4 12h-2v2h2v-2zm6-12v2h2c0-1.1-.9-2-2-2zm-6 0h-2v2h2V3zM9 17v-2H7a2 2 0 0 0 2 2zm10-4h2v-2h-2v2zm0-4h2V7h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zM5 7H3v12a2 2 0 0 0 2 2h12v-2H5V7zm10-2h2V3h-2v2zm0 12h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flip_to_front_24px"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3a2 2 0 0 0 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_g_translate_24px"><path d="M20 5h-9.12L10 2H4c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h7l1 3h8c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zM7.17 14.59c-2.25 0-4.09-1.83-4.09-4.09s1.83-4.09 4.09-4.09c1.04 0 1.99.37 2.74 1.07l.07.06-1.23 1.18-.06-.05c-.29-.27-.78-.59-1.52-.59-1.31 0-2.38 1.09-2.38 2.42s1.07 2.42 2.38 2.42c1.37 0 1.96-.87 2.12-1.46H7.08V9.91h3.95l.01.07c.04.21.05.4.05.61 0 2.35-1.61 4-3.92 4zm6.03-1.71c.33.6.74 1.18 1.19 1.7l-.54.53-.65-2.23zm.77-.76h-.99l-.31-1.04h3.99s-.34 1.31-1.56 2.74a9.18 9.18 0 0 1-1.13-1.7zM21 20c0 .55-.45 1-1 1h-7l2-2-.81-2.77.92-.92L17.79 18l.73-.73-2.71-2.68c.9-1.03 1.6-2.25 1.92-3.51H19v-1.04h-3.64V9h-1.04v1.04h-1.96L11.18 6H20c.55 0 1 .45 1 1v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_gavel_24px"><path d="M1 21h12v2H1zM5.245 8.07l2.83-2.827 14.14 14.142-2.828 2.828zM12.317 1l5.657 5.656-2.83 2.83-5.654-5.66zM3.825 9.485l5.657 5.657-2.828 2.828-5.657-5.657z"/></symbol><symbol viewBox="0 0 24 24" id="ic_get_app_24px"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_gif_24px"><path d="M11.5 9H13v6h-1.5zM9 9H6c-.6 0-1 .5-1 1v4c0 .5.4 1 1 1h3c.6 0 1-.5 1-1v-2H8.5v1.5h-2v-3H10V10c0-.5-.4-1-1-1zm10 1.5V9h-4.5v6H16v-2h2v-1.5h-2v-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_grade_24px"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></symbol><symbol viewBox="0 0 24 24" id="ic_group_work_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM8 17.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5zM9.5 8a2.5 2.5 0 0 1 5 0 2.5 2.5 0 0 1-5 0zm6.5 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_help_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></symbol><symbol viewBox="0 0 24 24" id="ic_help_outline_24px"><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14a4 4 0 0 0-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_highlight_off_24px"><path d="M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_history_24px"><path d="M13 3a9 9 0 0 0-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42A8.954 8.954 0 0 0 13 21a9 9 0 0 0 0-18zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_home_24px"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hourglass_empty_24px"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hourglass_full_24px"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_http_24px"><path d="M4.5 11h-2V9H1v6h1.5v-2.5h2V15H6V9H4.5v2zm2.5-.5h1.5V15H10v-4.5h1.5V9H7v1.5zm5.5 0H14V15h1.5v-4.5H17V9h-4.5v1.5zm9-1.5H18v6h1.5v-2h2c.8 0 1.5-.7 1.5-1.5v-1c0-.8-.7-1.5-1.5-1.5zm0 2.5h-2v-1h2v1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_https_24px"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_important_devices_24px"><path d="M23 11.01L18 11c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-9c0-.55-.45-.99-1-.99zM23 20h-5v-7h5v7zM20 2H2C.89 2 0 2.89 0 4v12a2 2 0 0 0 2 2h7v2H7v2h8v-2h-2v-2h2v-2H2V4h18v5h2V4a2 2 0 0 0-2-2zm-8.03 7L11 6l-.97 3H7l2.47 1.76-.94 2.91 2.47-1.8 2.47 1.8-.94-2.91L15 9h-3.03z"/></symbol><symbol viewBox="0 0 24 24" id="ic_info_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_info_outline_24px"><path d="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_input_24px"><path d="M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14a2 2 0 0 0-2-2zM11 16l4-4-4-4v3H1v2h10v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_invert_colors_24px"><path d="M17.66 7.93L12 2.27 6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31A7.98 7.98 0 0 0 12 21.58c2.05 0 4.1-.78 5.66-2.34 3.12-3.12 3.12-8.19 0-11.31zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z"/></symbol><symbol viewBox="0 0 24 24" id="ic_label_24px"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_label_outline_24px"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16zM16 17H5V7h11l3.55 5L16 17z"/></symbol><symbol viewBox="0 0 24 24" id="ic_language_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95a15.65 15.65 0 0 0-1.38-3.56A8.03 8.03 0 0 1 18.92 8zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56A7.987 7.987 0 0 1 5.08 16zm2.95-8H5.08a7.987 7.987 0 0 1 4.33-3.56A15.65 15.65 0 0 0 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95a8.03 8.03 0 0 1-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"/></symbol><symbol viewBox="0 0 24 24" id="ic_launch_24px"><path d="M19 19H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_lightbulb_outline_24px"><path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 0 1 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_line_style_24px"><path d="M3 16h5v-2H3v2zm6.5 0h5v-2h-5v2zm6.5 0h5v-2h-5v2zM3 20h2v-2H3v2zm4 0h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM3 12h8v-2H3v2zm10 0h8v-2h-8v2zM3 4v4h18V4H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_line_weight_24px"><path d="M3 17h18v-2H3v2zm0 3h18v-1H3v1zm0-7h18v-3H3v3zm0-9v4h18V4H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_list_24px"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_lock_24px"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_lock_open_24px"><path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_lock_outline_24px"><path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM18 20H6V10h12v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_loyalty_24px"><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7zm11.77 8.27L13 19.54l-4.27-4.27A2.5 2.5 0 0 1 10.5 11c.69 0 1.32.28 1.77.74l.73.72.73-.73a2.5 2.5 0 0 1 3.54 3.54z"/></symbol><symbol viewBox="0 0 24 24" id="ic_markunread_mailbox_24px"><path d="M20 6H10v6H8V4h6V0H6v6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_motorcycle_24px"><path d="M19.44 9.03L15.41 5H11v2h3.59l2 2H5c-2.8 0-5 2.2-5 5s2.2 5 5 5c2.46 0 4.45-1.69 4.9-4h1.65l2.77-2.77c-.21.54-.32 1.14-.32 1.77 0 2.8 2.2 5 5 5s5-2.2 5-5c0-2.65-1.97-4.77-4.56-4.97zM7.82 15C7.4 16.15 6.28 17 5 17c-1.63 0-3-1.37-3-3s1.37-3 3-3c1.28 0 2.4.85 2.82 2H5v2h2.82zM19 17c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_note_add_24px"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14h-3v3h-2v-3H8v-2h3v-3h2v3h3v2zm-3-7V3.5L18.5 9H13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_offline_pin_24px"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm5 16H7v-2h10v2zm-6.7-4L7 10.7l1.4-1.4 1.9 1.9 5.3-5.3L17 7.3 10.3 14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_opacity_24px"><path d="M17.66 8L12 2.35 6.34 8A8.02 8.02 0 0 0 4 13.64c0 2 .78 4.11 2.34 5.67a7.99 7.99 0 0 0 11.32 0c1.56-1.56 2.34-3.67 2.34-5.67S19.22 9.56 17.66 8zM6 14c.01-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 17.99 12 18 14H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_open_in_browser_24px"><path d="M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6a2 2 0 0 0-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_open_in_new_24px"><path d="M19 19H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_open_with_24px"><path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pageview_24px"><path d="M11.5 9a2.5 2.5 0 0 0 0 5 2.5 2.5 0 0 0 0-5zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pan_tool_24px"><path d="M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_payment_24px"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_camera_mic_24px"><path d="M20 5h-3.17L15 3H9L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v-2.09c-2.83-.48-5-2.94-5-5.91h2c0 2.21 1.79 4 4 4s4-1.79 4-4h2c0 2.97-2.17 5.43-5 5.91V21h7c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-6 8c0 1.1-.9 2-2 2s-2-.9-2-2V9c0-1.1.9-2 2-2s2 .9 2 2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_contact_calendar_24px"><path d="M19 3h-1V1h-2v2H8V1H6v2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_data_setting_24px"><path d="M18.99 11.5c.34 0 .67.03 1 .07L20 0 0 20h11.56c-.04-.33-.07-.66-.07-1 0-4.14 3.36-7.5 7.5-7.5zm3.71 7.99c.02-.16.04-.32.04-.49 0-.17-.01-.33-.04-.49l1.06-.83a.26.26 0 0 0 .06-.32l-1-1.73c-.06-.11-.19-.15-.31-.11l-1.24.5c-.26-.2-.54-.37-.85-.49l-.19-1.32c-.01-.12-.12-.21-.24-.21h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.13-.59.29-.85.49l-1.24-.5c-.11-.04-.24 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.83a3.908 3.908 0 0 0 0 .98l-1.06.83a.26.26 0 0 0-.06.32l1 1.73c.06.11.19.15.31.11l1.24-.5c.26.2.54.37.85.49l.19 1.32c.02.12.12.21.25.21h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.59-.29.84-.49l1.25.5c.11.04.24 0 .31-.11l1-1.73a.26.26 0 0 0-.06-.32l-1.07-.83zm-3.71 1.01c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_device_information_24px"><path d="M13 7h-2v2h2V7zm0 4h-2v6h2v-6zm4-9.99L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_identity_24px"><path d="M12 5.9a2.1 2.1 0 1 1 0 4.2 2.1 2.1 0 0 1 0-4.2m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_media_24px"><path d="M2 6H0v5h.01L0 20c0 1.1.9 2 2 2h18v-2H2V6zm20-2h-8l-2-2H6c-1.1 0-1.99.9-1.99 2L4 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7 15l4.5-6 3.5 4.51 2.5-3.01L21 15H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_phone_msg_24px"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.074 15.074 0 0 1-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM12 3v10l3-3h6V3h-9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_perm_scan_wifi_24px"><path d="M12 3C6.95 3 3.15 4.85 0 7.23L12 22 24 7.25C20.85 4.87 17.05 3 12 3zm1 13h-2v-6h2v6zm-2-8V6h2v2h-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pets_24px"><circle cx="4.5" cy="9.5" r="2.5"/><circle cx="9" cy="5.5" r="2.5"/><circle cx="15" cy="5.5" r="2.5"/><circle cx="19.5" cy="9.5" r="2.5"/><path d="M17.34 14.86c-.87-1.02-1.6-1.89-2.48-2.91-.46-.54-1.05-1.08-1.75-1.32-.11-.04-.22-.07-.33-.09-.25-.04-.52-.04-.78-.04s-.53 0-.79.05c-.11.02-.22.05-.33.09-.7.24-1.28.78-1.75 1.32-.87 1.02-1.6 1.89-2.48 2.91-1.31 1.31-2.92 2.76-2.62 4.79.29 1.02 1.02 2.03 2.33 2.32.73.15 3.06-.44 5.54-.44h.18c2.48 0 4.81.58 5.54.44 1.31-.29 2.04-1.31 2.33-2.32.31-2.04-1.3-3.49-2.61-4.8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_picture_in_picture_24px"><path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"/></symbol><symbol viewBox="0 0 24 24" id="ic_picture_in_picture_alt_24px"><path d="M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V4.97h18v14.05z"/></symbol><symbol viewBox="0 0 24 24" id="ic_play_for_work_24px"><path d="M11 5v5.59H7.5l4.5 4.5 4.5-4.5H13V5h-2zm-5 9c0 3.31 2.69 6 6 6s6-2.69 6-6h-2c0 2.21-1.79 4-4 4s-4-1.79-4-4H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_polymer_24px"><path d="M19 4h-4L7.11 16.63 4.5 12 9 4H5L.5 12 5 20h4l7.89-12.63L19.5 12 15 20h4l4.5-8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_power_settings_new_24px"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42A6.92 6.92 0 0 1 19 12c0 3.87-3.13 7-7 7A6.995 6.995 0 0 1 7.58 6.58L6.17 5.17A8.932 8.932 0 0 0 3 12a9 9 0 0 0 18 0c0-2.74-1.23-5.18-3.17-6.83z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pregnant_woman_24px"><path d="M9 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm7 9a3.285 3.285 0 0 0-2-3c0-1.66-1.34-3-3-3s-3 1.34-3 3v7h2v5h3v-5h3v-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_print_24px"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_query_builder_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></symbol><symbol viewBox="0 0 24 24" id="ic_question_answer_24px"><path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_receipt_24px"><path d="M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z"/></symbol><symbol viewBox="0 0 24 24" id="ic_record_voice_over_24px"><circle cx="9" cy="9" r="4"/><path d="M9 15c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4zm7.76-9.64l-1.68 1.69c.84 1.18.84 2.71 0 3.89l1.68 1.69c2.02-2.02 2.02-5.07 0-7.27zM20.07 2l-1.63 1.63c2.77 3.02 2.77 7.56 0 10.74L20.07 16c3.9-3.89 3.91-9.95 0-14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_redeem_24px"><path d="M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68A3.01 3.01 0 0 0 9 2C7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_remove_shopping_cart_24px"><path d="M22.73 22.73L2.77 2.77 2 2l-.73-.73L0 2.54l4.39 4.39 2.21 4.66-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h7.46l1.38 1.38A1.997 1.997 0 0 0 17 22c.67 0 1.26-.33 1.62-.84L21.46 24l1.27-1.27zM7.42 15c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h2.36l2 2H7.42zm8.13-2c.75 0 1.41-.41 1.75-1.03l3.58-6.49A1.003 1.003 0 0 0 20 4H6.54l9.01 9zM7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_reorder_24px"><path d="M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_report_problem_24px"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_restore_24px"><path d="M13 3a9 9 0 0 0-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42A8.954 8.954 0 0 0 13 21a9 9 0 0 0 0-18zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_restore_page_24px"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm-2 16c-2.05 0-3.81-1.24-4.58-3h1.71c.63.9 1.68 1.5 2.87 1.5 1.93 0 3.5-1.57 3.5-3.5S13.93 9.5 12 9.5a3.5 3.5 0 0 0-3.1 1.9l1.6 1.6h-4V9l1.3 1.3C8.69 8.92 10.23 8 12 8c2.76 0 5 2.24 5 5s-2.24 5-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_room_24px"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rounded_corner_24px"><path d="M19 19h2v2h-2v-2zm0-2h2v-2h-2v2zM3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm0-4h2V3H3v2zm4 0h2V3H7v2zm8 16h2v-2h-2v2zm-4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm-8 0h2v-2H7v2zm-4 0h2v-2H3v2zM21 8c0-2.76-2.24-5-5-5h-5v2h5c1.65 0 3 1.35 3 3v5h2V8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rowing_24px"><path d="M8.5 14.5L4 19l1.5 1.5L9 17h2l-2.5-2.5zM15 1c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 20.01L18 24l-2.99-3.01V19.5l-7.1-7.09c-.31.05-.61.07-.91.07v-2.16c1.66.03 3.61-.87 4.67-2.04l1.4-1.55c.19-.21.43-.38.69-.5.29-.14.62-.23.96-.23h.03C15.99 6.01 17 7.02 17 8.26v5.75a3 3 0 0 1-.92 2.16l-3.58-3.58v-2.27c-.63.52-1.43 1.02-2.29 1.39L16.5 18H18l3 3.01z"/></symbol><symbol viewBox="0 0 24 24" id="ic_schedule_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></symbol><symbol viewBox="0 0 24 24" id="ic_search_24px"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_24px"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0 0 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_applications_24px"><path d="M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42a.353.353 0 0 1 .08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68l-1.48-1.16a.353.353 0 0 1-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_backup_restore_24px"><path d="M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9a9 9 0 0 0-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7a6.995 6.995 0 0 1-11.06 5.7l-1.42 1.44A9 9 0 1 0 12 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_bluetooth_24px"><path d="M11 24h2v-2h-2v2zm-4 0h2v-2H7v2zm8 0h2v-2h-2v2zm2.71-18.29L12 0h-1v7.59L6.41 3 5 4.41 10.59 10 5 15.59 6.41 17 11 12.41V20h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 3.83l1.88 1.88L13 7.59V3.83zm1.88 10.46L13 16.17v-3.76l1.88 1.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_brightness_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_cell_24px"><path d="M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM16 .01L8 0C6.9 0 6 .9 6 2v16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V2c0-1.1-.9-1.99-2-1.99zM16 16H8V4h8v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_ethernet_24px"><path d="M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_input_antenna_24px"><path d="M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29a2.5 2.5 0 0 0-5 0c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2a9 9 0 0 1 18 0h2c0-6.07-4.93-11-11-11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_input_component_24px"><path d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_input_composite_24px"><path d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_input_hdmi_24px"><path d="M18 7V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v3H5v6l3 6v3h8v-3l3-6V7h-1zM8 4h8v3h-2V5h-1v2h-2V5h-1v2H8V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_input_svideo_24px"><path d="M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_overscan_24px"><path d="M12.01 5.5L10 8h4l-1.99-2.5zM18 10v4l2.5-1.99L18 10zM6 10l-2.5 2.01L6 14v-4zm8 6h-4l2.01 2.5L14 16zm7-13H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_phone_24px"><path d="M13 9h-2v2h2V9zm4 0h-2v2h2V9zm3 6.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.074 15.074 0 0 1-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 9v2h2V9h-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_power_24px"><path d="M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm2-22h-2v10h2V2zm3.56 2.44l-1.45 1.45A5.97 5.97 0 0 1 18 11c0 3.31-2.69 6-6 6s-6-2.69-6-6c0-2.17 1.16-4.06 2.88-5.12L7.44 4.44A7.96 7.96 0 0 0 4 11c0 4.42 3.58 8 8 8s8-3.58 8-8a7.96 7.96 0 0 0-3.44-6.56zM15 24h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_remote_24px"><path d="M15 9H9c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V10c0-.55-.45-1-1-1zm-3 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM7.05 6.05l1.41 1.41a5.022 5.022 0 0 1 7.08 0l1.41-1.41C15.68 4.78 13.93 4 12 4s-3.68.78-4.95 2.05zM12 0C8.96 0 6.21 1.23 4.22 3.22l1.41 1.41C7.26 3.01 9.51 2 12 2s4.74 1.01 6.36 2.64l1.41-1.41C17.79 1.23 15.04 0 12 0z"/></symbol><symbol viewBox="0 0 24 24" id="ic_settings_voice_24px"><path d="M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9 4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54 5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31 6-6.72z"/></symbol><symbol viewBox="0 0 24 24" id="ic_shop_24px"><path d="M16 6V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H2v13c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6h-6zm-6-2h4v2h-4V4zM9 18V9l7.5 4L9 18z"/></symbol><symbol viewBox="0 0 24 24" id="ic_shop_two_24px"><path d="M3 9H1v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2H3V9zm15-4V3c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H5v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2V5h-5zm-6-2h4v2h-4V3zm0 12V8l5.5 3-5.5 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_shopping_basket_24px"><path d="M17.21 9l-4.38-6.56a.993.993 0 0 0-.83-.42c-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_shopping_cart_24px"><path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49A1.003 1.003 0 0 0 20 4H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_speaker_notes_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 14H6v-2h2v2zm0-3H6V9h2v2zm0-3H6V6h2v2zm7 6h-5v-2h5v2zm3-3h-8V9h8v2zm0-3h-8V6h8v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_speaker_notes_off_24px"><path d="M10.54 11l-.54-.54L7.54 8 6 6.46 2.38 2.84 1.27 1.73 0 3l2.01 2.01L2 22l4-4h9l5.73 5.73L22 22.46 17.54 18l-7-7zM8 14H6v-2h2v2zm-2-3V9l2 2H6zm14-9H4.08L10 7.92V6h8v2h-7.92l1 1H18v2h-4.92l6.99 6.99C21.14 17.95 22 17.08 22 16V4c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_spellcheck_24px"><path d="M12.45 16h2.09L9.43 3H7.57L2.46 16h2.09l1.12-3h5.64l1.14 3zm-6.02-5L8.5 5.48 10.57 11H6.43zm15.16.59l-8.09 8.09L9.83 16l-1.41 1.41 5.09 5.09L23 13l-1.41-1.41z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stars_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm4.24 16L12 15.45 7.77 18l1.12-4.81-3.73-3.23 4.92-.42L12 5l1.92 4.53 4.92.42-3.73 3.23L16.23 18z"/></symbol><symbol viewBox="0 0 24 24" id="ic_store_24px"><path d="M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_subject_24px"><path d="M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_supervisor_account_24px"><path d="M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7a2.5 2.5 0 0 0 0 5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_swap_horiz_24px"><path d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_swap_vert_24px"><path d="M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_swap_vertical_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM6.5 9L10 5.5 13.5 9H11v4H9V9H6.5zm11 6L14 18.5 10.5 15H13v-4h2v4h2.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_system_update_alt_24px"><path d="M12 16.5l4-4h-3v-9h-2v9H8l4 4zm9-13h-6v1.99h6v14.03H3V5.49h6V3.5H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-14c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tab_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tab_unselected_24px"><path d="M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_theaters_24px"><path d="M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_thumb_down_24px"><path d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_thumb_up_24px"><path d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_thumbs_up_down_24px"><path d="M12 6c0-.55-.45-1-1-1H5.82l.66-3.18.02-.23c0-.31-.13-.59-.33-.8L5.38 0 .44 4.94C.17 5.21 0 5.59 0 6v6.5c0 .83.67 1.5 1.5 1.5h6.75c.62 0 1.15-.38 1.38-.91l2.26-5.29c.07-.17.11-.36.11-.55V6zm10.5 4h-6.75c-.62 0-1.15.38-1.38.91l-2.26 5.29c-.07.17-.11.36-.11.55V18c0 .55.45 1 1 1h5.18l-.66 3.18-.02.24c0 .31.13.59.33.8l.79.78 4.94-4.94c.27-.27.44-.65.44-1.06v-6.5c0-.83-.67-1.5-1.5-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_timeline_24px"><path d="M23 8c0 1.1-.9 2-2 2a1.7 1.7 0 0 1-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2 2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55 4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02 9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55 2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56A1.7 1.7 0 0 1 19 8c0-1.1.9-2 2-2s2 .9 2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_toc_24px"><path d="M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_today_24px"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_toll_24px"><path d="M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12a5.99 5.99 0 0 1 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09A5.99 5.99 0 0 1 3 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_touch_app_24px"><path d="M9 11.24V7.5a2.5 2.5 0 0 1 5 0v3.74c1.21-.81 2-2.18 2-3.74C16 5.01 13.99 3 11.5 3S7 5.01 7 7.5c0 1.56.79 2.93 2 3.74zm9.84 4.63l-4.54-2.26c-.17-.07-.35-.11-.54-.11H13v-6c0-.83-.67-1.5-1.5-1.5S10 6.67 10 7.5v10.74l-3.43-.72c-.08-.01-.15-.03-.24-.03-.31 0-.59.13-.79.33l-.79.8 4.94 4.94c.27.27.65.44 1.06.44h6.79c.75 0 1.33-.55 1.44-1.28l.75-5.27c.01-.07.02-.14.02-.2 0-.62-.38-1.16-.91-1.38z"/></symbol><symbol viewBox="0 0 24 24" id="ic_track_changes_24px"><path d="M19.07 4.93l-1.41 1.41A8.014 8.014 0 0 1 20 12c0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93v2.02C8.16 6.57 6 9.03 6 12c0 3.31 2.69 6 6 6s6-2.69 6-6c0-1.66-.67-3.16-1.76-4.24l-1.41 1.41C15.55 9.9 16 10.9 16 12c0 2.21-1.79 4-4 4s-4-1.79-4-4c0-1.86 1.28-3.41 3-3.86v2.14c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V2h-1C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10a9.97 9.97 0 0 0-2.93-7.07z"/></symbol><symbol viewBox="0 0 24 24" id="ic_translate_24px"><path d="M12.87 15.07l-2.54-2.51.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></symbol><symbol viewBox="0 0 24 24" id="ic_trending_down_24px"><path d="M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_trending_flat_24px"><path d="M22 12l-4-4v3H3v2h15v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_trending_up_24px"><path d="M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_turned_in_24px"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_turned_in_not_24px"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_update_24px"><path d="M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1a6.875 6.875 0 0 0 0 9.79 7.02 7.02 0 0 0 9.88 0C18.32 15.65 19 14.08 19 12.1h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58a8.987 8.987 0 0 1 12.65 0L21 3v7.12zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8h1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_verified_user_24px"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_agenda_24px"><path d="M20 13H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zm0-10H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_array_24px"><path d="M4 18h3V5H4v13zM18 5v13h3V5h-3zM8 18h9V5H8v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_carousel_24px"><path d="M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_column_24px"><path d="M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_day_24px"><path d="M2 21h19v-3H2v3zM20 8H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zM2 3v3h19V3H2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_headline_24px"><path d="M4 15h16v-2H4v2zm0 4h16v-2H4v2zm0-8h16V9H4v2zm0-6v2h16V5H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_list_24px"><path d="M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_module_24px"><path d="M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_quilt_24px"><path d="M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_stream_24px"><path d="M4 18h17v-6H4v6zM4 5v6h17V5H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_week_24px"><path d="M6 5H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm14 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm-7 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_visibility_24px"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_visibility_off_24px"><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></symbol><symbol viewBox="0 0 24 24" id="ic_watch_later_24px"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_work_24px"><path d="M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_youtube_searched_for_24px"><path d="M17.01 14h-.8l-.27-.27a6.45 6.45 0 0 0 1.57-4.23c0-3.59-2.91-6.5-6.5-6.5s-6.5 3-6.5 6.5H2l3.84 4 4.16-4H6.51a4.5 4.5 0 0 1 9 0 4.507 4.507 0 0 1-6.32 4.12L7.71 15.1a6.474 6.474 0 0 0 7.52-.67l.27.27v.79l5.01 4.99L22 19l-4.99-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_zoom_in_24px"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zm2.5-4h-2v2H9v-2H7V9h2V7h1v2h2v1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_zoom_out_24px"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-alert-symbol.svg b/skyquake/framework/style/icons/svg-sprite-alert-symbol.svg
new file mode 100755 (executable)
index 0000000..5c350e8
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_add_alert_24px"><path d="M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72A6.873 6.873 0 0 0 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z"/></symbol><symbol viewBox="0 0 24 24" id="ic_error_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_error_outline_24px"><path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_warning_24px"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-av-symbol.svg b/skyquake/framework/style/icons/svg-sprite-av-symbol.svg
new file mode 100755 (executable)
index 0000000..84aaa88
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_add_to_queue_24px"><path d="M21 3H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5a2 2 0 0 0-2-2zm0 14H3V5h18v12zm-5-7v2h-3v3h-2v-3H8v-2h3V7h2v3h3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airplay_24px"><path d="M6 22h12l-6-6zM21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4v-2H3V5h18v12h-4v2h4c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_album_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_art_track_24px"><path fill="#010101" d="M22 13h-8v-2h8v2zm0-6h-8v2h8V7zm-8 10h8v-2h-8v2zm-2-8v6c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V9c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2zm-1.5 6l-2.25-3-1.75 2.26-1.25-1.51L3.5 15h7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_av_timer_24px"><path d="M11 17c0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1-1 .45-1 1zm0-14v4h2V5.08c3.39.49 6 3.39 6 6.92 0 3.87-3.13 7-7 7s-7-3.13-7-7c0-1.68.59-3.22 1.58-4.42L12 13l1.41-1.41-6.8-6.8v.02C4.42 6.45 3 9.05 3 12c0 4.97 4.02 9 9 9a9 9 0 0 0 0-18h-1zm7 9c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zM6 12c0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1-1 .45-1 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_branding_watermark_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16h-9v-6h9v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_to_action_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3v-3h18v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_closed_caption_24px"><path d="M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_equalizer_24px"><path d="M10 20h4V4h-4v16zm-6 0h4v-8H4v8zM16 9v11h4V9h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_explicit_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h4v2h-4v2h4v2H9V7h6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fast_forward_24px"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fast_rewind_24px"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_featured_play_list_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 8H3V9h9v2zm0-4H3V5h9v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_featured_video_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 9H3V5h9v7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fiber_dvr_24px"><path d="M17.5 10.5h2v1h-2zm-13 0h2v3h-2zM21 3H3c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h18a2 2 0 0 0 2-2V5c0-1.11-.89-2-2-2zM8 13.5c0 .85-.65 1.5-1.5 1.5H3V9h3.5c.85 0 1.5.65 1.5 1.5v3zm4.62 1.5h-1.5L9.37 9h1.5l1 3.43 1-3.43h1.5l-1.75 6zM21 11.5c0 .6-.4 1.15-.9 1.4L21 15h-1.5l-.85-2H17.5v2H16V9h3.5c.85 0 1.5.65 1.5 1.5v1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fiber_manual_record_24px"><circle fill="#010101" cx="12" cy="12" r="8"/></symbol><symbol viewBox="0 0 24 24" id="ic_fiber_new_24px"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zM8.5 15H7.3l-2.55-3.5V15H3.5V9h1.25l2.5 3.5V9H8.5v6zm5-4.74H11v1.12h2.5v1.26H11v1.11h2.5V15h-4V9h4v1.26zm7 3.74c0 .55-.45 1-1 1h-4c-.55 0-1-.45-1-1V9h1.25v4.51h1.13V9.99h1.25v3.51h1.12V9h1.25v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fiber_pin_24px"><path d="M5.5 10.5h2v1h-2zM20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zM9 11.5c0 .85-.65 1.5-1.5 1.5h-2v2H4V9h3.5c.85 0 1.5.65 1.5 1.5v1zm3.5 3.5H11V9h1.5v6zm7.5 0h-1.2l-2.55-3.5V15H15V9h1.25l2.5 3.5V9H20v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fiber_smart_record_24px"><g fill="#010101"><circle cx="9" cy="12" r="8"/><path d="M17 4.26v2.09a5.99 5.99 0 0 1 0 11.3v2.09c3.45-.89 6-4.01 6-7.74s-2.55-6.85-6-7.74z"/></g></symbol><symbol viewBox="0 0 24 24" id="ic_forward_10_24px"><path d="M4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8zm6.8 3H10v-3.3L9 13v-.7l1.8-.6h.1V16zm4.3-1.8c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_forward_30_24px"><path d="M9.6 13.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5zM4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_forward_5_24px"><path d="M4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8zm6.7.9l.2-2.2h2.4v.7h-1.7l-.1.9s.1 0 .1-.1.1 0 .1-.1.1 0 .2 0h.2c.2 0 .4 0 .5.1s.3.2.4.3.2.3.3.5.1.4.1.6c0 .2 0 .4-.1.5s-.1.3-.3.5-.3.2-.5.3-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.3-.1-.5h.8c0 .2.1.3.2.4s.2.1.4.1c.1 0 .2 0 .3-.1l.2-.2s.1-.2.1-.3v-.6l-.1-.2-.2-.2s-.2-.1-.3-.1h-.2s-.1 0-.2.1-.1 0-.1.1-.1.1-.1.1h-.6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_games_24px"><path d="M15 7.5V2H9v5.5l3 3 3-3zM7.5 9H2v6h5.5l3-3-3-3zM9 16.5V22h6v-5.5l-3-3-3 3zM16.5 9l-3 3 3 3H22V9h-5.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hd_24px"><path d="M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm2-6h4c.55 0 1 .45 1 1v4c0 .55-.45 1-1 1h-4V9zm1.5 4.5h2v-3h-2v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hearing_24px"><path d="M17 20c-.29 0-.56-.06-.76-.15-.71-.37-1.21-.88-1.71-2.38-.51-1.56-1.47-2.29-2.39-3-.79-.61-1.61-1.24-2.32-2.53C9.29 10.98 9 9.93 9 9c0-2.8 2.2-5 5-5s5 2.2 5 5h2c0-3.93-3.07-7-7-7S7 5.07 7 9c0 1.26.38 2.65 1.07 3.9.91 1.65 1.98 2.48 2.85 3.15.81.62 1.39 1.07 1.71 2.05.6 1.82 1.37 2.84 2.73 3.55A4 4 0 0 0 21 18h-2c0 1.1-.9 2-2 2zM7.64 2.64L6.22 1.22C4.23 3.21 3 5.96 3 9s1.23 5.79 3.22 7.78l1.41-1.41C6.01 13.74 5 11.49 5 9s1.01-4.74 2.64-6.36zM11.5 9a2.5 2.5 0 0 0 5 0 2.5 2.5 0 0 0-5 0z"/></symbol><symbol viewBox="0 0 24 24" id="ic_high_quality_24px"><path d="M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 11H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_library_add_24px"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_library_books_24px"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_library_music_24px"><path d="M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 5h-3v5.5a2.5 2.5 0 0 1-5 0 2.5 2.5 0 0 1 2.5-2.5c.57 0 1.08.19 1.5.51V5h4v2zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_loop_24px"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0 0 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 0 0 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mic_24px"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mic_none_24px"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1.2-9.1c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2l-.01 6.2c0 .66-.53 1.2-1.19 1.2-.66 0-1.2-.54-1.2-1.2V4.9zm6.5 6.1c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mic_off_24px"><path d="M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3L3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_movie_24px"><path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_music_video_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14zM8 15c0-1.66 1.34-3 3-3 .35 0 .69.07 1 .18V6h5v2h-3v7.03A3.003 3.003 0 0 1 11 18c-1.66 0-3-1.34-3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_new_releases_24px"><path d="M23 12l-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12zm-10 5h-2v-2h2v2zm0-4h-2V7h2v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_not_interested_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31A7.902 7.902 0 0 1 12 20zm6.31-3.1L7.1 5.69A7.902 7.902 0 0 1 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_note_24px"><path d="M22 10l-6-6H4c-1.1 0-2 .9-2 2v12.01c0 1.1.9 1.99 2 1.99l16-.01c1.1 0 2-.89 2-1.99v-8zm-7-4.5l5.5 5.5H15V5.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pause_24px"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pause_circle_filled_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pause_circle_outline_24px"><path d="M9 16h2V8H9v8zm3-14C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm1-4h2V8h-2v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_play_arrow_24px"><path d="M8 5v14l11-7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_play_circle_filled_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_play_circle_outline_24px"><path d="M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_playlist_add_24px"><path d="M14 10H2v2h12v-2zm0-4H2v2h12V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2 16h8v-2H2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_playlist_add_check_24px"><path d="M14 10H2v2h12v-2zm0-4H2v2h12V6zM2 16h8v-2H2v2zm19.5-4.5L23 13l-6.99 7-4.51-4.5L13 14l3.01 3 5.49-5.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_playlist_play_24px"><path d="M19 9H2v2h17V9zm0-4H2v2h17V5zM2 15h13v-2H2v2zm15-2v6l5-3-5-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_queue_24px"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_queue_music_24px"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_queue_play_next_24px"><path d="M21 3H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h5v2h8v-2h2v-2H3V5h18v8h2V5a2 2 0 0 0-2-2zm-8 7V7h-2v3H8v2h3v3h2v-3h3v-2h-3zm11 8l-4.5 4.5L18 21l3-3-3-3 1.5-1.5L24 18z"/></symbol><symbol viewBox="0 0 24 24" id="ic_radio_24px"><path d="M3.24 6.15C2.51 6.43 2 7.17 2 8v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8c0-1.11-.89-2-2-2H8.3l8.26-3.34L15.88 1 3.24 6.15zM7 20c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-8h-2v-2h-2v2H4V8h16v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_recent_actors_24px"><path d="M21 5v14h2V5h-2zm-4 14h2V5h-2v14zM14 5H2c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zM8 7.75c1.24 0 2.25 1.01 2.25 2.25S9.24 12.25 8 12.25 5.75 11.24 5.75 10 6.76 7.75 8 7.75zM12.5 17h-9v-.75c0-1.5 3-2.25 4.5-2.25s4.5.75 4.5 2.25V17z"/></symbol><symbol viewBox="0 0 24 24" id="ic_remove_from_queue_24px"><path d="M21 3H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5a2 2 0 0 0-2-2zm0 14H3V5h18v12zm-5-7v2H8v-2h8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_repeat_24px"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_repeat_one_24px"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_replay_10_24px"><path d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-1.1 11H10v-3.3L9 13v-.7l1.8-.6h.1V16zm4.3-1.8c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1c.2.1.3.2.5.3s.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_replay_24px"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_replay_30_24px"><path d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-2.4 8.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5c0-.1-.1-.2-.1-.3s-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_replay_5_24px"><path d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-1.3 8.9l.2-2.2h2.4v.7h-1.7l-.1.9s.1 0 .1-.1.1 0 .1-.1.1 0 .2 0h.2c.2 0 .4 0 .5.1s.3.2.4.3.2.3.3.5.1.4.1.6c0 .2 0 .4-.1.5s-.1.3-.3.5-.3.2-.4.3-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.3-.1-.5h.8c0 .2.1.3.2.4s.2.1.4.1c.1 0 .2 0 .3-.1l.2-.2s.1-.2.1-.3v-.6l-.1-.2-.2-.2s-.2-.1-.3-.1h-.2s-.1 0-.2.1-.1 0-.1.1-.1.1-.1.1h-.7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_shuffle_24px"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_skip_next_24px"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_skip_previous_24px"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_slow_motion_video_24px"><path d="M13.05 9.79L10 7.5v9l3.05-2.29L16 12zm0 0L10 7.5v9l3.05-2.29L16 12zm0 0L10 7.5v9l3.05-2.29L16 12zM11 4.07V2.05c-2.01.2-3.84 1-5.32 2.21L7.1 5.69A7.94 7.94 0 0 1 11 4.07zM5.69 7.1L4.26 5.68A9.95 9.95 0 0 0 2.05 11h2.02a7.94 7.94 0 0 1 1.62-3.9zM4.07 13H2.05c.2 2.01 1 3.84 2.21 5.32l1.43-1.43A7.868 7.868 0 0 1 4.07 13zm1.61 6.74A9.98 9.98 0 0 0 11 21.95v-2.02a7.94 7.94 0 0 1-3.9-1.62l-1.42 1.43zM22 12c0 5.16-3.92 9.42-8.95 9.95v-2.02C16.97 19.41 20 16.05 20 12s-3.03-7.41-6.95-7.93V2.05C18.08 2.58 22 6.84 22 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_snooze_24px"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9a9 9 0 0 0 0-18zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-3-9h3.63L9 15.2V17h6v-2h-3.63L15 10.8V9H9v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sort_by_alpha_24px"><path d="M14.94 4.66h-4.72l2.36-2.36zm-4.69 14.71h4.66l-2.33 2.33zM6.1 6.27L1.6 17.73h1.84l.92-2.45h5.11l.92 2.45h1.84L7.74 6.27H6.1zm-1.13 7.37l1.94-5.18 1.94 5.18H4.97zm10.76 2.5h6.12v1.59h-8.53v-1.29l5.92-8.56h-5.88v-1.6h8.3v1.26l-5.93 8.6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stop_24px"><path d="M6 6h12v12H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_subscriptions_24px"><path d="M20 8H4V6h16v2zm-2-6H6v2h12V2zm4 10v8c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2v-8c0-1.1.9-2 2-2h16c1.1 0 2 .9 2 2zm-6 4l-6-3.27v6.53L16 16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_subtitles_24px"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_surround_sound_24px"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7.76 16.24l-1.41 1.41A7.91 7.91 0 0 1 4 12c0-2.05.78-4.1 2.34-5.66l1.41 1.41C6.59 8.93 6 10.46 6 12s.59 3.07 1.76 4.24zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm5.66 1.66l-1.41-1.41C17.41 15.07 18 13.54 18 12s-.59-3.07-1.76-4.24l1.41-1.41A7.91 7.91 0 0 1 20 12c0 2.05-.78 4.1-2.34 5.66zM12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_video_call_24px"><path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4zM14 13h-3v3H9v-3H6v-2h3V8h2v3h3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_video_label_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 13H3V5h18v11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_video_library_24px"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8 12.5v-9l6 4.5-6 4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_videocam_24px"><path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_videocam_off_24px"><path d="M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_volume_down_24px"><path d="M18.5 12A4.5 4.5 0 0 0 16 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_volume_mute_24px"><path d="M7 9v6h4l5 5V4l-5 5H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_volume_off_24px"><path d="M16.5 12A4.5 4.5 0 0 0 14 7.97v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_volume_up_24px"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></symbol><symbol viewBox="0 0 24 24" id="ic_web_24px"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_web_asset_24px"><path fill="#010101" d="M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6a2 2 0 0 0-2-2zm0 14H5V8h14v10z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-communication-symbol.svg b/skyquake/framework/style/icons/svg-sprite-communication-symbol.svg
new file mode 100755 (executable)
index 0000000..7b0a620
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_business_24px"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_24px"><path d="M6.62 10.79a15.15 15.15 0 0 0 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_end_24px"><path d="M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08a.956.956 0 0 1-.29-.7c0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28a11.27 11.27 0 0 0-2.67-1.85.996.996 0 0 1-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_made_24px"><path d="M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_merge_24px"><path d="M17 20.41L18.41 19 15 15.59 13.59 17 17 20.41zM7.5 8H11v5.59L5.59 19 7 20.41l6-6V8h3.5L12 3.5 7.5 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_missed_24px"><path d="M19.59 7L12 14.59 6.41 9H11V7H3v8h2v-4.59l7 7 9-9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_missed_outgoing_24px"><path d="M3 8.41l9 9 7-7V15h2V7h-8v2h4.59L12 14.59 4.41 7 3 8.41z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_received_24px"><path d="M20 5.41L18.59 4 7 15.59V9H5v10h10v-2H8.41z"/></symbol><symbol viewBox="0 0 24 24" id="ic_call_split_24px"><path d="M14 4l2.29 2.29-2.88 2.88 1.42 1.42 2.88-2.88L20 10V4zm-4 0H4v6l2.29-2.29 4.71 4.7V20h2v-8.41l-5.29-5.3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_chat_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_chat_bubble_24px"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_chat_bubble_outline_24px"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_clear_all_24px"><path d="M5 13h14v-2H5v2zm-2 4h14v-2H3v2zM7 7v2h14V7H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_comment_24px"><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18zM18 14H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_contact_mail_24px"><path d="M21 8V7l-3 2-3-2v1l3 2 3-2zm1-5H2C.9 3 0 3.9 0 5v14c0 1.1.9 2 2 2h20c1.1 0 1.99-.9 1.99-2L24 5c0-1.1-.9-2-2-2zM8 6c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H2v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1zm8-6h-8V6h8v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_contact_phone_24px"><path d="M22 3H2C.9 3 0 3.9 0 5v14c0 1.1.9 2 2 2h20c1.1 0 1.99-.9 1.99-2L24 5c0-1.1-.9-2-2-2zM8 6c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H2v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1zm3.85-4h1.64L21 16l-1.99 1.99A7.512 7.512 0 0 1 16.28 14c-.18-.64-.28-1.31-.28-2s.1-1.36.28-2a7.474 7.474 0 0 1 2.73-3.99L21 8l-1.51 2h-1.64c-.22.63-.35 1.3-.35 2s.13 1.37.35 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_contacts_24px"><path d="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25 2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5 .83 5 2.5V17z"/></symbol><symbol viewBox="0 0 24 24" id="ic_dialer_sip_24px"><path d="M17 3h-1v5h1V3zm-2 2h-2V4h2V3h-3v3h2v1h-2v1h3V5zm3-2v5h1V6h2V3h-3zm2 2h-1V4h1v1zm0 10.5c-1.25 0-2.45-.2-3.57-.57a.998.998 0 0 0-1.01.24l-2.2 2.2a15.045 15.045 0 0 1-6.59-6.59l2.2-2.21c.27-.26.35-.65.24-1A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_dialpad_24px"><path d="M12 19c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zM6 1c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12-8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-6 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_email_24px"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_forum_24px"><path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_import_contacts_24px"><path d="M21 5c-1.11-.35-2.33-.5-3.5-.5-1.95 0-4.05.4-5.5 1.5-1.45-1.1-3.55-1.5-5.5-1.5S2.45 4.9 1 6v14.65c0 .25.25.5.5.5.1 0 .15-.05.25-.05C3.1 20.45 5.05 20 6.5 20c1.95 0 4.05.4 5.5 1.5 1.35-.85 3.8-1.5 5.5-1.5 1.65 0 3.35.3 4.75 1.05.1.05.15.05.25.05.25 0 .5-.25.5-.5V6c-.6-.45-1.25-.75-2-1zm0 13.5c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5V8c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5v11.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_import_export_24px"><path d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_invert_colors_off_24px"><path d="M20.65 20.87l-2.35-2.35-6.3-6.29-3.56-3.57-1.42-1.41L4.27 4.5 3 5.77l2.78 2.78a8.005 8.005 0 0 0 .56 10.69A7.98 7.98 0 0 0 12 21.58c1.79 0 3.57-.59 5.03-1.78l2.7 2.7L21 21.23l-.35-.36zM12 19.59c-1.6 0-3.11-.62-4.24-1.76A5.945 5.945 0 0 1 6 13.59c0-1.32.43-2.57 1.21-3.6L12 14.77v4.82zM12 5.1v4.58l7.25 7.26c1.37-2.96.84-6.57-1.6-9.01L12 2.27l-3.7 3.7 1.41 1.41L12 5.1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_live_help_24px"><path d="M19 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 16h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 11.9 13 12.5 13 14h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></symbol><symbol viewBox="0 0 24 24" id="ic_location_off_24px"><path d="M12 6.5A2.5 2.5 0 0 1 14.5 9c0 .74-.33 1.39-.83 1.85l3.63 3.63c.98-1.86 1.7-3.8 1.7-5.48 0-3.87-3.13-7-7-7a7 7 0 0 0-5.04 2.15l3.19 3.19c.46-.52 1.11-.84 1.85-.84zm4.37 9.6l-4.63-4.63-.11-.11L3.27 3 2 4.27l3.18 3.18C5.07 7.95 5 8.47 5 9c0 5.25 7 13 7 13s1.67-1.85 3.38-4.35L18.73 21 20 19.73l-3.63-3.63z"/></symbol><symbol viewBox="0 0 24 24" id="ic_location_on_24px"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mail_outline_24px"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8l8 5 8-5v10zm-8-7L4 6h16l-8 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_message_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_no_sim_24px"><path d="M18.99 5c0-1.1-.89-2-1.99-2h-7L7.66 5.34 19 16.68 18.99 5zM3.65 3.88L2.38 5.15 5 7.77V19c0 1.1.9 2 2 2h10.01c.35 0 .67-.1.96-.26l1.88 1.88 1.27-1.27L3.65 3.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_24px"><path d="M6.62 10.79a15.15 15.15 0 0 0 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phonelink_erase_24px"><path d="M13 8.2l-1-1-4 4-4-4-1 1 4 4-4 4 1 1 4-4 4 4 1-1-4-4 4-4zM19 1H9c-1.1 0-2 .9-2 2v3h2V4h10v16H9v-2H7v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phonelink_lock_24px"><path d="M19 1H9c-1.1 0-2 .9-2 2v3h2V4h10v16H9v-2H7v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm-8.2 10V9.5C10.8 8.1 9.4 7 8 7S5.2 8.1 5.2 9.5V11c-.6 0-1.2.6-1.2 1.2v3.5c0 .7.6 1.3 1.2 1.3h5.5c.7 0 1.3-.6 1.3-1.2v-3.5c0-.7-.6-1.3-1.2-1.3zm-1.3 0h-3V9.5c0-.8.7-1.3 1.5-1.3s1.5.5 1.5 1.3V11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phonelink_ring_24px"><path d="M20.1 7.7l-1 1c1.8 1.8 1.8 4.6 0 6.5l1 1c2.5-2.3 2.5-6.1 0-8.5zM18 9.8l-1 1c.5.7.5 1.6 0 2.3l1 1c1.2-1.2 1.2-3 0-4.3zM14 1H4c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 19H4V4h10v16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phonelink_setup_24px"><path d="M11.8 12.5v-1l1.1-.8c.1-.1.1-.2.1-.3l-1-1.7c-.1-.1-.2-.2-.3-.1l-1.3.4c-.3-.2-.6-.4-.9-.5l-.2-1.3c0-.1-.1-.2-.3-.2H7c-.1 0-.2.1-.3.2l-.2 1.3c-.3.1-.6.3-.9.5l-1.3-.5c-.1 0-.2 0-.3.1l-1 1.7c-.1.1 0 .2.1.3l1.1.8v1l-1.1.8c-.1.2-.1.3-.1.4l1 1.7c.1.1.2.2.3.1l1.4-.4c.3.2.6.4.9.5l.2 1.3c-.1.1.1.2.2.2h2c.1 0 .2-.1.3-.2l.2-1.3c.3-.1.6-.3.9-.5l1.3.5c.1 0 .2 0 .3-.1l1-1.7c.1-.1 0-.2-.1-.3l-1.1-.9zM8 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM19 1H9c-1.1 0-2 .9-2 2v3h2V4h10v16H9v-2H7v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_portable_wifi_off_24px"><path d="M17.56 14.24c.28-.69.44-1.45.44-2.24 0-3.31-2.69-6-6-6-.79 0-1.55.16-2.24.44l1.62 1.62c.2-.03.41-.06.62-.06a4 4 0 0 1 3.95 4.63l1.61 1.61zM12 4c4.42 0 8 3.58 8 8 0 1.35-.35 2.62-.95 3.74l1.47 1.47A9.86 9.86 0 0 0 22 12c0-5.52-4.48-10-10-10-1.91 0-3.69.55-5.21 1.47l1.46 1.46A8.04 8.04 0 0 1 12 4zM3.27 2.5L2 3.77l2.1 2.1C2.79 7.57 2 9.69 2 12c0 3.7 2.01 6.92 4.99 8.65l1-1.73C5.61 17.53 4 14.96 4 12c0-1.76.57-3.38 1.53-4.69l1.43 1.44C6.36 9.68 6 10.8 6 12c0 2.22 1.21 4.15 3 5.19l1-1.74c-1.19-.7-2-1.97-2-3.45 0-.65.17-1.25.44-1.79l1.58 1.58L10 12c0 1.1.9 2 2 2l.21-.02.01.01 7.51 7.51L21 20.23 4.27 3.5l-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_present_to_all_24px"><path d="M21 3H3c-1.11 0-2 .89-2 2v14c0 1.11.89 2 2 2h18c1.11 0 2-.89 2-2V5c0-1.11-.89-2-2-2zm0 16.02H3V4.98h18v14.04zM10 12H8l4-4 4 4h-2v4h-4v-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_ring_volume_24px"><path d="M23.71 16.67A16.97 16.97 0 0 0 12 12C7.46 12 3.34 13.78.29 16.67c-.18.18-.29.43-.29.71 0 .28.11.53.29.71l2.48 2.48c.18.18.43.29.71.29.27 0 .52-.11.7-.28.79-.74 1.69-1.36 2.66-1.85.33-.16.56-.5.56-.9v-3.1c1.45-.48 3-.73 4.6-.73s3.15.25 4.6.72v3.1c0 .39.23.74.56.9.98.49 1.87 1.12 2.66 1.85.18.18.43.28.7.28.28 0 .53-.11.71-.29l2.48-2.48c.18-.18.29-.43.29-.71a.99.99 0 0 0-.29-.7zM21.16 6.26l-1.41-1.41-3.56 3.55 1.41 1.41s3.45-3.52 3.56-3.55zM13 2h-2v5h2V2zM6.4 9.81L7.81 8.4 4.26 4.84 2.84 6.26c.11.03 3.56 3.55 3.56 3.55z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rss_feed_24px"><circle cx="6.18" cy="17.82" r="2.18"/><path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_screen_share_24px"><path d="M20 18c1.1 0 1.99-.9 1.99-2L22 6a2 2 0 0 0-2-2H4c-1.11 0-2 .89-2 2v10a2 2 0 0 0 2 2H0v2h24v-2h-4zm-7-3.53v-2.19c-2.78 0-4.61.85-6 2.72.56-2.67 2.11-5.33 6-5.87V7l4 3.73-4 3.74z"/></symbol><symbol viewBox="0 0 24 24" id="ic_speaker_phone_24px"><path d="M7 7.07L8.43 8.5c.91-.91 2.18-1.48 3.57-1.48s2.66.57 3.57 1.48L17 7.07C15.72 5.79 13.95 5 12 5s-3.72.79-5 2.07zM12 1C8.98 1 6.24 2.23 4.25 4.21l1.41 1.41C7.28 4 9.53 3 12 3s4.72 1 6.34 2.62l1.41-1.41A10.963 10.963 0 0 0 12 1zm2.86 9.01L9.14 10C8.51 10 8 10.51 8 11.14v9.71c0 .63.51 1.14 1.14 1.14h5.71c.63 0 1.14-.51 1.14-1.14v-9.71c.01-.63-.5-1.13-1.13-1.13zM15 20H9v-8h6v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stay_current_landscape_24px"><path d="M1.01 7L1 17c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2H3c-1.1 0-1.99.9-1.99 2zM19 7v10H5V7h14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stay_current_portrait_24px"><path d="M17 1.01L7 1c-1.1 0-1.99.9-1.99 2v18c0 1.1.89 2 1.99 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stay_primary_landscape_24px"><path d="M1.01 7L1 17c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2H3c-1.1 0-1.99.9-1.99 2zM19 7v10H5V7h14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stay_primary_portrait_24px"><path d="M17 1.01L7 1c-1.1 0-1.99.9-1.99 2v18c0 1.1.89 2 1.99 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_stop_screen_share_24px"><path d="M21.22 18.02l2 2H24v-2h-2.78zm.77-2l.01-10a2 2 0 0 0-2-2H7.22l5.23 5.23c.18-.04.36-.07.55-.1V7.02l4 3.73-1.58 1.47 5.54 5.54c.61-.33 1.03-.99 1.03-1.74zM2.39 1.73L1.11 3l1.54 1.54c-.4.36-.65.89-.65 1.48v10a2 2 0 0 0 2 2H0v2h18.13l2.71 2.71 1.27-1.27L2.39 1.73zM7 15.02c.31-1.48.92-2.95 2.07-4.06l1.59 1.59c-1.54.38-2.7 1.18-3.66 2.47z"/></symbol><symbol viewBox="0 0 24 24" id="ic_swap_calls_24px"><path d="M18 4l-4 4h3v7c0 1.1-.9 2-2 2s-2-.9-2-2V8c0-2.21-1.79-4-4-4S5 5.79 5 8v7H2l4 4 4-4H7V8c0-1.1.9-2 2-2s2 .9 2 2v7c0 2.21 1.79 4 4 4s4-1.79 4-4V8h3l-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_textsms_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_voicemail_24px"><path d="M18.5 6C15.46 6 13 8.46 13 11.5c0 1.33.47 2.55 1.26 3.5H9.74A5.45 5.45 0 0 0 11 11.5C11 8.46 8.54 6 5.5 6S0 8.46 0 11.5 2.46 17 5.5 17h13c3.04 0 5.5-2.46 5.5-5.5S21.54 6 18.5 6zm-13 9C3.57 15 2 13.43 2 11.5S3.57 8 5.5 8 9 9.57 9 11.5 7.43 15 5.5 15zm13 0c-1.93 0-3.5-1.57-3.5-3.5S16.57 8 18.5 8 22 9.57 22 11.5 20.43 15 18.5 15z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vpn_key_24px"><path d="M12.65 10A5.99 5.99 0 0 0 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6a5.99 5.99 0 0 0 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-content-symbol.svg b/skyquake/framework/style/icons/svg-sprite-content-symbol.svg
new file mode 100755 (executable)
index 0000000..65dd1a9
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_add_24px"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_add_box_24px"><path d="M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_add_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_add_circle_outline_24px"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_archive_24px"><path d="M20.54 5.23l-1.39-1.68A1.45 1.45 0 0 0 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_backspace_24px"><path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z"/></symbol><symbol viewBox="0 0 24 24" id="ic_block_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9A7.902 7.902 0 0 1 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1A7.902 7.902 0 0 1 20 12c0 4.42-3.58 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_clear_24px"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_content_copy_24px"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_content_cut_24px"><path d="M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_content_paste_24px"><path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_create_24px"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a.996.996 0 0 0 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></symbol><symbol viewBox="0 0 24 24" id="ic_delete_sweep_24px"><path d="M15 16h4v2h-4zm0-8h7v2h-7zm0 4h6v2h-6zM3 18c0 1.1.9 2 2 2h6c1.1 0 2-.9 2-2V8H3v10zM14 5h-3l-1-1H6L5 5H2v2h12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_drafts_24px"><path d="M21.99 8c0-.72-.37-1.35-.94-1.7L12 1 2.95 6.3C2.38 6.65 2 7.28 2 8v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2l-.01-10zM12 13L3.74 7.84 12 3l8.26 4.84L12 13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_list_24px"><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flag_24px"><path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_font_download_24px"><path d="M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z"/></symbol><symbol viewBox="0 0 24 24" id="ic_forward_24px"><path d="M12 8V4l8 8-8 8v-4H4V8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_gesture_24px"><path d="M4.59 6.89c.7-.71 1.4-1.35 1.71-1.22.5.2 0 1.03-.3 1.52-.25.42-2.86 3.89-2.86 6.31 0 1.28.48 2.34 1.34 2.98.75.56 1.74.73 2.64.46 1.07-.31 1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78.64-5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33 4.69-6.1H21v-2.5h-2.47c-.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94 2.84-.58.73-2.06 2.48-2.29 2.72-.25.3-.68.84-1.11.84-.45 0-.72-.83-.36-1.92.35-1.09 1.4-2.86 1.85-3.52.78-1.14 1.3-1.92 1.3-3.28C8.95 3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-.36.36-.66.66-.88.93l1.75 1.71zm9.29 11.66c-.31 0-.74-.26-.74-.72 0-.6.73-2.2 2.87-2.76-.3 2.69-1.43 3.48-2.13 3.48z"/></symbol><symbol viewBox="0 0 24 24" id="ic_inbox_24px"><path d="M19 3H4.99c-1.11 0-1.98.89-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5a2 2 0 0 0-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_link_24px"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_low_priority_24px"><path d="M14 5h8v2h-8zm0 5.5h8v2h-8zm0 5.5h8v2h-8zM2 11.5C2 15.08 4.92 18 8.5 18H9v2l3-3-3-3v2h-.5C6.02 16 4 13.98 4 11.5S6.02 7 8.5 7H12V5H8.5C4.92 5 2 7.92 2 11.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mail_24px"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_markunread_24px"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_move_to_inbox_24px"><path d="M19 3H4.99c-1.11 0-1.98.9-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10zm-3-5h-2V7h-4v3H8l4 4 4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_next_week_24px"><path fill="#010101" d="M20 7h-4V5c0-.55-.22-1.05-.59-1.41C15.05 3.22 14.55 3 14 3h-4c-1.1 0-2 .9-2 2v2H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zM10 5h4v2h-4V5zm1 13.5l-1-1 3-3-3-3 1-1 4 4-4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_redo_24px"><path d="M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16a8.002 8.002 0 0 1 7.6-5.5c1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_remove_24px"><path d="M19 13H5v-2h14v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_remove_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_remove_circle_outline_24px"><path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_reply_24px"><path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_reply_all_24px"><path d="M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_report_24px"><path d="M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_save_24px"><path d="M17 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_select_all_24px"><path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_send_24px"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sort_24px"><path d="M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_text_format_24px"><path d="M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z"/></symbol><symbol viewBox="0 0 24 24" id="ic_unarchive_24px"><path d="M20.55 5.22l-1.39-1.68A1.51 1.51 0 0 0 18 3H6c-.47 0-.88.21-1.15.55L3.46 5.22C3.17 5.57 3 6.01 3 6.5V19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6.5c0-.49-.17-.93-.45-1.28zM12 9.5l5.5 5.5H14v2h-4v-2H6.5L12 9.5zM5.12 5l.82-1h12l.93 1H5.12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_undo_24px"><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_weekend_24px"><path d="M21 10c-1.1 0-2 .9-2 2v3H5v-3c0-1.1-.9-2-2-2s-2 .9-2 2v5c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-5c0-1.1-.9-2-2-2zm-3-5H6c-1.1 0-2 .9-2 2v2.15c1.16.41 2 1.51 2 2.82V14h12v-2.03c0-1.3.84-2.4 2-2.82V7c0-1.1-.9-2-2-2z" fill="#010101"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-device.svg b/skyquake/framework/style/icons/svg-sprite-device.svg
new file mode 100755 (executable)
index 0000000..d86f1fc
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="26" height="2064" viewBox="0 0 26 2064"><svg width="24" height="24" viewBox="0 0 24 24" id="ic_access_alarm_24px" y="0"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_access_alarms_24px" y="24"><path d="M22 5.7l-4.6-3.9-1.3 1.5 4.6 3.9L22 5.7zM7.9 3.4L6.6 1.9 2 5.7l1.3 1.5 4.6-3.8zM12.5 8H11v6l4.7 2.9.8-1.2-4-2.4V8zM12 4c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_access_time_24px" y="48"><path fill-opacity=".9" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_add_alarm_24px" y="72"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_airplanemode_off_24px" y="96"><path d="M13 9V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v3.68l7.83 7.83L21 16v-2l-8-5zM3 5.27l4.99 4.99L2 14v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-3.73L18.73 21 20 19.73 4.27 4 3 5.27z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_airplanemode_on_24px" y="120"><path d="M10.18 9"/><path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_20_24px" y="144"><path d="M7 17v3.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V17H7z"/><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V17h10V5.33z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_30_24px" y="168"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V15h10V5.33z"/><path d="M7 15v5.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V15H7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_50_24px" y="192"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V13h10V5.33z"/><path d="M7 13v7.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V13H7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_60_24px" y="216"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V11h10V5.33z"/><path d="M7 11v9.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V11H7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_80_24px" y="240"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V9h10V5.33z"/><path d="M7 9v11.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V9H7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_90_24px" y="264"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V8h10V5.33z"/><path d="M7 8v12.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V8H7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_alert_24px" y="288"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4zM13 18h-2v-2h2v2zm0-4h-2V9h2v5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_20_24px" y="312"><path d="M11 20v-3H7v3.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V17h-4.4L11 20z"/><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V17h4v-2.5H9L13 7v5.5h2L12.6 17H17V5.33C17 4.6 16.4 4 15.67 4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_30_24px" y="336"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v9.17h2L13 7v5.5h2l-1.07 2H17V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M11 20v-5.5H7v6.17C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V14.5h-3.07L11 20z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_50_24px" y="360"><path d="M14.47 13.5L11 20v-5.5H9l.53-1H7v7.17C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V13.5h-2.53z"/><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v8.17h2.53L13 7v5.5h2l-.53 1H17V5.33C17 4.6 16.4 4 15.67 4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_60_24px" y="384"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V11h3.87L13 7v4h4V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M13 12.5h2L11 20v-5.5H9l1.87-3.5H7v9.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V11h-4v1.5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_80_24px" y="408"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V9h4.93L13 7v2h4V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M13 12.5h2L11 20v-5.5H9L11.93 9H7v11.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V9h-4v3.5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_90_24px" y="432"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V8h5.47L13 7v1h4V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M13 12.5h2L11 20v-5.5H9L12.47 8H7v12.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V8h-4v4.5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_charging_full_24px" y="456"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4zM11 20v-5.5H9L13 7v5.5h2L11 20z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_full_24px" y="480"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_std_24px" y="504"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_battery_unknown_24px" y="528"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4zm-2.72 13.95h-1.9v-1.9h1.9v1.9zm1.35-5.26s-.38.42-.67.71c-.48.48-.83 1.15-.83 1.6h-1.6c0-.83.46-1.52.93-2l.93-.94c.27-.27.44-.65.44-1.06 0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5H9c0-1.66 1.34-3 3-3s3 1.34 3 3c0 .66-.27 1.26-.7 1.69z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_bluetooth_24px" y="552"><path d="M17.71 7.71L12 2h-1v7.59L6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 5.83l1.88 1.88L13 9.59V5.83zm1.88 10.46L13 18.17v-3.76l1.88 1.88z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_bluetooth_connected_24px" y="576"><path d="M7 12l-2-2-2 2 2 2 2-2zm10.71-4.29L12 2h-1v7.59L6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 5.83l1.88 1.88L13 9.59V5.83zm1.88 10.46L13 18.17v-3.76l1.88 1.88zM19 10l-2 2 2 2 2-2-2-2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_bluetooth_disabled_24px" y="600"><path d="M13 5.83l1.88 1.88-1.6 1.6 1.41 1.41 3.02-3.02L12 2h-1v5.03l2 2v-3.2zM5.41 4L4 5.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l4.29-4.29 2.3 2.29L20 18.59 5.41 4zM13 18.17v-3.76l1.88 1.88L13 18.17z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_bluetooth_searching_24px" y="624"><path d="M14.24 12.01l2.32 2.32c.28-.72.44-1.51.44-2.33 0-.82-.16-1.59-.43-2.31l-2.33 2.32zm5.29-5.3l-1.26 1.26c.63 1.21.98 2.57.98 4.02s-.36 2.82-.98 4.02l1.2 1.2c.97-1.54 1.54-3.36 1.54-5.31-.01-1.89-.55-3.67-1.48-5.19zm-3.82 1L10 2H9v7.59L4.41 5 3 6.41 8.59 12 3 17.59 4.41 19 9 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM11 5.83l1.88 1.88L11 9.59V5.83zm1.88 10.46L11 18.17v-3.76l1.88 1.88z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_brightness_auto_24px" y="648"><path d="M10.85 12.65h2.3L12 9l-1.15 3.65zM20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM14.3 16l-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9h-1.9z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_brightness_high_24px" y="672"><path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm0-10c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_brightness_low_24px" y="696"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_brightness_medium_24px" y="720"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18V6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_data_usage_24px" y="744"><path d="M13 2.05v3.03c3.39.49 6 3.39 6 6.92 0 .9-.18 1.75-.48 2.54l2.6 1.53c.56-1.24.88-2.62.88-4.07 0-5.18-3.95-9.45-9-9.95zM12 19c-3.87 0-7-3.13-7-7 0-3.53 2.61-6.43 6-6.92V2.05c-5.06.5-9 4.76-9 9.95 0 5.52 4.47 10 9.99 10 3.31 0 6.24-1.61 8.06-4.09l-2.6-1.53C16.17 17.98 14.21 19 12 19z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_developer_mode_24px" y="768"><path d="M7 5h10v2h2V3c0-1.1-.9-1.99-2-1.99L7 1c-1.1 0-2 .9-2 2v4h2V5zm8.41 11.59L20 12l-4.59-4.59L14 8.83 17.17 12 14 15.17l1.41 1.42zM10 15.17L6.83 12 10 8.83 8.59 7.41 4 12l4.59 4.59L10 15.17zM17 19H7v-2H5v4c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-4h-2v2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_devices_24px" y="792"><path d="M4 6h18V4H4c-1.1 0-2 .9-2 2v11H0v3h14v-3H4V6zm19 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_dvr_24px" y="816"><path d="M21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.1-.9-2-2-2zm0 14H3V5h18v12zm-2-9H8v2h11V8zm0 4H8v2h11v-2zM7 8H5v2h2V8zm0 4H5v2h2v-2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_gps_fixed_24px" y="840"><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_gps_not_fixed_24px" y="864"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_gps_off_24px" y="888"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06c-1.13.12-2.19.46-3.16.97l1.5 1.5C10.16 5.19 11.06 5 12 5c3.87 0 7 3.13 7 7 0 .94-.19 1.84-.52 2.65l1.5 1.5c.5-.96.84-2.02.97-3.15H23v-2h-2.06zM3 4.27l2.04 2.04C3.97 7.62 3.25 9.23 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c1.77-.2 3.38-.91 4.69-1.98L19.73 21 21 19.73 4.27 3 3 4.27zm13.27 13.27C15.09 18.45 13.61 19 12 19c-3.87 0-7-3.13-7-7 0-1.61.55-3.09 1.46-4.27l9.81 9.81z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_location_disabled_24px" y="912"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06c-1.13.12-2.19.46-3.16.97l1.5 1.5C10.16 5.19 11.06 5 12 5c3.87 0 7 3.13 7 7 0 .94-.19 1.84-.52 2.65l1.5 1.5c.5-.96.84-2.02.97-3.15H23v-2h-2.06zM3 4.27l2.04 2.04C3.97 7.62 3.25 9.23 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c1.77-.2 3.38-.91 4.69-1.98L19.73 21 21 19.73 4.27 3 3 4.27zm13.27 13.27C15.09 18.45 13.61 19 12 19c-3.87 0-7-3.13-7-7 0-1.61.55-3.09 1.46-4.27l9.81 9.81z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_location_searching_24px" y="936"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_multitrack_audio_24px" y="960"><path d="M7 18h2V6H7v12zm4 4h2V2h-2v20zm-8-8h2v-4H3v4zm12 4h2V6h-2v12zm4-8v4h2v-4h-2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_network_cell_24px" y="984"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M17 7L2 22h15z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_network_wifi_24px" y="1008"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M3.53 10.95l8.46 10.54.01.01.01-.01 8.46-10.54C20.04 10.62 16.81 8 12 8c-4.81 0-8.04 2.62-8.47 2.95z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_nfc_24px" y="1032"><path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_now_wallpaper_24px" y="1056"><path d="M4 4h7V2H4c-1.1 0-2 .9-2 2v7h2V4zm6 9l-4 5h12l-3-4-2.03 2.71L10 13zm7-4.5c0-.83-.67-1.5-1.5-1.5S14 7.67 14 8.5s.67 1.5 1.5 1.5S17 9.33 17 8.5zM20 2h-7v2h7v7h2V4c0-1.1-.9-2-2-2zm0 18h-7v2h7c1.1 0 2-.9 2-2v-7h-2v7zM4 13H2v7c0 1.1.9 2 2 2h7v-2H4v-7z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_now_widgets_24px" y="1080"><path d="M13 13v8h8v-8h-8zM3 21h8v-8H3v8zM3 3v8h8V3H3zm13.66-1.31L11 7.34 16.66 13l5.66-5.66-5.66-5.65z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_screen_lock_landscape_24px" y="1104"><path d="M21 5H3c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-2 12H5V7h14v10zm-9-1h4c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1v-1c0-1.11-.9-2-2-2-1.11 0-2 .9-2 2v1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1zm.8-6c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2v1h-2.4v-1z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_screen_lock_portrait_24px" y="1128"><path d="M10 16h4c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1v-1c0-1.11-.9-2-2-2-1.11 0-2 .9-2 2v1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1zm.8-6c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2v1h-2.4v-1zM17 1H7c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 18H7V5h10v14z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_screen_lock_rotation_24px" y="1152"><path d="M23.25 12.77l-2.57-2.57-1.41 1.41 2.22 2.22-5.66 5.66L4.51 8.17l5.66-5.66 2.1 2.1 1.41-1.41L11.23.75c-.59-.59-1.54-.59-2.12 0L2.75 7.11c-.59.59-.59 1.54 0 2.12l12.02 12.02c.59.59 1.54.59 2.12 0l6.36-6.36c.59-.59.59-1.54 0-2.12zM8.47 20.48C5.2 18.94 2.86 15.76 2.5 12H1c.51 6.16 5.66 11 11.95 11l.66-.03-3.81-3.82-1.33 1.33zM16 9h5c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1v-.5C21 1.12 19.88 0 18.5 0S16 1.12 16 2.5V3c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1zm.8-6.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V3h-3.4v-.5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_screen_rotation_24px" y="1176"><path d="M16.48 2.52c3.27 1.55 5.61 4.72 5.97 8.48h1.5C23.44 4.84 18.29 0 12 0l-.66.03 3.81 3.81 1.33-1.32zm-6.25-.77c-.59-.59-1.54-.59-2.12 0L1.75 8.11c-.59.59-.59 1.54 0 2.12l12.02 12.02c.59.59 1.54.59 2.12 0l6.36-6.36c.59-.59.59-1.54 0-2.12L10.23 1.75zm4.6 19.44L2.81 9.17l6.36-6.36 12.02 12.02-6.36 6.36zm-7.31.29C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_sd_storage_24px" y="1200"><path d="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 6h-2V4h2v4zm3 0h-2V4h2v4zm3 0h-2V4h2v4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_settings_system_daydream_24px" y="1224"><path d="M9 16h6.5c1.38 0 2.5-1.12 2.5-2.5S16.88 11 15.5 11h-.05c-.24-1.69-1.69-3-3.45-3-1.4 0-2.6.83-3.16 2.02h-.16C7.17 10.18 6 11.45 6 13c0 1.66 1.34 3 3 3zM21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_0_bar_24px" y="1248"><path fill-opacity=".3" d="M2 22h20V2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_1_bar_24px" y="1272"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M12 12L2 22h10z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_2_bar_24px" y="1296"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M14 10L2 22h12z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_3_bar_24px" y="1320"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M17 7L2 22h15z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_4_bar_24px" y="1344"><path d="M2 22h20V2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_connected_no_internet_0_bar_24px" y="1368"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M20 22h2v-2h-2v2zm0-12v8h2v-8h-2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_connected_no_internet_1_bar_24px" y="1392"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M20 10v8h2v-8h-2zm-8 12V12L2 22h10zm8 0h2v-2h-2v2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_connected_no_internet_2_bar_24px" y="1416"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M14 22V10L2 22h12zm6-12v8h2v-8h-2zm0 12h2v-2h-2v2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_connected_no_internet_3_bar_24px" y="1440"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M17 22V7L2 22h15zm3-12v8h2v-8h-2zm0 12h2v-2h-2v2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_connected_no_internet_4_bar_24px" y="1464"><path d="M20 18h2v-8h-2v8zm0 4h2v-2h-2v2zM2 22h16V8h4V2L2 22z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_no_sim_24px" y="1488"><path d="M18.99 5c0-1.1-.89-2-1.99-2h-7L7.66 5.34 19 16.68 18.99 5zM3.65 3.88L2.38 5.15 5 7.77V19c0 1.1.9 2 2 2h10.01c.35 0 .67-.1.96-.26l1.88 1.88 1.27-1.27L3.65 3.88z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_null_24px" y="1512"><path d="M20 6.83V20H6.83L20 6.83M22 2L2 22h20V2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_cellular_off_24px" y="1536"><path d="M21 1l-8.59 8.59L21 18.18V1zM4.77 4.5L3.5 5.77l6.36 6.36L1 21h17.73l2 2L22 21.73 4.77 4.5z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_wifi_0_bar_24px" y="1560"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_wifi_1_bar_24px" y="1584"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M6.67 14.86L12 21.49v.01l.01-.01 5.33-6.63C17.06 14.65 15.03 13 12 13s-5.06 1.65-5.33 1.86z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_wifi_2_bar_24px" y="1608"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M4.79 12.52l7.2 8.98H12l.01-.01 7.2-8.98C18.85 12.24 16.1 10 12 10s-6.85 2.24-7.21 2.52z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_wifi_3_bar_24px" y="1632"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M3.53 10.95l8.46 10.54.01.01.01-.01 8.46-10.54C20.04 10.62 16.81 8 12 8c-4.81 0-8.04 2.62-8.47 2.95z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_wifi_4_bar_24px" y="1656"><path d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_signal_wifi_off_24px" y="1680"><path d="M23.64 7c-.45-.34-4.93-4-11.64-4-1.5 0-2.89.19-4.15.48L18.18 13.8 23.64 7zm-6.6 8.22L3.27 1.44 2 2.72l2.05 2.06C1.91 5.76.59 6.82.36 7l11.63 14.49.01.01.01-.01 3.9-4.86 3.32 3.32 1.27-1.27-3.46-3.46z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_1_bar_26x24px" y="1704"><path d="M13 21.99l5.66-7.05C18.44 14.78 16.27 13 13 13s-5.44 1.78-5.66 1.95L13 21.99z"/><path fill-opacity=".3" d="M13.01 21.99L25.58 6.32C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_2_bar_26x24px" y="1728"><path fill-opacity=".3" d="M13.01 21.99L25.58 6.32C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01z"/><path d="M13.01 21.99l7.54-9.4C20.26 12.38 17.36 10 13 10c-4.36 0-7.26 2.38-7.55 2.59l7.54 9.4h.02z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_3_bar_26x24px" y="1752"><path d="M13.01 21.99l9.43-11.75C22.07 9.97 18.44 7 13 7c-5.44 0-9.07 2.97-9.44 3.24l9.43 11.75h.02z"/><path fill-opacity=".3" d="M13.01 21.99L25.58 6.32C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_4_bar_26x24px" y="1776"><path d="M13.01 21.99L25.58 6.32C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_connected_no_internet_1_26x24px" y="1800"><path fill-opacity=".3" d="M24.24 8l1.35-1.68C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01L20 13.28V8h4.24z"/><path d="M7.34 14.95L13 21.99V22v-.01l5.66-7.05C18.44 14.78 16.27 13 13 13s-5.44 1.78-5.66 1.95zM22 22h2v-2h-2v2zm0-12v8h2v-8h-2z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_connected_no_internet_26x24px" y="1824"><path fill-opacity=".3" d="M24.24 8l1.35-1.68C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01L20 13.28V8h4.24z"/><path d="M22 22h2v-2h-2v2zm0-12v8h2v-8h-2z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_connected_no_internet_2_26x24px" y="1848"><path fill-opacity=".3" d="M24.24 8l1.35-1.68C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01L20 13.28V8h4.24z"/><path d="M5.45 12.59l7.54 9.4.01.01.01-.01L20 13.28v-1.09c-1.07-.73-3.59-2.19-7-2.19-4.36 0-7.26 2.38-7.55 2.59zM22 10v8h2v-8h-2zm0 12h2v-2h-2v2z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_connected_no_internet_3_26x24px" y="1872"><path fill-opacity=".3" d="M24.24 8l1.35-1.68C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01L20 13.28V8h4.24z"/><path d="M20 13.28V8.71C18.35 7.87 15.94 7 13 7c-5.44 0-9.07 2.97-9.44 3.24l9.43 11.75.01.01.01-.01L20 13.28zM22 22h2v-2h-2v2zm0-12v8h2v-8h-2z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_connected_no_internet_4_26x24px" y="1896"><path d="M22 22h2v-2h-2v2zM13 2C5.74 2 .9 5.96.42 6.32l12.57 15.66.01.02.01-.01L20 13.28V8h4.24l1.35-1.68C25.1 5.96 20.26 2 13 2zm9 16h2v-8h-2v8z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_not_connected_26x24px" y="1920"><path fill-opacity=".3" d="M21 8.5c.85 0 1.64.23 2.34.62l2.24-2.79C25.1 5.96 20.26 2 13 2S.9 5.96.42 6.32l12.57 15.66.01.02.01-.01 4.21-5.24c-.76-.87-1.22-2-1.22-3.25 0-2.76 2.24-5 5-5z"/><path d="M21 10c-1.93 0-3.5 1.57-3.5 3.5h1.75c0-.97.78-1.75 1.75-1.75s1.75.78 1.75 1.75c0 .48-.2.92-.51 1.24l-1.09 1.1c-.63.63-1.02 1.51-1.02 2.47v.44h1.75c0-1.31.39-1.84 1.03-2.47l.78-.8c.5-.5.82-1.2.82-1.97C24.5 11.57 22.93 10 21 10zm-.95 11.95h1.9v-1.9h-1.9v1.9z"/></svg><svg width="26" height="24" viewBox="0 0 26 24" id="ic_signal_wifi_statusbar_null_26x24px" y="1944"><path d="M13 4c4.25 0 7.62 1.51 9.68 2.75L13 18.8 3.33 6.75C5.38 5.51 8.75 4 13 4m0-2C5.74 2 .9 5.96.42 6.32l12.57 15.66.01.02.01-.01L25.58 6.32C25.1 5.96 20.26 2 13 2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_storage_24px" y="1968"><path d="M2 20h20v-4H2v4zm2-3h2v2H4v-2zM2 4v4h20V4H2zm4 3H4V5h2v2zm-4 7h20v-4H2v4zm2-3h2v2H4v-2z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_usb_24px" y="1992"><path d="M15 7v4h1v2h-3V5h2l-3-4-3 4h2v8H8v-2.07c.7-.37 1.2-1.08 1.2-1.93 0-1.21-.99-2.2-2.2-2.2-1.21 0-2.2.99-2.2 2.2 0 .85.5 1.56 1.2 1.93V13c0 1.11.89 2 2 2h3v3.05c-.71.37-1.2 1.1-1.2 1.95 0 1.22.99 2.2 2.2 2.2 1.21 0 2.2-.98 2.2-2.2 0-.85-.49-1.58-1.2-1.95V15h3c1.11 0 2-.89 2-2v-2h1V7h-4z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_wifi_lock_24px" y="2016"><path d="M20.5 9.5c.28 0 .55.04.81.08L24 6c-3.34-2.51-7.5-4-12-4S3.34 3.49 0 6l12 16 3.5-4.67V14.5c0-2.76 2.24-5 5-5zM23 16v-1.5c0-1.38-1.12-2.5-2.5-2.5S18 13.12 18 14.5V16c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1zm-1 0h-3v-1.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V16z"/></svg><svg width="24" height="24" viewBox="0 0 24 24" id="ic_wifi_tethering_24px" y="2040"><path d="M12 11c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 2c0-3.31-2.69-6-6-6s-6 2.69-6 6c0 2.22 1.21 4.15 3 5.19l1-1.74c-1.19-.7-2-1.97-2-3.45 0-2.21 1.79-4 4-4s4 1.79 4 4c0 1.48-.81 2.75-2 3.45l1 1.74c1.79-1.04 3-2.97 3-5.19zM12 3C6.48 3 2 7.48 2 13c0 3.7 2.01 6.92 4.99 8.65l1-1.73C5.61 18.53 4 15.96 4 13c0-4.42 3.58-8 8-8s8 3.58 8 8c0 2.96-1.61 5.53-4 6.92l1 1.73c2.99-1.73 5-4.95 5-8.65 0-5.52-4.48-10-10-10z"/></svg></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-editor-symbol.svg b/skyquake/framework/style/icons/svg-sprite-editor-symbol.svg
new file mode 100755 (executable)
index 0000000..5a0a575
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_attach_file_24px"><path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5a2.5 2.5 0 0 1 5 0v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5a2.5 2.5 0 0 0 5 0V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_attach_money_24px"><path d="M11.8 10.9c-2.27-.59-3-1.2-3-2.15 0-1.09 1.01-1.85 2.7-1.85 1.78 0 2.44.85 2.5 2.1h2.21c-.07-1.72-1.12-3.3-3.21-3.81V3h-3v2.16c-1.94.42-3.5 1.68-3.5 3.61 0 2.31 1.91 3.46 4.7 4.13 2.5.6 3 1.48 3 2.41 0 .69-.49 1.79-2.7 1.79-2.06 0-2.87-.92-2.98-2.1h-2.2c.12 2.19 1.76 3.42 3.68 3.83V21h3v-2.15c1.95-.37 3.5-1.5 3.5-3.55 0-2.84-2.43-3.81-4.7-4.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_all_24px"><path d="M3 3v18h18V3H3zm8 16H5v-6h6v6zm0-8H5V5h6v6zm8 8h-6v-6h6v6zm0-8h-6V5h6v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_bottom_24px"><path d="M9 11H7v2h2v-2zm4 4h-2v2h2v-2zM9 3H7v2h2V3zm4 8h-2v2h2v-2zM5 3H3v2h2V3zm8 4h-2v2h2V7zm4 4h-2v2h2v-2zm-4-8h-2v2h2V3zm4 0h-2v2h2V3zm2 10h2v-2h-2v2zm0 4h2v-2h-2v2zM5 7H3v2h2V7zm14-4v2h2V3h-2zm0 6h2V7h-2v2zM5 11H3v2h2v-2zM3 21h18v-2H3v2zm2-6H3v2h2v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_clear_24px"><path d="M7 5h2V3H7v2zm0 8h2v-2H7v2zm0 8h2v-2H7v2zm4-4h2v-2h-2v2zm0 4h2v-2h-2v2zm-8 0h2v-2H3v2zm0-4h2v-2H3v2zm0-4h2v-2H3v2zm0-4h2V7H3v2zm0-4h2V3H3v2zm8 8h2v-2h-2v2zm8 4h2v-2h-2v2zm0-4h2v-2h-2v2zm0 8h2v-2h-2v2zm0-12h2V7h-2v2zm-8 0h2V7h-2v2zm8-6v2h2V3h-2zm-8 2h2V3h-2v2zm4 16h2v-2h-2v2zm0-8h2v-2h-2v2zm0-8h2V3h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_color_24px"><path d="M17.75 7L14 3.25l-10 10V17h3.75l10-10zm2.96-2.96a.996.996 0 0 0 0-1.41L18.37.29a.996.996 0 0 0-1.41 0L15 2.25 18.75 6l1.96-1.96z"/><path fill-opacity=".36" d="M0 20h24v4H0z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_horizontal_24px"><path d="M3 21h2v-2H3v2zM5 7H3v2h2V7zM3 17h2v-2H3v2zm4 4h2v-2H7v2zM5 3H3v2h2V3zm4 0H7v2h2V3zm8 0h-2v2h2V3zm-4 4h-2v2h2V7zm0-4h-2v2h2V3zm6 14h2v-2h-2v2zm-8 4h2v-2h-2v2zm-8-8h18v-2H3v2zM19 3v2h2V3h-2zm0 6h2V7h-2v2zm-8 8h2v-2h-2v2zm4 4h2v-2h-2v2zm4 0h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_inner_24px"><path d="M3 21h2v-2H3v2zm4 0h2v-2H7v2zM5 7H3v2h2V7zM3 17h2v-2H3v2zM9 3H7v2h2V3zM5 3H3v2h2V3zm12 0h-2v2h2V3zm2 6h2V7h-2v2zm0-6v2h2V3h-2zm-4 18h2v-2h-2v2zM13 3h-2v8H3v2h8v8h2v-8h8v-2h-8V3zm6 18h2v-2h-2v2zm0-4h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_left_24px"><path d="M11 21h2v-2h-2v2zm0-4h2v-2h-2v2zm0-12h2V3h-2v2zm0 4h2V7h-2v2zm0 4h2v-2h-2v2zm-4 8h2v-2H7v2zM7 5h2V3H7v2zm0 8h2v-2H7v2zm-4 8h2V3H3v18zM19 9h2V7h-2v2zm-4 12h2v-2h-2v2zm4-4h2v-2h-2v2zm0-14v2h2V3h-2zm0 10h2v-2h-2v2zm0 8h2v-2h-2v2zm-4-8h2v-2h-2v2zm0-8h2V3h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_outer_24px"><path d="M13 7h-2v2h2V7zm0 4h-2v2h2v-2zm4 0h-2v2h2v-2zM3 3v18h18V3H3zm16 16H5V5h14v14zm-6-4h-2v2h2v-2zm-4-4H7v2h2v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_right_24px"><path d="M7 21h2v-2H7v2zM3 5h2V3H3v2zm4 0h2V3H7v2zm0 8h2v-2H7v2zm-4 8h2v-2H3v2zm8 0h2v-2h-2v2zm-8-8h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm8 8h2v-2h-2v2zm4-4h2v-2h-2v2zm4-10v18h2V3h-2zm-4 18h2v-2h-2v2zm0-16h2V3h-2v2zm-4 8h2v-2h-2v2zm0-8h2V3h-2v2zm0 4h2V7h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_style_24px"><path d="M15 21h2v-2h-2v2zm4 0h2v-2h-2v2zM7 21h2v-2H7v2zm4 0h2v-2h-2v2zm8-4h2v-2h-2v2zm0-4h2v-2h-2v2zM3 3v18h2V5h16V3H3zm16 6h2V7h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_top_24px"><path d="M7 21h2v-2H7v2zm0-8h2v-2H7v2zm4 0h2v-2h-2v2zm0 8h2v-2h-2v2zm-8-4h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2v-2H3v2zm0-4h2V7H3v2zm8 8h2v-2h-2v2zm8-8h2V7h-2v2zm0 4h2v-2h-2v2zM3 3v2h18V3H3zm16 14h2v-2h-2v2zm-4 4h2v-2h-2v2zM11 9h2V7h-2v2zm8 12h2v-2h-2v2zm-4-8h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_border_vertical_24px"><path d="M3 9h2V7H3v2zm0-4h2V3H3v2zm4 16h2v-2H7v2zm0-8h2v-2H7v2zm-4 0h2v-2H3v2zm0 8h2v-2H3v2zm0-4h2v-2H3v2zM7 5h2V3H7v2zm12 12h2v-2h-2v2zm-8 4h2V3h-2v18zm8 0h2v-2h-2v2zm0-8h2v-2h-2v2zm0-10v2h2V3h-2zm0 6h2V7h-2v2zm-4-4h2V3h-2v2zm0 16h2v-2h-2v2zm0-8h2v-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_bubble_chart_24px"><circle cx="7.2" cy="14.4" r="3.2"/><circle cx="14.8" cy="18" r="2"/><circle cx="15.2" cy="8.8" r="4.8"/></symbol><symbol viewBox="0 0 24 24" id="ic_drag_handle_24px"><path d="M20 9H4v2h16V9zM4 15h16v-2H4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_align_center_24px"><path d="M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_align_justify_24px"><path d="M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zm0-6v2h18V3H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_align_left_24px"><path d="M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_align_right_24px"><path d="M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_bold_24px"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_clear_24px"><path d="M3.27 5L2 6.27l6.97 6.97L6.5 19h3l1.57-3.66L16.73 21 18 19.73 3.55 5.27 3.27 5zM6 5v.18L8.82 8h2.4l-.72 1.68 2.1 2.1L14.21 8H20V5H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_color_fill_24px"><path d="M16.56 8.94L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15a1.49 1.49 0 0 0 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.58.59-1.53 0-2.12zM5.21 10L10 5.21 14.79 10H5.21zM19 11.5s-2 2.17-2 3.5c0 1.1.9 2 2 2s2-.9 2-2c0-1.33-2-3.5-2-3.5z"/><path fill-opacity=".36" d="M0 20h24v4H0z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_color_reset_24px"><path d="M18 14c0-4-6-10.8-6-10.8s-1.33 1.51-2.73 3.52l8.59 8.59c.09-.42.14-.86.14-1.31zm-.88 3.12L12.5 12.5 5.27 5.27 4 6.55l3.32 3.32C6.55 11.32 6 12.79 6 14c0 3.31 2.69 6 6 6 1.52 0 2.9-.57 3.96-1.5l2.63 2.63 1.27-1.27-2.74-2.74z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_color_text_24px"><path fill-opacity=".36" d="M0 20h24v4H0z"/><path d="M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_indent_decrease_24px"><path d="M11 17h10v-2H11v2zm-8-5l4 4V8l-4 4zm0 9h18v-2H3v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_indent_increase_24px"><path d="M3 21h18v-2H3v2zM3 8v8l4-4-4-4zm8 9h10v-2H11v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_italic_24px"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_line_spacing_24px"><path d="M6 7h2.5L5 3.5 1.5 7H4v10H1.5L5 20.5 8.5 17H6V7zm4-2v2h12V5H10zm0 14h12v-2H10v2zm0-6h12v-2H10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_list_bulleted_24px"><path d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_list_numbered_24px"><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_paint_24px"><path d="M18 4V3c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V6h1v4H9v11c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-9h8V4h-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_quote_24px"><path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_shapes_24px"><path d="M23 7V1h-6v2H7V1H1v6h2v10H1v6h6v-2h10v2h6v-6h-2V7h2zM3 3h2v2H3V3zm2 18H3v-2h2v2zm12-2H7v-2H5V7h2V5h10v2h2v10h-2v2zm4 2h-2v-2h2v2zM19 5V3h2v2h-2zm-5.27 9h-3.49l-.73 2H7.89l3.4-9h1.4l3.41 9h-1.63l-.74-2zm-3.04-1.26h2.61L12 8.91l-1.31 3.83z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_size_24px"><path d="M9 4v3h5v12h3V7h5V4H9zm-6 8h3v7h3v-7h3V9H3v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_strikethrough_24px"><path d="M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_textdirection_l_to_r_24px"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_textdirection_r_to_l_24px"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zm-2 7v-3l-4 4 4 4v-3h12v-2H8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_format_underlined_24px"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_functions_24px"><path d="M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_highlight_24px"><path d="M6 14l3 3v5h6v-5l3-3V9H6zm5-12h2v3h-2zM3.5 5.875L4.914 4.46l2.12 2.122L5.62 7.997zm13.46.71l2.123-2.12 1.414 1.414L18.375 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_chart_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_comment_24px"><path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_drive_file_24px"><path d="M6 2c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6H6zm7 7V3.5L18.5 9H13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_emoticon_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_invitation_24px"><path d="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_link_24px"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_insert_photo_24px"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_linear_scale_24px"><path d="M19.5 9.5c-1.03 0-1.9.62-2.29 1.5h-2.92c-.39-.88-1.26-1.5-2.29-1.5s-1.9.62-2.29 1.5H6.79c-.39-.88-1.26-1.5-2.29-1.5a2.5 2.5 0 0 0 0 5c1.03 0 1.9-.62 2.29-1.5h2.92c.39.88 1.26 1.5 2.29 1.5s1.9-.62 2.29-1.5h2.92c.39.88 1.26 1.5 2.29 1.5a2.5 2.5 0 0 0 0-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_merge_type_24px"><path d="M17 20.41L18.41 19 15 15.59 13.59 17 17 20.41zM7.5 8H11v5.59L5.59 19 7 20.41l6-6V8h3.5L12 3.5 7.5 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mode_comment_24px"><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mode_edit_24px"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a.996.996 0 0 0 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></symbol><symbol viewBox="0 0 24 24" id="ic_monetization_on_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1.41 16.09V20h-2.67v-1.93c-1.71-.36-3.16-1.46-3.27-3.4h1.96c.1 1.05.82 1.87 2.65 1.87 1.96 0 2.4-.98 2.4-1.59 0-.83-.44-1.61-2.67-2.14-2.48-.6-4.18-1.62-4.18-3.67 0-1.72 1.39-2.84 3.11-3.21V4h2.67v1.95c1.86.45 2.79 1.86 2.85 3.39H14.3c-.05-1.11-.64-1.87-2.22-1.87-1.5 0-2.4.68-2.4 1.64 0 .84.65 1.39 2.67 1.91s4.18 1.39 4.18 3.91c-.01 1.83-1.38 2.83-3.12 3.16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_money_off_24px"><path d="M12.5 6.9c1.78 0 2.44.85 2.5 2.1h2.21c-.07-1.72-1.12-3.3-3.21-3.81V3h-3v2.16c-.53.12-1.03.3-1.48.54l1.47 1.47c.41-.17.91-.27 1.51-.27zM5.33 4.06L4.06 5.33 7.5 8.77c0 2.08 1.56 3.21 3.91 3.91l3.51 3.51c-.34.48-1.05.91-2.42.91-2.06 0-2.87-.92-2.98-2.1h-2.2c.12 2.19 1.76 3.42 3.68 3.83V21h3v-2.15c.96-.18 1.82-.55 2.45-1.12l2.22 2.22 1.27-1.27L5.33 4.06z"/></symbol><symbol viewBox="0 0 24 24" id="ic_multiline_chart_24px"><path d="M22 6.92l-1.41-1.41-2.85 3.21C15.68 6.4 12.83 5 9.61 5 6.72 5 4.07 6.16 2 8l1.42 1.42C5.12 7.93 7.27 7 9.61 7c2.74 0 5.09 1.26 6.77 3.24l-2.88 3.24-4-4L2 16.99l1.5 1.5 6-6.01 4 4 4.05-4.55c.75 1.35 1.25 2.9 1.44 4.55H21c-.22-2.3-.95-4.39-2.04-6.14L22 6.92z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pie_chart_24px"><path d="M11 2v20c-5.07-.5-9-4.79-9-10s3.93-9.5 9-10zm2.03 0v8.99H22c-.47-4.74-4.24-8.52-8.97-8.99zm0 11.01V22c4.74-.47 8.5-4.25 8.97-8.99h-8.97z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pie_chart_outlined_24px"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm1 2.07c3.61.45 6.48 3.33 6.93 6.93H13V4.07zM4 12c0-4.06 3.07-7.44 7-7.93v15.87c-3.93-.5-7-3.88-7-7.94zm9 7.93V13h6.93A8.002 8.002 0 0 1 13 19.93z"/></symbol><symbol viewBox="0 0 24 24" id="ic_publish_24px"><path d="M5 4v2h14V4H5zm0 10h4v6h6v-6h4l-7-7-7 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_short_text_24px"><path d="M4 9h16v2H4zm0 4h10v2H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_show_chart_24px"><path d="M3.5 18.49l6-6.01 4 4L22 6.92l-1.41-1.41-7.09 7.97-4-4L2 16.99z"/></symbol><symbol viewBox="0 0 24 24" id="ic_space_bar_24px"><path d="M18 9v4H6V9H4v6h16V9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_strikethrough_s_24px"><path fill="#010101" d="M7.24 8.75c-.26-.48-.39-1.03-.39-1.67 0-.61.13-1.16.4-1.67.26-.5.63-.93 1.11-1.29a5.73 5.73 0 0 1 1.7-.83c.66-.19 1.39-.29 2.18-.29.81 0 1.54.11 2.21.34.66.22 1.23.54 1.69.94.47.4.83.88 1.08 1.43.25.55.38 1.15.38 1.81h-3.01c0-.31-.05-.59-.15-.85-.09-.27-.24-.49-.44-.68-.2-.19-.45-.33-.75-.44-.3-.1-.66-.16-1.06-.16-.39 0-.74.04-1.03.13-.29.09-.53.21-.72.36-.19.16-.34.34-.44.55-.1.21-.15.43-.15.66 0 .48.25.88.74 1.21.38.25.77.48 1.41.7H7.39c-.05-.08-.11-.17-.15-.25zM21 12v-2H3v2h9.62c.18.07.4.14.55.2.37.17.66.34.87.51.21.17.35.36.43.57.07.2.11.43.11.69 0 .23-.05.45-.14.66-.09.2-.23.38-.42.53-.19.15-.42.26-.71.35-.29.08-.63.13-1.01.13-.43 0-.83-.04-1.18-.13s-.66-.23-.91-.42a1.92 1.92 0 0 1-.59-.75c-.14-.31-.25-.76-.25-1.21H6.4c0 .55.08 1.13.24 1.58.16.45.37.85.65 1.21.28.35.6.66.98.92.37.26.78.48 1.22.65.44.17.9.3 1.38.39.48.08.96.13 1.44.13.8 0 1.53-.09 2.18-.28s1.21-.45 1.67-.79c.46-.34.82-.77 1.07-1.27s.38-1.07.38-1.71c0-.6-.1-1.14-.31-1.61-.05-.11-.11-.23-.17-.33H21z"/></symbol><symbol viewBox="0 0 24 24" id="ic_text_fields_24px"><path d="M2.5 4v3h5v12h3V7h5V4h-13zm19 5h-9v3h3v7h3v-7h3V9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_title_24px"><path d="M5 4v3h5.5v12h3V7H19V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vertical_align_bottom_24px"><path d="M16 13h-3V3h-2v10H8l4 4 4-4zM4 19v2h16v-2H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vertical_align_center_24px"><path d="M8 19h3v4h2v-4h3l-4-4-4 4zm8-14h-3V1h-2v4H8l4 4 4-4zM4 11v2h16v-2H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vertical_align_top_24px"><path d="M8 11h3v10h2V11h3l-4-4-4 4zM4 3v2h16V3H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wrap_text_24px"><path d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3 3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-file-symbol.svg b/skyquake/framework/style/icons/svg-sprite-file-symbol.svg
new file mode 100755 (executable)
index 0000000..01d7d4d
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_attachment_24px"><path d="M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5a2.5 2.5 0 0 1 0-5H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01A3.98 3.98 0 0 1 12 7a4 4 0 0 1 4 4h.5a2.5 2.5 0 0 1 0 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_done_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_download_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_off_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46a5.497 5.497 0 0 1 8.05 4.87v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_queue_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71A5.5 5.5 0 0 1 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cloud_upload_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_create_new_folder_24px"><path d="M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-1 8h-3v3h-2v-3h-3v-2h3V9h2v3h3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_file_download_24px"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_file_upload_24px"><path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_folder_24px"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_folder_open_24px"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_folder_shared_24px"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-hardware-symbol.svg b/skyquake/framework/style/icons/svg-sprite-hardware-symbol.svg
new file mode 100755 (executable)
index 0000000..7f5d14c
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_cast_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2a9 9 0 0 1 9 9h2c0-6.08-4.93-11-11-11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cast_connected_24px"><path d="M1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm18-7H5v1.63c3.96 1.28 7.09 4.41 8.37 8.37H19V7zM1 10v2a9 9 0 0 1 9 9h2c0-6.08-4.93-11-11-11zm20-7H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_computer_24px"><path d="M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_desktop_mac_24px"><path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7l-2 3v1h8v-1l-2-3h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 12H3V4h18v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_desktop_windows_24px"><path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v2H8v2h8v-2h-2v-2h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H3V4h18v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_developer_board_24px"><path d="M22 9V7h-2V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2v-2h-2V9h2zm-4 10H4V5h14v14zM6 13h5v4H6zm6-6h4v3h-4zM6 7h5v5H6zm6 4h4v6h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_device_hub_24px"><path d="M17 16l-4-4V8.82C14.16 8.4 15 7.3 15 6c0-1.66-1.34-3-3-3S9 4.34 9 6c0 1.3.84 2.4 2 2.82V12l-4 4H3v5h5v-3.05l4-4.2 4 4.2V21h5v-5h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_devices_other_24px"><path d="M3 6h18V4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4v-2H3V6zm10 6H9v1.78c-.61.55-1 1.33-1 2.22s.39 1.67 1 2.22V20h4v-1.78c.61-.55 1-1.34 1-2.22s-.39-1.67-1-2.22V12zm-2 5.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM22 8h-6c-.5 0-1 .5-1 1v10c0 .5.5 1 1 1h6c.5 0 1-.5 1-1V9c0-.5-.5-1-1-1zm-1 10h-4v-8h4v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_dock_24px"><path d="M8 23h8v-2H8v2zm8-21.99L8 1c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM16 15H8V5h8v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_gamepad_24px"><path d="M15 7.5V2H9v5.5l3 3 3-3zM7.5 9H2v6h5.5l3-3-3-3zM9 16.5V22h6v-5.5l-3-3-3 3zM16.5 9l-3 3 3 3H22V9h-5.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_headset_24px"><path d="M12 1a9 9 0 0 0-9 9v7c0 1.66 1.34 3 3 3h3v-8H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-4v8h3c1.66 0 3-1.34 3-3v-7a9 9 0 0 0-9-9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_headset_mic_24px"><path d="M12 1a9 9 0 0 0-9 9v7c0 1.66 1.34 3 3 3h3v-8H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-4v8h4v1h-7v2h6c1.66 0 3-1.34 3-3V10a9 9 0 0 0-9-9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_24px"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_arrow_down_24px"><path d="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_arrow_left_24px"><path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_arrow_right_24px"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_arrow_up_24px"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_backspace_24px"><path d="M21 11H6.83l3.58-3.59L9 6l-6 6 6 6 1.41-1.41L6.83 13H21z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_capslock_24px"><path d="M12 8.41L16.59 13 18 11.59l-6-6-6 6L7.41 13 12 8.41zM6 18h12v-2H6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_hide_24px"><path d="M20 3H4c-1.1 0-1.99.9-1.99 2L2 15c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 3h2v2h-2V6zm0 3h2v2h-2V9zM8 6h2v2H8V6zm0 3h2v2H8V9zm-1 2H5V9h2v2zm0-3H5V6h2v2zm9 7H8v-2h8v2zm0-4h-2V9h2v2zm0-3h-2V6h2v2zm3 3h-2V9h2v2zm0-3h-2V6h2v2zm-7 15l4-4H8l4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_return_24px"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_tab_24px"><path d="M11.59 7.41L15.17 11H1v2h14.17l-3.59 3.59L13 18l6-6-6-6-1.41 1.41zM20 6v12h2V6h-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_keyboard_voice_24px"><path d="M12 15c1.66 0 2.99-1.34 2.99-3L15 6c0-1.66-1.34-3-3-3S9 4.34 9 6v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 15 6.7 12H5c0 3.42 2.72 6.23 6 6.72V22h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_laptop_24px"><path d="M20 18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_laptop_chromebook_24px"><path d="M22 18V3H2v15H0v2h24v-2h-2zm-8 0h-4v-1h4v1zm6-3H4V5h16v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_laptop_mac_24px"><path d="M20 18c1.1 0 1.99-.9 1.99-2L22 5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2H0c0 1.1.9 2 2 2h20c1.1 0 2-.9 2-2h-4zM4 5h16v11H4V5zm8 14c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_laptop_windows_24px"><path d="M20 18v-1c1.1 0 1.99-.9 1.99-2L22 5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2v1H0v2h24v-2h-4zM4 5h16v10H4V5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_memory_24px"><path d="M15 9H9v6h6V9zm-2 4h-2v-2h2v2zm8-2V9h-2V7c0-1.1-.9-2-2-2h-2V3h-2v2h-2V3H9v2H7c-1.1 0-2 .9-2 2v2H3v2h2v2H3v2h2v2c0 1.1.9 2 2 2h2v2h2v-2h2v2h2v-2h2c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2zm-4 6H7V7h10v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mouse_24px"><path d="M13 1.07V9h7c0-4.08-3.05-7.44-7-7.93zM4 15c0 4.42 3.58 8 8 8s8-3.58 8-8v-4H4v4zm7-13.93C7.05 1.56 4 4.92 4 9h7V1.07z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_android_24px"><path d="M16 1H8C6.34 1 5 2.34 5 4v16c0 1.66 1.34 3 3 3h8c1.66 0 3-1.34 3-3V4c0-1.66-1.34-3-3-3zm-2 20h-4v-1h4v1zm3.25-3H6.75V4h10.5v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_iphone_24px"><path d="M15.5 1h-8A2.5 2.5 0 0 0 5 3.5v17A2.5 2.5 0 0 0 7.5 23h8a2.5 2.5 0 0 0 2.5-2.5v-17A2.5 2.5 0 0 0 15.5 1zm-4 21c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4.5-4H7V4h9v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phonelink_24px"><path d="M4 6h18V4H4c-1.1 0-2 .9-2 2v11H0v3h14v-3H4V6zm19 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phonelink_off_24px"><path d="M22 6V4H6.82l2 2H22zM1.92 1.65L.65 2.92l1.82 1.82C2.18 5.08 2 5.52 2 6v11H0v3h17.73l2.35 2.35 1.27-1.27L3.89 3.62 1.92 1.65zM4 6.27L14.73 17H4V6.27zM23 8h-6c-.55 0-1 .45-1 1v4.18l2 2V10h4v7h-2.18l3 3H23c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_power_input_24px"><path d="M2 9v2h19V9H2zm0 6h5v-2H2v2zm7 0h5v-2H9v2zm7 0h5v-2h-5v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_router_24px"><path d="M20.2 5.9l.8-.8C19.6 3.7 17.8 3 16 3s-3.6.7-5 2.1l.8.8C13 4.8 14.5 4.2 16 4.2s3 .6 4.2 1.7zm-.9.8c-.9-.9-2.1-1.4-3.3-1.4s-2.4.5-3.3 1.4l.8.8c.7-.7 1.6-1 2.5-1 .9 0 1.8.3 2.5 1l.8-.8zM19 13h-2V9h-2v4H5c-1.1 0-2 .9-2 2v4c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-4c0-1.1-.9-2-2-2zM8 18H6v-2h2v2zm3.5 0h-2v-2h2v2zm3.5 0h-2v-2h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_scanner_24px"><path d="M19.8 10.7L4.2 5l-.7 1.9L17.6 12H5c-1.1 0-2 .9-2 2v4c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-5.5c0-.8-.5-1.6-1.2-1.8zM7 17H5v-2h2v2zm12 0H9v-2h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_security_24px"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sim_card_24px"><path d="M19.99 4c0-1.1-.89-2-1.99-2h-8L4 8v12c0 1.1.9 2 2 2h12.01c1.1 0 1.99-.9 1.99-2l-.01-16zM9 19H7v-2h2v2zm8 0h-2v-2h2v2zm-8-4H7v-4h2v4zm4 4h-2v-4h2v4zm0-6h-2v-2h2v2zm4 2h-2v-4h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_smartphone_24px"><path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_speaker_24px"><path d="M17 2H7c-1.1 0-2 .9-2 2v16c0 1.1.9 1.99 2 1.99L17 22c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 2c1.1 0 2 .9 2 2s-.9 2-2 2a2 2 0 0 1 0-4zm0 16c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_speaker_group_24px"><path d="M18.2 1H9.8C8.81 1 8 1.81 8 2.8v14.4c0 .99.81 1.79 1.8 1.79l8.4.01c.99 0 1.8-.81 1.8-1.8V2.8c0-.99-.81-1.8-1.8-1.8zM14 3a2 2 0 1 1 0 4 2 2 0 0 1 0-4zm0 13.5c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/><circle cx="14" cy="12.5" r="2.5"/><path d="M6 5H4v16a2 2 0 0 0 2 2h10v-2H6V5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tablet_24px"><path d="M21 4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 1.99-.9 1.99-2L23 6c0-1.1-.9-2-2-2zm-2 14H5V6h14v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tablet_android_24px"><path d="M18 0H6C4.34 0 3 1.34 3 3v18c0 1.66 1.34 3 3 3h12c1.66 0 3-1.34 3-3V3c0-1.66-1.34-3-3-3zm-4 22h-4v-1h4v1zm5.25-3H4.75V3h14.5v16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tablet_mac_24px"><path d="M18.5 0h-14A2.5 2.5 0 0 0 2 2.5v19A2.5 2.5 0 0 0 4.5 24h14a2.5 2.5 0 0 0 2.5-2.5v-19A2.5 2.5 0 0 0 18.5 0zm-7 23c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm7.5-4H4V3h15v16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_toys_24px"><path d="M12 12c0-3 2.5-5.5 5.5-5.5S23 9 23 12H12zm0 0c0 3-2.5 5.5-5.5 5.5S1 15 1 12h11zm0 0c-3 0-5.5-2.5-5.5-5.5S9 1 12 1v11zm0 0c3 0 5.5 2.5 5.5 5.5S15 23 12 23V12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tv_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.1-.9-2-2-2zm0 14H3V5h18v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_videogame_asset_24px"><path d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-10 7H8v3H6v-3H3v-2h3V8h2v3h3v2zm4.5 2c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4-3c-.83 0-1.5-.67-1.5-1.5S18.67 9 19.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_watch_24px"><path d="M20 12c0-2.54-1.19-4.81-3.04-6.27L16 0H8l-.95 5.73C5.19 7.19 4 9.45 4 12s1.19 4.81 3.05 6.27L8 24h8l.96-5.73A7.976 7.976 0 0 0 20 12zM6 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6-6-2.69-6-6z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-image-symbol.svg b/skyquake/framework/style/icons/svg-sprite-image-symbol.svg
new file mode 100755 (executable)
index 0000000..5431358
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_add_a_photo_24px"><path d="M3 4V1h2v3h3v2H5v3H3V6H0V4h3zm3 6V7h3V4h7l1.83 2H21c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V10h3zm7 9c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-3.2-5c0 1.77 1.43 3.2 3.2 3.2s3.2-1.43 3.2-3.2-1.43-3.2-3.2-3.2-3.2 1.43-3.2 3.2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_add_to_photos_24px"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_adjust_24px"><path d="M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10 10-4.49 10-10S17.51 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3-8c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assistant_24px"><path d="M19 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5.12 10.88L12 17l-1.88-4.12L6 11l4.12-1.88L12 5l1.88 4.12L18 11l-4.12 1.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_assistant_photo_24px"><path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_audiotrack_24px"><path d="M12 3v9.28a4.39 4.39 0 0 0-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_blur_circular_24px"><path d="M10 9c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zM7 9.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm3 7c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-3-3c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm3-6c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM14 9c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-1.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm3 6c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-4c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm2-3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-3.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_blur_linear_24px"><path d="M5 17.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5-1.5.67-1.5 1.5.67 1.5 1.5 1.5zM9 13c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zM3 21h18v-2H3v2zM5 9.5c.83 0 1.5-.67 1.5-1.5S5.83 6.5 5 6.5 3.5 7.17 3.5 8 4.17 9.5 5 9.5zm0 4c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5-1.5.67-1.5 1.5.67 1.5 1.5 1.5zM9 17c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm8-.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM3 3v2h18V3H3zm14 5.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm0 4c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM13 9c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_blur_off_24px"><path d="M14 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm-.2 4.48l.2.02c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5-1.5.67-1.5 1.5l.02.2c.09.67.61 1.19 1.28 1.28zM14 3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm-4 0c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm11 7c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM10 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm8 8c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm-4 13.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM2.5 5.27l3.78 3.78L6 9c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1c0-.1-.03-.19-.06-.28l2.81 2.81c-.71.11-1.25.73-1.25 1.47 0 .83.67 1.5 1.5 1.5.74 0 1.36-.54 1.47-1.25l2.81 2.81A.875.875 0 0 0 14 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1c0-.1-.03-.19-.06-.28l3.78 3.78L20 20.23 3.77 4 2.5 5.27zM10 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm11-3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 13c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zM3 9.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm7 11c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-3-3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_blur_on_24px"><path d="M6 13c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-8c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-3 .5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm15 5.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM14 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm-11 10c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm7 7c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-17c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM10 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 5.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm8 .5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-8c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm3 8.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM14 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-4-12c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0 8.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm4-4.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-4c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_1_24px"><circle cx="12" cy="12" r="10"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_2_24px"><path d="M10 2c-1.82 0-3.53.5-5 1.35C7.99 5.08 10 8.3 10 12s-2.01 6.92-5 8.65C6.47 21.5 8.18 22 10 22c5.52 0 10-4.48 10-10S15.52 2 10 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_3_24px"><path d="M9 2c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10S14.52 2 9 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_4_24px"><path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_5_24px"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_6_24px"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18V6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brightness_7_24px"><path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm0-10c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_broken_image_24px"><path d="M21 5v6.59l-3-3.01-4 4.01-4-4-4 4-3-3.01V5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2zm-3 6.42l3 3.01V19c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2v-6.58l3 2.99 4-4 4 4 4-3.99z"/></symbol><symbol viewBox="0 0 24 24" id="ic_brush_24px"><path d="M7 14c-1.66 0-3 1.34-3 3 0 1.31-1.16 2-2 2 .92 1.22 2.49 2 4 2a4 4 0 0 0 4-4c0-1.66-1.34-3-3-3zm13.71-9.37l-1.34-1.34a.996.996 0 0 0-1.41 0L9 12.25 11.75 15l8.96-8.96a.996.996 0 0 0 0-1.41z"/></symbol><symbol viewBox="0 0 24 24" id="ic_burst_mode_24px"><path d="M1 5h2v14H1zm4 0h2v14H5zm17 0H10c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zM11 17l2.5-3.15L15.29 16l2.5-3.22L21 17H11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_camera_24px"><path d="M9.4 10.5l4.77-8.26a9.984 9.984 0 0 0-8.49 2.01l3.66 6.35.06-.1zM21.54 9c-.92-2.92-3.15-5.26-6-6.34L11.88 9h9.66zm.26 1h-7.49l.29.5 4.76 8.25A9.91 9.91 0 0 0 22 12c0-.69-.07-1.35-.2-2zM8.54 12l-3.9-6.75A9.958 9.958 0 0 0 2.2 14h7.49l-1.15-2zm-6.08 3c.92 2.92 3.15 5.26 6 6.34L12.12 15H2.46zm11.27 0l-3.9 6.76a9.984 9.984 0 0 0 8.49-2.01l-3.66-6.35-.93 1.6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_camera_alt_24px"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_camera_front_24px"><path d="M10 20H5v2h5v2l3-3-3-3v2zm4 0v2h5v-2h-5zM12 8c1.1 0 2-.9 2-2s-.9-2-2-2-1.99.9-1.99 2S10.9 8 12 8zm5-8H7C5.9 0 5 .9 5 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zM7 2h10v10.5c0-1.67-3.33-2.5-5-2.5s-5 .83-5 2.5V2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_camera_rear_24px"><path d="M10 20H5v2h5v2l3-3-3-3v2zm4 0v2h5v-2h-5zm3-20H7C5.9 0 5 .9 5 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zm-5 6c-1.11 0-2-.9-2-2s.89-2 1.99-2 2 .9 2 2C14 5.1 13.1 6 12 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_camera_roll_24px"><path d="M14 5c0-1.1-.9-2-2-2h-1V2c0-.55-.45-1-1-1H6c-.55 0-1 .45-1 1v1H4c-1.1 0-2 .9-2 2v15c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2h8V5h-8zm-2 13h-2v-2h2v2zm0-9h-2V7h2v2zm4 9h-2v-2h2v2zm0-9h-2V7h2v2zm4 9h-2v-2h2v2zm0-9h-2V7h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_center_focus_strong_24px"><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-7 7H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_center_focus_weak_24px"><path d="M5 15H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_collections_24px"><path d="M22 16V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2zm-11-4l2.03 2.71L16 11l4 5H8l3-4zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_collections_bookmark_24px"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 10l-2.5-1.5L15 12V4h5v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_color_lens_24px"><path d="M12 3a9 9 0 0 0 0 18c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_colorize_24px"><path d="M20.71 5.63l-2.34-2.34a.996.996 0 0 0-1.41 0l-3.12 3.12-1.93-1.91-1.41 1.41 1.42 1.42L3 16.25V21h4.75l8.92-8.92 1.42 1.42 1.41-1.41-1.92-1.92 3.12-3.12a1 1 0 0 0 .01-1.42zM6.92 19L5 17.08l8.06-8.06 1.92 1.92L6.92 19z"/></symbol><symbol viewBox="0 0 24 24" id="ic_compare_24px"><path d="M10 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h5v2h2V1h-2v2zm0 15H5l5-6v6zm9-15h-5v2h5v13l-5-6v9h5c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_control_point_24px"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.49 2 2 6.49 2 12s4.49 10 10 10 10-4.49 10-10S17.51 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_control_point_duplicate_24px"><path d="M16 8h-2v3h-3v2h3v3h2v-3h3v-2h-3zM2 12c0-2.79 1.64-5.2 4.01-6.32V3.52C2.52 4.76 0 8.09 0 12s2.52 7.24 6.01 8.48v-2.16A6.99 6.99 0 0 1 2 12zm13-9c-4.96 0-9 4.04-9 9s4.04 9 9 9 9-4.04 9-9-4.04-9-9-9zm0 16c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_16_9_24px"><path d="M19 6H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H5V8h14v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_24px"><path d="M17 15h2V7c0-1.1-.9-2-2-2H9v2h8v8zM7 17V1H5v4H1v2h4v10c0 1.1.9 2 2 2h10v4h2v-4h4v-2H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_3_2_24px"><path d="M19 4H5c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H5V6h14v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_5_4_24px"><path d="M19 5H5c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 12H5V7h14v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_7_5_24px"><path d="M19 7H5c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 8H5V9h14v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_din_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_free_24px"><path d="M3 5v4h2V5h4V3H5c-1.1 0-2 .9-2 2zm2 10H3v4c0 1.1.9 2 2 2h4v-2H5v-4zm14 4h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zm0-16h-4v2h4v4h2V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_landscape_24px"><path d="M19 5H5c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 12H5V7h14v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_original_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zm-5.04-6.71l-2.75 3.54-1.96-2.36L6.5 17h11l-3.54-4.71z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_portrait_24px"><path d="M17 3H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H7V5h10v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_rotate_24px"><path d="M7.47 21.49C4.2 19.93 1.86 16.76 1.5 13H0c.51 6.16 5.66 11 11.95 11 .23 0 .44-.02.66-.03L8.8 20.15l-1.33 1.34zM12.05 0c-.23 0-.44.02-.66.04l3.81 3.81 1.33-1.33C19.8 4.07 22.14 7.24 22.5 11H24c-.51-6.16-5.66-11-11.95-11zM16 14h2V8a2 2 0 0 0-2-2h-6v2h6v6zm-8 2V4H6v2H4v2h2v8a2 2 0 0 0 2 2h8v2h2v-2h2v-2H8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_crop_square_24px"><path d="M18 4H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H6V6h12v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_dehaze_24px"><path d="M2 15.5v2h20v-2H2zm0-5v2h20v-2H2zm0-5v2h20v-2H2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_details_24px"><path d="M3 4l9 16 9-16H3zm3.38 2h11.25L12 16 6.38 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_edit_24px"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a.996.996 0 0 0 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exposure_24px"><path d="M15 17v2h2v-2h2v-2h-2v-2h-2v2h-2v2h2zm5-15H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM5 5h6v2H5V5zm15 15H4L20 4v16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exposure_neg_1_24px"><path d="M4 11v2h8v-2H4zm15 7h-2V7.38L14 8.4V6.7L18.7 5h.3v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exposure_neg_2_24px"><path d="M15.05 16.29l2.86-3.07c.38-.39.72-.79 1.04-1.18.32-.39.59-.78.82-1.17.23-.39.41-.78.54-1.17s.19-.79.19-1.18c0-.53-.09-1.02-.27-1.46a2.94 2.94 0 0 0-.78-1.11c-.34-.31-.77-.54-1.26-.71A5.72 5.72 0 0 0 16.47 5c-.69 0-1.31.11-1.85.32-.54.21-1 .51-1.36.88-.37.37-.65.8-.84 1.3-.18.47-.27.97-.28 1.5h2.14c.01-.31.05-.6.13-.87.09-.29.23-.54.4-.75.18-.21.41-.37.68-.49.27-.12.6-.18.96-.18.31 0 .58.05.81.15.23.1.43.25.59.43.16.18.28.4.37.65.08.25.13.52.13.81 0 .22-.03.43-.08.65-.06.22-.15.45-.29.7-.14.25-.32.53-.56.83-.23.3-.52.65-.88 1.03l-4.17 4.55V18H21v-1.71h-5.95zM2 11v2h8v-2H2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exposure_plus_1_24px"><path d="M10 7H8v4H4v2h4v4h2v-4h4v-2h-4V7zm10 11h-2V7.38L15 8.4V6.7L19.7 5h.3v13z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exposure_plus_2_24px"><path d="M16.05 16.29l2.86-3.07c.38-.39.72-.79 1.04-1.18.32-.39.59-.78.82-1.17.23-.39.41-.78.54-1.17.13-.39.19-.79.19-1.18 0-.53-.09-1.02-.27-1.46a2.94 2.94 0 0 0-.78-1.11c-.34-.31-.77-.54-1.26-.71A5.72 5.72 0 0 0 17.47 5c-.69 0-1.31.11-1.85.32-.54.21-1 .51-1.36.88-.37.37-.65.8-.84 1.3-.18.47-.27.97-.28 1.5h2.14c.01-.31.05-.6.13-.87.09-.29.23-.54.4-.75.18-.21.41-.37.68-.49.27-.12.6-.18.96-.18.31 0 .58.05.81.15.23.1.43.25.59.43.16.18.28.4.37.65.08.25.13.52.13.81 0 .22-.03.43-.08.65-.06.22-.15.45-.29.7-.14.25-.32.53-.56.83-.23.3-.52.65-.88 1.03l-4.17 4.55V18H22v-1.71h-5.95zM8 7H6v4H2v2h4v4h2v-4h4v-2H8V7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_exposure_zero_24px"><path d="M16.14 12.5c0 1-.1 1.85-.3 2.55-.2.7-.48 1.27-.83 1.7-.36.44-.79.75-1.3.95-.51.2-1.07.3-1.7.3-.62 0-1.18-.1-1.69-.3-.51-.2-.95-.51-1.31-.95-.36-.44-.65-1.01-.85-1.7-.2-.7-.3-1.55-.3-2.55v-2.04c0-1 .1-1.85.3-2.55.2-.7.48-1.26.84-1.69.36-.43.8-.74 1.31-.93C10.81 5.1 11.38 5 12 5c.63 0 1.19.1 1.7.29.51.19.95.5 1.31.93.36.43.64.99.84 1.69.2.7.3 1.54.3 2.55v2.04zm-2.11-2.36c0-.64-.05-1.18-.13-1.62-.09-.44-.22-.79-.4-1.06-.17-.27-.39-.46-.64-.58-.25-.13-.54-.19-.86-.19-.32 0-.61.06-.86.18s-.47.31-.64.58c-.17.27-.31.62-.4 1.06s-.13.98-.13 1.62v2.67c0 .64.05 1.18.14 1.62.09.45.23.81.4 1.09s.39.48.64.61.54.19.87.19c.33 0 .62-.06.87-.19s.46-.33.63-.61c.17-.28.3-.64.39-1.09.09-.45.13-.99.13-1.62v-2.66z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_1_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm11 10h2V5h-4v2h2v8zm7-14H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_24px"><path d="M15.96 10.29l-2.75 3.54-1.96-2.36L8.5 15h11l-3.54-4.71zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_2_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-4-4h-4v-2h2a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-4v2h4v2h-2a2 2 0 0 0-2 2v4h6v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_3_24px"><path d="M21 1H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm14 8v-1.5c0-.83-.67-1.5-1.5-1.5.83 0 1.5-.67 1.5-1.5V7a2 2 0 0 0-2-2h-4v2h4v2h-2v2h2v2h-4v2h4a2 2 0 0 0 2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_4_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm12 10h2V5h-2v4h-2V5h-2v6h4v4zm6-14H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_5_24px"><path d="M21 1H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm14 8v-2a2 2 0 0 0-2-2h-2V7h4V5h-6v6h4v2h-4v2h4a2 2 0 0 0 2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_6_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-8-2h2a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2h-2V7h4V5h-4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2zm0-4h2v2h-2v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_7_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-8-2l4-8V5h-6v2h4l-4 8h2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_8_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-8-2h2a2 2 0 0 0 2-2v-1.5c0-.83-.67-1.5-1.5-1.5.83 0 1.5-.67 1.5-1.5V7a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v1.5c0 .83.67 1.5 1.5 1.5-.83 0-1.5.67-1.5 1.5V13a2 2 0 0 0 2 2zm0-8h2v2h-2V7zm0 4h2v2h-2v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_9_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM15 5h-2a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2v2h-4v2h4a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 4h-2V7h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_9_plus_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm11 7V8a2 2 0 0 0-2-2h-1a2 2 0 0 0-2 2v1a2 2 0 0 0 2 2h1v1H9v2h3a2 2 0 0 0 2-2zm-3-3V8h1v1h-1zm10-8H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 8h-2V7h-2v2h-2v2h2v2h2v-2h2v6H7V3h14v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_b_and_w_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16l-7-8v8H5l7-8V5h7v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_center_focus_24px"><path d="M5 15H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zM12 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_drama_24px"><path d="M19.35 10.04A7.49 7.49 0 0 0 12 4a7.48 7.48 0 0 0-6.64 4.04A5.996 5.996 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4h2c0-2.76-1.86-5.08-4.4-5.78C8.61 6.88 10.2 6 12 6c3.03 0 5.5 2.47 5.5 5.5v.5H19c1.65 0 3 1.35 3 3s-1.35 3-3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_frames_24px"><path d="M20 4h-4l-4-4-4 4H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H4V6h4.52l3.52-3.5L15.52 6H20v14zM18 8H6v10h12"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_hdr_24px"><path d="M14 6l-3.75 5 2.85 3.8-1.6 1.2C9.81 13.75 7 10 7 10l-6 8h22L14 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_none_24px"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_tilt_shift_24px"><path d="M11 4.07V2.05c-2.01.2-3.84 1-5.32 2.21L7.1 5.69A7.94 7.94 0 0 1 11 4.07zm7.32.19A9.95 9.95 0 0 0 13 2.05v2.02c1.46.18 2.79.76 3.9 1.62l1.42-1.43zM19.93 11h2.02c-.2-2.01-1-3.84-2.21-5.32L18.31 7.1a7.94 7.94 0 0 1 1.62 3.9zM5.69 7.1L4.26 5.68A9.95 9.95 0 0 0 2.05 11h2.02a7.94 7.94 0 0 1 1.62-3.9zM4.07 13H2.05c.2 2.01 1 3.84 2.21 5.32l1.43-1.43A7.868 7.868 0 0 1 4.07 13zM15 12c0-1.66-1.34-3-3-3s-3 1.34-3 3 1.34 3 3 3 3-1.34 3-3zm3.31 4.9l1.43 1.43a9.98 9.98 0 0 0 2.21-5.32h-2.02a7.945 7.945 0 0 1-1.62 3.89zM13 19.93v2.02c2.01-.2 3.84-1 5.32-2.21l-1.43-1.43c-1.1.86-2.43 1.44-3.89 1.62zm-7.32-.19A9.98 9.98 0 0 0 11 21.95v-2.02a7.94 7.94 0 0 1-3.9-1.62l-1.42 1.43z"/></symbol><symbol viewBox="0 0 24 24" id="ic_filter_vintage_24px"><path d="M18.7 12.4a6.06 6.06 0 0 0-.86-.4c.29-.11.58-.24.86-.4a6.012 6.012 0 0 0 3-5.19 6.007 6.007 0 0 0-6 0c-.28.16-.54.35-.78.54.05-.31.08-.63.08-.95 0-2.22-1.21-4.15-3-5.19C10.21 1.85 9 3.78 9 6c0 .32.03.64.08.95-.24-.2-.5-.39-.78-.55a6.008 6.008 0 0 0-6 0 5.97 5.97 0 0 0 3 5.19c.28.16.57.29.86.4-.29.11-.58.24-.86.4a6.012 6.012 0 0 0-3 5.19 6.007 6.007 0 0 0 6 0c.28-.16.54-.35.78-.54-.05.32-.08.64-.08.96 0 2.22 1.21 4.15 3 5.19 1.79-1.04 3-2.97 3-5.19 0-.32-.03-.64-.08-.95.24.2.5.38.78.54a6.008 6.008 0 0 0 6 0 6.012 6.012 0 0 0-3-5.19zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flare_24px"><path d="M7 11H1v2h6v-2zm2.17-3.24L7.05 5.64 5.64 7.05l2.12 2.12 1.41-1.41zM13 1h-2v6h2V1zm5.36 6.05l-1.41-1.41-2.12 2.12 1.41 1.41 2.12-2.12zM17 11v2h6v-2h-6zm-5-2c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3zm2.83 7.24l2.12 2.12 1.41-1.41-2.12-2.12-1.41 1.41zm-9.19.71l1.41 1.41 2.12-2.12-1.41-1.41-2.12 2.12zM11 23h2v-6h-2v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flash_auto_24px"><path d="M3 2v12h3v9l7-12H9l4-9H3zm16 0h-2l-3.2 9h1.9l.7-2h3.2l.7 2h1.9L19 2zm-2.15 5.65L18 4l1.15 3.65h-2.3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flash_off_24px"><path d="M3.27 3L2 4.27l5 5V13h3v9l3.58-6.14L17.73 20 19 18.73 3.27 3zM17 10h-4l4-8H7v2.18l8.46 8.46L17 10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flash_on_24px"><path d="M7 2v11h3v9l7-12h-4l4-8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flip_24px"><path d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_gradient_24px"><path d="M11 9h2v2h-2zm-2 2h2v2H9zm4 0h2v2h-2zm2-2h2v2h-2zM7 9h2v2H7zm12-6H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 18H7v-2h2v2zm4 0h-2v-2h2v2zm4 0h-2v-2h2v2zm2-7h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v2H9v-2H7v2H5v-2h2v-2H5V5h14v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_grain_24px"><path d="M10 12c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zM6 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12-8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-4 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_grid_off_24px"><path d="M8 4v1.45l2 2V4h4v4h-3.45l2 2H14v1.45l2 2V10h4v4h-3.45l2 2H20v1.45l2 2V4c0-1.1-.9-2-2-2H4.55l2 2H8zm8 0h4v4h-4V4zM1.27 1.27L0 2.55l2 2V20c0 1.1.9 2 2 2h15.46l2 2 1.27-1.27L1.27 1.27zM10 12.55L11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H4v-4h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.54V20zm2 0v-1.46L17.46 20H16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_grid_on_24px"><path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H4v-4h4v4zm0-6H4v-4h4v4zm0-6H4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hdr_off_24px"><path d="M17.5 15v-2h1.1l.9 2H21l-.9-2.1c.5-.2.9-.8.9-1.4v-1c0-.8-.7-1.5-1.5-1.5H16v4.9l1.1 1.1h.4zm0-4.5h2v1h-2v-1zm-4.5 0v.4l1.5 1.5v-1.9c0-.8-.7-1.5-1.5-1.5h-1.9l1.5 1.5h.4zm-3.5-1l-7-7-1.1 1L6.9 9h-.4v2h-2V9H3v6h1.5v-2.5h2V15H8v-4.9l1.5 1.5V15h3.4l7.6 7.6 1.1-1.1-12.1-12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hdr_on_24px"><path d="M21 11.5v-1c0-.8-.7-1.5-1.5-1.5H16v6h1.5v-2h1.1l.9 2H21l-.9-2.1c.5-.3.9-.8.9-1.4zm-1.5 0h-2v-1h2v1zm-13-.5h-2V9H3v6h1.5v-2.5h2V15H8V9H6.5v2zM13 9H9.5v6H13c.8 0 1.5-.7 1.5-1.5v-3c0-.8-.7-1.5-1.5-1.5zm0 4.5h-2v-3h2v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hdr_strong_24px"><path d="M17 6c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zM5 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hdr_weak_24px"><path d="M5 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm12-2c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_healing_24px"><path d="M17.73 12.02l3.98-3.98a.996.996 0 0 0 0-1.41l-4.34-4.34a.996.996 0 0 0-1.41 0l-3.98 3.98L8 2.29a1 1 0 0 0-1.41 0L2.25 6.63a.996.996 0 0 0 0 1.41l3.98 3.98L2.25 16a.996.996 0 0 0 0 1.41l4.34 4.34c.39.39 1.02.39 1.41 0l3.98-3.98 3.98 3.98c.2.2.45.29.71.29.26 0 .51-.1.71-.29l4.34-4.34a.996.996 0 0 0 0-1.41l-3.99-3.98zM12 9c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-4.71 1.96L3.66 7.34l3.63-3.63 3.62 3.62-3.62 3.63zM10 13c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm2 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm2-4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2.66 9.34l-3.63-3.62 3.63-3.63 3.62 3.62-3.62 3.63z"/></symbol><symbol viewBox="0 0 24 24" id="ic_image_24px"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_image_aspect_ratio_24px"><path d="M16 10h-2v2h2v-2zm0 4h-2v2h2v-2zm-8-4H6v2h2v-2zm4 0h-2v2h2v-2zm8-6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V6h16v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_iso_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5.5 7.5h2v-2H9v2h2V9H9v2H7.5V9h-2V7.5zM19 19H5L19 5v14zm-2-2v-1.5h-5V17h5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_landscape_24px"><path d="M14 6l-3.75 5 2.85 3.8-1.6 1.2C9.81 13.75 7 10 7 10l-6 8h22L14 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_leak_add_24px"><path d="M6 3H3v3c1.66 0 3-1.34 3-3zm8 0h-2a9 9 0 0 1-9 9v2c6.08 0 11-4.93 11-11zm-4 0H8c0 2.76-2.24 5-5 5v2c3.87 0 7-3.13 7-7zm0 18h2a9 9 0 0 1 9-9v-2c-6.07 0-11 4.93-11 11zm8 0h3v-3c-1.66 0-3 1.34-3 3zm-4 0h2c0-2.76 2.24-5 5-5v-2c-3.87 0-7 3.13-7 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_leak_remove_24px"><path d="M10 3H8c0 .37-.04.72-.12 1.06l1.59 1.59C9.81 4.84 10 3.94 10 3zM3 4.27l2.84 2.84C5.03 7.67 4.06 8 3 8v2c1.61 0 3.09-.55 4.27-1.46L8.7 9.97A8.99 8.99 0 0 1 3 12v2c2.71 0 5.19-.99 7.11-2.62l2.5 2.5A11.044 11.044 0 0 0 10 21h2c0-2.16.76-4.14 2.03-5.69l1.43 1.43A6.922 6.922 0 0 0 14 21h2c0-1.06.33-2.03.89-2.84L19.73 21 21 19.73 4.27 3 3 4.27zM14 3h-2c0 1.5-.37 2.91-1.02 4.16l1.46 1.46C13.42 6.98 14 5.06 14 3zm5.94 13.12c.34-.08.69-.12 1.06-.12v-2c-.94 0-1.84.19-2.66.52l1.6 1.6zm-4.56-4.56l1.46 1.46A8.98 8.98 0 0 1 21 12v-2c-2.06 0-3.98.58-5.62 1.56z"/></symbol><symbol viewBox="0 0 24 24" id="ic_lens_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_linked_camera_24px"><circle cx="12" cy="14" r="3.2"/><path d="M16 3.33A4.67 4.67 0 0 1 20.67 8H22c0-3.31-2.69-6-6-6v1.33M16 6c1.11 0 2 .89 2 2h1.33A3.33 3.33 0 0 0 16 4.67V6"/><path d="M17 9c0-1.11-.89-2-2-2V4H9L7.17 6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9h-5zm-5 10c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_24px"><path d="M12 10c-3.86 0-7 3.14-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.86-3.14-7-7-7zm0-4C5.93 6 1 10.93 1 17h2c0-4.96 4.04-9 9-9s9 4.04 9 9h2c0-6.07-4.93-11-11-11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_3_24px"><path d="M19.01 3h-14c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 7.5c0 .83-.67 1.5-1.5 1.5.83 0 1.5.67 1.5 1.5V15a2 2 0 0 1-2 2h-4v-2h4v-2h-2v-2h2V9h-4V7h4a2 2 0 0 1 2 2v1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_4_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 14h-2v-4H9V7h2v4h2V7h2v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_5_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h2a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H9v-2h4v-2H9V7h6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_6_24px"><path d="M11 15h2v-2h-2v2zm8-12H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h2a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_one_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14h-2V9h-2V7h4v10z"/></symbol><symbol viewBox="0 0 24 24" id="ic_looks_two_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 8a2 2 0 0 1-2 2h-2v2h4v2H9v-4a2 2 0 0 1 2-2h2V9H9V7h4a2 2 0 0 1 2 2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_loupe_24px"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.49 2 2 6.49 2 12s4.49 10 10 10h8c1.1 0 2-.9 2-2v-8c0-5.51-4.49-10-10-10zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_monochrome_photos_24px"><path d="M20 5h-3.2L15 3H9L7.2 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 14h-8v-1c-2.8 0-5-2.2-5-5s2.2-5 5-5V7h8v12zm-3-6c0-2.8-2.2-5-5-5v1.8c1.8 0 3.2 1.4 3.2 3.2s-1.4 3.2-3.2 3.2V18c2.8 0 5-2.2 5-5zm-8.2 0c0 1.8 1.4 3.2 3.2 3.2V9.8c-1.8 0-3.2 1.4-3.2 3.2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_movie_creation_24px"><path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_movie_filter_24px"><path d="M18 4l2 3h-3l-2-3h-2l2 3h-3l-2-3H8l2 3H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4zm-6.75 11.25L10 18l-1.25-2.75L6 14l2.75-1.25L10 10l1.25 2.75L14 14l-2.75 1.25zm5.69-3.31L16 14l-.94-2.06L13 11l2.06-.94L16 8l.94 2.06L19 11l-2.06.94z"/></symbol><symbol viewBox="0 0 24 24" id="ic_music_note_24px"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_nature_24px"><path d="M13 16.12a7 7 0 0 0 6.17-6.95c0-3.87-3.13-7-7-7s-7 3.13-7 7A6.98 6.98 0 0 0 11 16.06V20H5v2h14v-2h-6v-3.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_nature_people_24px"><path d="M22.17 9.17c0-3.87-3.13-7-7-7s-7 3.13-7 7A6.98 6.98 0 0 0 14 16.06V20H6v-3h1v-4c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v4h1v5h16v-2h-3v-3.88a7 7 0 0 0 6.17-6.95zM4.5 11c.83 0 1.5-.67 1.5-1.5S5.33 8 4.5 8 3 8.67 3 9.5 3.67 11 4.5 11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_navigate_before_24px"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_navigate_next_24px"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_palette_24px"><path d="M12 3a9 9 0 0 0 0 18c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_panorama_24px"><path d="M23 18V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zM8.5 12.5l2.5 3.01L14.5 11l4.5 6H5l3.5-4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_panorama_fish_eye_24px"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_panorama_horizontal_24px"><path d="M20 6.54v10.91c-2.6-.77-5.28-1.16-8-1.16-2.72 0-5.4.39-8 1.16V6.54c2.6.77 5.28 1.16 8 1.16 2.72.01 5.4-.38 8-1.16M21.43 4c-.1 0-.2.02-.31.06C18.18 5.16 15.09 5.7 12 5.7c-3.09 0-6.18-.55-9.12-1.64A.94.94 0 0 0 2.57 4c-.34 0-.57.23-.57.63v14.75c0 .39.23.62.57.62.1 0 .2-.02.31-.06 2.94-1.1 6.03-1.64 9.12-1.64 3.09 0 6.18.55 9.12 1.64.11.04.21.06.31.06.33 0 .57-.23.57-.63V4.63c0-.4-.24-.63-.57-.63z"/></symbol><symbol viewBox="0 0 24 24" id="ic_panorama_vertical_24px"><path d="M19.94 21.12c-1.1-2.94-1.64-6.03-1.64-9.12 0-3.09.55-6.18 1.64-9.12a.94.94 0 0 0 .06-.31c0-.34-.23-.57-.63-.57H4.63c-.4 0-.63.23-.63.57 0 .1.02.2.06.31C5.16 5.82 5.71 8.91 5.71 12c0 3.09-.55 6.18-1.64 9.12-.05.11-.07.22-.07.31 0 .33.23.57.63.57h14.75c.39 0 .63-.24.63-.57-.01-.1-.03-.2-.07-.31zM6.54 20c.77-2.6 1.16-5.28 1.16-8 0-2.72-.39-5.4-1.16-8h10.91c-.77 2.6-1.16 5.28-1.16 8 0 2.72.39 5.4 1.16 8H6.54z"/></symbol><symbol viewBox="0 0 24 24" id="ic_panorama_wide_angle_24px"><path d="M12 6c2.45 0 4.71.2 7.29.64A21 21 0 0 1 20 12a21 21 0 0 1-.71 5.36c-2.58.44-4.84.64-7.29.64s-4.71-.2-7.29-.64A21 21 0 0 1 4 12a21 21 0 0 1 .71-5.36C7.29 6.2 9.55 6 12 6m0-2c-2.73 0-5.22.24-7.95.72l-.93.16-.25.9C2.29 7.85 2 9.93 2 12s.29 4.15.87 6.22l.25.89.93.16c2.73.49 5.22.73 7.95.73s5.22-.24 7.95-.72l.93-.16.25-.89c.58-2.08.87-4.16.87-6.23s-.29-4.15-.87-6.22l-.25-.89-.93-.16C17.22 4.24 14.73 4 12 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_24px"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_album_24px"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4zm0 15l3-3.86 2.14 2.58 3-3.86L18 19H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_camera_24px"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_filter_24px"><path d="M19.02 10v9H5V5h9V3H5.02c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-9h-2zM17 10l.94-2.06L20 7l-2.06-.94L17 4l-.94 2.06L14 7l2.06.94zm-3.75.75L12 8l-1.25 2.75L8 12l2.75 1.25L12 16l1.25-2.75L16 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_library_24px"><path d="M22 16V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2zm-11-4l2.03 2.71L16 11l4 5H8l3-4zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_size_select_actual_24px"><path d="M21 3H3C2 3 1 4 1 5v14c0 1.1.9 2 2 2h18c1 0 2-1 2-2V5c0-1-1-2-2-2zM5 17l3.5-4.5 2.5 3.01L14.5 11l4.5 6H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_size_select_large_24px"><path d="M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_photo_size_select_small_24px"><path d="M23 15h-2v2h2v-2zm0-4h-2v2h2v-2zm0 8h-2v2c1 0 2-1 2-2zM15 3h-2v2h2V3zm8 4h-2v2h2V7zm-2-4v2h2c0-1-1-2-2-2zM3 21h8v-6H1v4c0 1.1.9 2 2 2zM3 7H1v2h2V7zm12 12h-2v2h2v-2zm4-16h-2v2h2V3zm0 16h-2v2h2v-2zM3 3C2 3 1 4 1 5h2V3zm0 8H1v2h2v-2zm8-8H9v2h2V3zM7 3H5v2h2V3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_picture_as_pdf_24px"><path d="M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 7.5c0 .83-.67 1.5-1.5 1.5H9v2H7.5V7H10c.83 0 1.5.67 1.5 1.5v1zm5 2c0 .83-.67 1.5-1.5 1.5h-2.5V7H15c.83 0 1.5.67 1.5 1.5v3zm4-3H19v1h1.5V11H19v2h-1.5V7h3v1.5zM9 9.5h1v-1H9v1zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm10 5.5h1v-3h-1v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_portrait_24px"><path d="M12 12.25c1.24 0 2.25-1.01 2.25-2.25S13.24 7.75 12 7.75 9.75 8.76 9.75 10s1.01 2.25 2.25 2.25zm4.5 4c0-1.5-3-2.25-4.5-2.25s-4.5.75-4.5 2.25V17h9v-.75zM19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_remove_red_eye_24px"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rotate_90_degrees_ccw_24px"><path d="M7.34 6.41L.86 12.9l6.49 6.48 6.49-6.48-6.5-6.49zM3.69 12.9l3.66-3.66L11 12.9l-3.66 3.66-3.65-3.66zm15.67-6.26A8.95 8.95 0 0 0 13 4V.76L8.76 5 13 9.24V6c1.79 0 3.58.68 4.95 2.05a7.007 7.007 0 0 1 0 9.9 6.973 6.973 0 0 1-7.79 1.44l-1.49 1.49C10.02 21.62 11.51 22 13 22c2.3 0 4.61-.88 6.36-2.64a8.98 8.98 0 0 0 0-12.72z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rotate_left_24px"><path d="M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rotate_right_24px"><path d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11a7.906 7.906 0 0 0-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"/></symbol><symbol viewBox="0 0 24 24" id="ic_slideshow_24px"><path d="M10 8v8l5-4-5-4zm9-5H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_straighten_24px"><path d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H3V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_style_24px"><path d="M2.53 19.65l1.34.56v-9.03l-2.43 5.86a2.02 2.02 0 0 0 1.09 2.61zm19.5-3.7L17.07 3.98a2.013 2.013 0 0 0-1.81-1.23c-.26 0-.53.04-.79.15L7.1 5.95a2 2 0 0 0-1.08 2.6l4.96 11.97a1.998 1.998 0 0 0 2.6 1.08l7.36-3.05a1.994 1.994 0 0 0 1.09-2.6zM7.88 8.75c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-2 11c0 1.1.9 2 2 2h1.45l-3.45-8.34v6.34z"/></symbol><symbol viewBox="0 0 24 24" id="ic_switch_camera_24px"><path d="M20 4h-3.17L15 2H9L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 11.5V13H9v2.5L5.5 12 9 8.5V11h6V8.5l3.5 3.5-3.5 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_switch_video_24px"><path d="M18 9.5V6c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h14c.55 0 1-.45 1-1v-3.5l4 4v-13l-4 4zm-5 6V13H7v2.5L3.5 12 7 8.5V11h6V8.5l3.5 3.5-3.5 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tag_faces_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_texture_24px"><path d="M19.51 3.08L3.08 19.51c.09.34.27.65.51.9.25.24.56.42.9.51L20.93 4.49c-.19-.69-.73-1.23-1.42-1.41zM11.88 3L3 11.88v2.83L14.71 3h-2.83zM5 3c-1.1 0-2 .9-2 2v2l4-4H5zm14 18c.55 0 1.05-.22 1.41-.59.37-.36.59-.86.59-1.41v-2l-4 4h2zm-9.71 0h2.83L21 12.12V9.29L9.29 21z"/></symbol><symbol viewBox="0 0 24 24" id="ic_timelapse_24px"><path d="M16.24 7.76A5.974 5.974 0 0 0 12 6v6l-4.24 4.24c2.34 2.34 6.14 2.34 8.49 0a5.99 5.99 0 0 0-.01-8.48zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_timer_10_24px"><path d="M0 7.72V9.4l3-1V18h2V6h-.25L0 7.72zm23.78 6.65c-.14-.28-.35-.53-.63-.74-.28-.21-.61-.39-1.01-.53s-.85-.27-1.35-.38a6.64 6.64 0 0 1-.87-.23 2.61 2.61 0 0 1-.55-.25.717.717 0 0 1-.28-.3.978.978 0 0 1 .01-.8c.06-.13.15-.25.27-.34.12-.1.27-.18.45-.24s.4-.09.64-.09c.25 0 .47.04.66.11.19.07.35.17.48.29.13.12.22.26.29.42.06.16.1.32.1.49h1.95a2.517 2.517 0 0 0-.93-1.97c-.3-.25-.66-.44-1.09-.59C21.49 9.07 21 9 20.46 9c-.51 0-.98.07-1.39.21-.41.14-.77.33-1.06.57-.29.24-.51.52-.67.84-.16.32-.23.65-.23 1.01s.08.69.23.96c.15.28.36.52.64.73.27.21.6.38.98.53.38.14.81.26 1.27.36.39.08.71.17.95.26s.43.19.57.29c.13.1.22.22.27.34.05.12.07.25.07.39 0 .32-.13.57-.4.77-.27.2-.66.29-1.17.29-.22 0-.43-.02-.64-.08-.21-.05-.4-.13-.56-.24a1.333 1.333 0 0 1-.59-1.11h-1.89c0 .36.08.71.24 1.05.16.34.39.65.7.93.31.27.69.49 1.15.66.46.17.98.25 1.58.25.53 0 1.01-.06 1.44-.19.43-.13.8-.31 1.11-.54.31-.23.54-.51.71-.83.17-.32.25-.67.25-1.06-.02-.4-.09-.74-.24-1.02zm-9.96-7.32c-.34-.4-.75-.7-1.23-.88-.47-.18-1.01-.27-1.59-.27-.58 0-1.11.09-1.59.27-.48.18-.89.47-1.23.88-.34.41-.6.93-.79 1.59-.18.65-.28 1.45-.28 2.39v1.92c0 .94.09 1.74.28 2.39.19.66.45 1.19.8 1.6.34.41.75.71 1.23.89.48.18 1.01.28 1.59.28.59 0 1.12-.09 1.59-.28.48-.18.88-.48 1.22-.89.34-.41.6-.94.78-1.6.18-.65.28-1.45.28-2.39v-1.92c0-.94-.09-1.74-.28-2.39-.18-.66-.44-1.19-.78-1.59zm-.92 6.17c0 .6-.04 1.11-.12 1.53-.08.42-.2.76-.36 1.02-.16.26-.36.45-.59.57-.23.12-.51.18-.82.18-.3 0-.58-.06-.82-.18s-.44-.31-.6-.57c-.16-.26-.29-.6-.38-1.02-.09-.42-.13-.93-.13-1.53v-2.5c0-.6.04-1.11.13-1.52.09-.41.21-.74.38-1 .16-.25.36-.43.6-.55.24-.11.51-.17.81-.17.31 0 .58.06.81.17.24.11.44.29.6.55.16.25.29.58.37.99.08.41.13.92.13 1.52v2.51z"/></symbol><symbol viewBox="0 0 24 24" id="ic_timer_24px"><path d="M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.03-6.61l1.42-1.42c-.43-.51-.9-.99-1.41-1.41l-1.42 1.42A8.962 8.962 0 0 0 12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9a8.994 8.994 0 0 0 7.03-14.61zM12 20c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_timer_3_24px"><path d="M11.61 12.97c-.16-.24-.36-.46-.62-.65a3.38 3.38 0 0 0-.93-.48c.3-.14.57-.3.8-.5.23-.2.42-.41.57-.64.15-.23.27-.46.34-.71.08-.24.11-.49.11-.73 0-.55-.09-1.04-.28-1.46-.18-.42-.44-.77-.78-1.06-.33-.28-.73-.5-1.2-.64-.45-.13-.97-.2-1.53-.2-.55 0-1.06.08-1.52.24-.47.17-.87.4-1.2.69-.33.29-.6.63-.78 1.03-.2.39-.29.83-.29 1.29h1.98c0-.26.05-.49.14-.69.09-.2.22-.38.38-.52.17-.14.36-.25.58-.33.22-.08.46-.12.73-.12.61 0 1.06.16 1.36.47.3.31.44.75.44 1.32 0 .27-.04.52-.12.74-.08.22-.21.41-.38.57-.17.16-.38.28-.63.37-.25.09-.55.13-.89.13H6.72v1.57H7.9c.34 0 .64.04.91.11.27.08.5.19.69.35.19.16.34.36.44.61.1.24.16.54.16.87 0 .62-.18 1.09-.53 1.42-.35.33-.84.49-1.45.49-.29 0-.56-.04-.8-.13-.24-.08-.44-.2-.61-.36-.17-.16-.3-.34-.39-.56-.09-.22-.14-.46-.14-.72H4.19c0 .55.11 1.03.32 1.45.21.42.5.77.86 1.05s.77.49 1.24.63.96.21 1.48.21c.57 0 1.09-.08 1.58-.23.49-.15.91-.38 1.26-.68.36-.3.64-.66.84-1.1.2-.43.3-.93.3-1.48 0-.29-.04-.58-.11-.86-.08-.25-.19-.51-.35-.76zm9.26 1.4c-.14-.28-.35-.53-.63-.74-.28-.21-.61-.39-1.01-.53s-.85-.27-1.35-.38a6.64 6.64 0 0 1-.87-.23 2.61 2.61 0 0 1-.55-.25.717.717 0 0 1-.28-.3c-.05-.11-.08-.24-.08-.39a.946.946 0 0 1 .36-.75c.12-.1.27-.18.45-.24s.4-.09.64-.09c.25 0 .47.04.66.11.19.07.35.17.48.29.13.12.22.26.29.42.06.16.1.32.1.49h1.95a2.517 2.517 0 0 0-.93-1.97c-.3-.25-.66-.44-1.09-.59-.43-.15-.92-.22-1.46-.22-.51 0-.98.07-1.39.21-.41.14-.77.33-1.06.57-.29.24-.51.52-.67.84-.16.32-.23.65-.23 1.01s.08.68.23.96c.15.28.37.52.64.73.27.21.6.38.98.53.38.14.81.26 1.27.36.39.08.71.17.95.26s.43.19.57.29c.13.1.22.22.27.34.05.12.07.25.07.39 0 .32-.13.57-.4.77-.27.2-.66.29-1.17.29-.22 0-.43-.02-.64-.08-.21-.05-.4-.13-.56-.24a1.333 1.333 0 0 1-.59-1.11h-1.89c0 .36.08.71.24 1.05.16.34.39.65.7.93.31.27.69.49 1.15.66.46.17.98.25 1.58.25.53 0 1.01-.06 1.44-.19.43-.13.8-.31 1.11-.54.31-.23.54-.51.71-.83.17-.32.25-.67.25-1.06-.02-.4-.09-.74-.24-1.02z"/></symbol><symbol viewBox="0 0 24 24" id="ic_timer_off_24px"><path d="M19.04 4.55l-1.42 1.42a9.012 9.012 0 0 0-10.57-.49l1.46 1.46C9.53 6.35 10.73 6 12 6c3.87 0 7 3.13 7 7 0 1.27-.35 2.47-.94 3.49l1.45 1.45A8.878 8.878 0 0 0 21 13c0-2.12-.74-4.07-1.97-5.61l1.42-1.42-1.41-1.42zM15 1H9v2h6V1zm-4 8.44l2 2V8h-2v1.44zM3.02 4L1.75 5.27 4.5 8.03A8.905 8.905 0 0 0 3 13c0 4.97 4.02 9 9 9 1.84 0 3.55-.55 4.98-1.5l2.5 2.5 1.27-1.27-7.71-7.71L3.02 4zM12 20c-3.87 0-7-3.13-7-7 0-1.28.35-2.48.95-3.52l9.56 9.56c-1.03.61-2.23.96-3.51.96z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tonality_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.94-.49-7-3.85-7-7.93s3.05-7.44 7-7.93v15.86zm2-15.86c1.03.13 2 .45 2.87.93H13v-.93zM13 7h5.24c.25.31.48.65.68 1H13V7zm0 3h6.74c.08.33.15.66.19 1H13v-1zm0 9.93V19h2.87c-.87.48-1.84.8-2.87.93zM18.24 17H13v-1h5.92c-.2.35-.43.69-.68 1zm1.5-3H13v-1h6.93c-.04.34-.11.67-.19 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_transform_24px"><path d="M22 18v-2H8V4h2L7 1 4 4h2v2H2v2h4v8c0 1.1.9 2 2 2h8v2h-2l3 3 3-3h-2v-2h4zM10 8h6v6h2V8c0-1.1-.9-2-2-2h-6v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tune_24px"><path d="M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_comfy_24px"><path d="M3 9h4V5H3v4zm0 5h4v-4H3v4zm5 0h4v-4H8v4zm5 0h4v-4h-4v4zM8 9h4V5H8v4zm5-4v4h4V5h-4zm5 9h4v-4h-4v4zM3 19h4v-4H3v4zm5 0h4v-4H8v4zm5 0h4v-4h-4v4zm5 0h4v-4h-4v4zm0-14v4h4V5h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_view_compact_24px"><path d="M3 19h6v-7H3v7zm7 0h12v-7H10v7zM3 5v6h19V5H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vignette_24px"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 15c-4.42 0-8-2.69-8-6s3.58-6 8-6 8 2.69 8 6-3.58 6-8 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wb_auto_24px"><path d="M6.85 12.65h2.3L8 9l-1.15 3.65zM22 7l-1.2 6.29L19.3 7h-1.6l-1.49 6.29L15 7h-.76A7.97 7.97 0 0 0 8 4c-4.42 0-8 3.58-8 8s3.58 8 8 8c3.13 0 5.84-1.81 7.15-4.43l.1.43H17l1.5-6.1L20 16h1.75l2.05-9H22zm-11.7 9l-.7-2H6.4l-.7 2H3.8L7 7h2l3.2 9h-1.9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wb_cloudy_24px"><path d="M19.36 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.64-4.96z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wb_incandescent_24px"><path d="M3.55 18.54l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8zM11 22.45h2V19.5h-2v2.95zM4 10.5H1v2h3v-2zm11-4.19V1.5H9v4.81C7.21 7.35 6 9.28 6 11.5c0 3.31 2.69 6 6 6s6-2.69 6-6c0-2.22-1.21-4.15-3-5.19zm5 4.19v2h3v-2h-3zm-2.76 7.66l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wb_iridescent_24px"><path d="M5 14.5h14v-6H5v6zM11 .55V3.5h2V.55h-2zm8.04 2.5l-1.79 1.79 1.41 1.41 1.8-1.79-1.42-1.41zM13 22.45V19.5h-2v2.95h2zm7.45-3.91l-1.8-1.79-1.41 1.41 1.79 1.8 1.42-1.42zM3.55 4.46l1.79 1.79 1.41-1.41-1.79-1.79-1.41 1.41zm1.41 15.49l1.79-1.8-1.41-1.41-1.79 1.79 1.41 1.42z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wb_sunny_24px"><path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-maps-symbol.svg b/skyquake/framework/style/icons/svg-sprite-maps-symbol.svg
new file mode 100755 (executable)
index 0000000..31a70d1
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_add_location_24px"><path d="M12 2C8.14 2 5 5.14 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.86-3.14-7-7-7zm4 8h-3v3h-2v-3H8V8h3V5h2v3h3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_beenhere_24px"><path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-9 15l-5-5 1.41-1.41L10 13.17l7.59-7.59L19 7l-9 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_24px"><path d="M21.71 11.29l-9-9a.996.996 0 0 0-1.41 0l-9 9a.996.996 0 0 0 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9a.996.996 0 0 0 0-1.41zM14 14.5V12h-4v3H8v-4c0-.55.45-1 1-1h5V7.5l3.5 3.5-3.5 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_bike_24px"><path d="M15.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM5 12c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 8.5c-1.9 0-3.5-1.6-3.5-3.5s1.6-3.5 3.5-3.5 3.5 1.6 3.5 3.5-1.6 3.5-3.5 3.5zm5.8-10l2.4-2.4.8.8c1.3 1.3 3 2.1 5.1 2.1V9c-1.5 0-2.7-.6-3.6-1.5l-1.9-1.9c-.5-.4-1-.6-1.6-.6s-1.1.2-1.4.6L7.8 8.4c-.4.4-.6.9-.6 1.4 0 .6.2 1.1.6 1.4L11 14v5h2v-6.2l-2.2-2.3zM19 12c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 8.5c-1.9 0-3.5-1.6-3.5-3.5s1.6-3.5 3.5-3.5 3.5 1.6 3.5 3.5-1.6 3.5-3.5 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_boat_24px"><path d="M20 21c-1.39 0-2.78-.47-4-1.32-2.44 1.71-5.56 1.71-8 0C6.78 20.53 5.39 21 4 21H2v2h2c1.38 0 2.74-.35 4-.99a8.752 8.752 0 0 0 8 0c1.26.65 2.62.99 4 .99h2v-2h-2zM3.95 19H4c1.6 0 3.02-.88 4-2 .98 1.12 2.4 2 4 2s3.02-.88 4-2c.98 1.12 2.4 2 4 2h.05l1.89-6.68c.08-.26.06-.54-.06-.78s-.34-.42-.6-.5L20 10.62V6c0-1.1-.9-2-2-2h-3V1H9v3H6c-1.1 0-2 .9-2 2v4.62l-1.29.42a1.007 1.007 0 0 0-.66 1.28L3.95 19zM6 6h12v3.97L12 8 6 9.97V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_bus_24px"><path d="M4 16c0 .88.39 1.67 1 2.22V20c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h8v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1.78c.61-.55 1-1.34 1-2.22V6c0-3.5-3.58-4-8-4s-8 .5-8 4v10zm3.5 1c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm9 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6H6V6h12v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_car_24px"><path d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_railway_24px"><path d="M4 15.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h12v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V5c0-3.5-3.58-4-8-4s-8 .5-8 4v10.5zm8 1.5c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm6-7H6V5h12v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_run_24px"><path d="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1 2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1l-5.2 2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_subway_24px"><path d="M12 2c-4.42 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h12v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-6H6V6h5v5zm5.5 6c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6h-5V6h5v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_transit_24px"><path d="M12 2c-4.42 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h12v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-6H6V6h5v5zm5.5 6c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6h-5V6h5v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_directions_walk_24px"><path d="M13.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM9.8 8.9L7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3C14.8 12 16.8 13 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7"/></symbol><symbol viewBox="0 0 24 24" id="ic_edit_location_24px"><path d="M12 2C8.14 2 5 5.14 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.86-3.14-7-7-7zm-1.56 10H9v-1.44l3.35-3.34 1.43 1.43L10.44 12zm4.45-4.45l-.7.7-1.44-1.44.7-.7a.38.38 0 0 1 .54 0l.9.9c.15.15.15.39 0 .54z"/></symbol><symbol viewBox="0 0 24 24" id="ic_ev_station_24px"><path d="M19.77 7.23l.01-.01-3.72-3.72L15 4.56l2.11 2.11c-.94.36-1.61 1.26-1.61 2.33a2.5 2.5 0 0 0 2.5 2.5c.36 0 .69-.08 1-.21v7.21c0 .55-.45 1-1 1s-1-.45-1-1V14c0-1.1-.9-2-2-2h-1V5c0-1.1-.9-2-2-2H6c-1.1 0-2 .9-2 2v16h10v-7.5h1.5v5a2.5 2.5 0 0 0 5 0V9c0-.69-.28-1.32-.73-1.77zM18 10c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zM8 18v-4.5H6L10 6v5h2l-4 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_flight_24px"><path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hotel_24px"><path d="M7 13c1.66 0 3-1.34 3-3S8.66 7 7 7s-3 1.34-3 3 1.34 3 3 3zm12-6h-8v7H3V5H1v15h2v-3h18v3h2v-9a4 4 0 0 0-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_layers_24px"><path d="M11.99 18.54l-7.37-5.73L3 14.07l9 7 9-7-1.63-1.27-7.38 5.74zM12 16l7.36-5.73L21 9l-9-7-9 7 1.63 1.27L12 16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_layers_clear_24px"><path d="M19.81 14.99l1.19-.92-1.43-1.43-1.19.92 1.43 1.43zm-.45-4.72L21 9l-9-7-2.91 2.27 7.87 7.88 2.4-1.88zM3.27 1L2 2.27l4.22 4.22L3 9l1.63 1.27L12 16l2.1-1.63 1.43 1.43L12 18.54l-7.37-5.73L3 14.07l9 7 4.95-3.85L20.73 21 22 19.73 3.27 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_activity_24px"><path d="M20 12c0-1.1.9-2 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-1.99.9-1.99 2v4c1.1 0 1.99.9 1.99 2s-.89 2-2 2v4c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-4c-1.1 0-2-.9-2-2zm-4.42 4.8L12 14.5l-3.58 2.3 1.08-4.12-3.29-2.69 4.24-.25L12 5.8l1.54 3.95 4.24.25-3.29 2.69 1.09 4.11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_airport_24px"><path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_atm_24px"><path d="M11 17h2v-1h1c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1h-3v-1h4V8h-2V7h-2v1h-1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1h3v1H9v2h2v1zm9-13H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4V6h16v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_bar_24px"><path d="M21 5V3H3v2l8 9v5H6v2h12v-2h-5v-5l8-9zM7.43 7L5.66 5h12.69l-1.78 2H7.43z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_cafe_24px"><path d="M20 3H4v10a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4v-3h2c1.11 0 2-.89 2-2V5c0-1.11-.89-2-2-2zm0 5h-2V5h2v3zM2 21h18v-2H2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_car_wash_24px"><path d="M17 5c.83 0 1.5-.67 1.5-1.5 0-1-1.5-2.7-1.5-2.7s-1.5 1.7-1.5 2.7c0 .83.67 1.5 1.5 1.5zm-5 0c.83 0 1.5-.67 1.5-1.5 0-1-1.5-2.7-1.5-2.7s-1.5 1.7-1.5 2.7c0 .83.67 1.5 1.5 1.5zM7 5c.83 0 1.5-.67 1.5-1.5C8.5 2.5 7 .8 7 .8S5.5 2.5 5.5 3.5C5.5 4.33 6.17 5 7 5zm11.92 3.01C18.72 7.42 18.16 7 17.5 7h-11c-.66 0-1.21.42-1.42 1.01L3 14v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 18c-.83 0-1.5-.67-1.5-1.5S5.67 15 6.5 15s1.5.67 1.5 1.5S7.33 18 6.5 18zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 13l1.5-4.5h11L19 13H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_convenience_store_24px"><path d="M19 7V4H5v3H2v13h8v-4h4v4h8V7h-3zm-8 3H9v1h2v1H8V9h2V8H8V7h3v3zm5 2h-1v-2h-2V7h1v2h1V7h1v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_dining_24px"><path d="M8.1 13.34l2.83-2.83L3.91 3.5a4.008 4.008 0 0 0 0 5.66l4.19 4.18zm6.78-1.81c1.53.71 3.68.21 5.27-1.38 1.91-1.91 2.28-4.65.81-6.12-1.46-1.46-4.2-1.1-6.12.81-1.59 1.59-2.09 3.74-1.38 5.27L3.7 19.87l1.41 1.41L12 14.41l6.88 6.88 1.41-1.41L13.41 13l1.47-1.47z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_drink_24px"><path d="M3 2l2.01 18.23C5.13 21.23 5.97 22 7 22h10c1.03 0 1.87-.77 1.99-1.77L21 2H3zm9 17c-1.66 0-3-1.34-3-3 0-2 3-5.4 3-5.4s3 3.4 3 5.4c0 1.66-1.34 3-3 3zm6.33-11H5.67l-.44-4h13.53l-.43 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_florist_24px"><path d="M12 22a9 9 0 0 0 9-9 9 9 0 0 0-9 9zM5.6 10.25a2.5 2.5 0 0 0 3.92 2.06l-.02.19a2.5 2.5 0 0 0 5 0l-.02-.19c.4.28.89.44 1.42.44a2.5 2.5 0 0 0 2.5-2.5c0-1-.59-1.85-1.43-2.25a2.49 2.49 0 0 0 1.43-2.25 2.5 2.5 0 0 0-3.92-2.06l.02-.19a2.5 2.5 0 1 0-5 0l.02.19c-.4-.28-.89-.44-1.42-.44a2.5 2.5 0 0 0-2.5 2.5c0 1 .59 1.85 1.43 2.25a2.49 2.49 0 0 0-1.43 2.25zM12 5.5a2.5 2.5 0 0 1 0 5 2.5 2.5 0 0 1 0-5zM3 13a9 9 0 0 0 9 9 9 9 0 0 0-9-9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_gas_station_24px"><path d="M19.77 7.23l.01-.01-3.72-3.72L15 4.56l2.11 2.11c-.94.36-1.61 1.26-1.61 2.33a2.5 2.5 0 0 0 2.5 2.5c.36 0 .69-.08 1-.21v7.21c0 .55-.45 1-1 1s-1-.45-1-1V14c0-1.1-.9-2-2-2h-1V5c0-1.1-.9-2-2-2H6c-1.1 0-2 .9-2 2v16h10v-7.5h1.5v5a2.5 2.5 0 0 0 5 0V9c0-.69-.28-1.32-.73-1.77zM12 10H6V5h6v5zm6 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_grocery_store_24px"><path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49A1.003 1.003 0 0 0 20 4H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_hospital_24px"><path d="M19 3H5c-1.1 0-1.99.9-1.99 2L3 19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 11h-4v4h-4v-4H6v-4h4V6h4v4h4v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_hotel_24px"><path d="M7 13c1.66 0 3-1.34 3-3S8.66 7 7 7s-3 1.34-3 3 1.34 3 3 3zm12-6h-8v7H3V5H1v15h2v-3h18v3h2v-9a4 4 0 0 0-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_laundry_service_24px"><path d="M9.17 16.83a4.008 4.008 0 0 0 5.66 0 4.008 4.008 0 0 0 0-5.66l-5.66 5.66zM18 2.01L6 2c-1.11 0-2 .89-2 2v16c0 1.11.89 2 2 2h12c1.11 0 2-.89 2-2V4c0-1.11-.89-1.99-2-1.99zM10 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM7 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm5 16c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_library_24px"><path d="M12 11.55C9.64 9.35 6.48 8 3 8v11c3.48 0 6.64 1.35 9 3.55 2.36-2.19 5.52-3.55 9-3.55V8c-3.48 0-6.64 1.35-9 3.55zM12 8c1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3 1.34 3 3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_mall_24px"><path d="M19 6h-2c0-2.76-2.24-5-5-5S7 3.24 7 6H5c-1.1 0-1.99.9-1.99 2L3 20c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-7-3c1.66 0 3 1.34 3 3H9c0-1.66 1.34-3 3-3zm0 10c-2.76 0-5-2.24-5-5h2c0 1.66 1.34 3 3 3s3-1.34 3-3h2c0 2.76-2.24 5-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_movies_24px"><path d="M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_offer_24px"><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_parking_24px"><path d="M13 3H6v18h4v-6h3c3.31 0 6-2.69 6-6s-2.69-6-6-6zm.2 8H10V7h3.2c1.1 0 2 .9 2 2s-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_pharmacy_24px"><path d="M21 5h-2.64l1.14-3.14L17.15 1l-1.46 4H3v2l2 6-2 6v2h18v-2l-2-6 2-6V5zm-5 9h-3v3h-2v-3H8v-2h3V9h2v3h3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_phone_24px"><path d="M6.62 10.79a15.15 15.15 0 0 0 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_pizza_24px"><path d="M12 2C8.43 2 5.23 3.54 3.01 6L12 22l8.99-16C18.78 3.55 15.57 2 12 2zM7 7c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2zm5 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_play_24px"><path d="M20 12c0-1.1.9-2 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-1.99.9-1.99 2v4c1.1 0 1.99.9 1.99 2s-.89 2-2 2v4c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-4c-1.1 0-2-.9-2-2zm-4.42 4.8L12 14.5l-3.58 2.3 1.08-4.12-3.29-2.69 4.24-.25L12 5.8l1.54 3.95 4.24.25-3.29 2.69 1.09 4.11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_post_office_24px"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_printshop_24px"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_see_24px"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_shipping_24px"><path d="M20 8h-3V4H3c-1.1 0-2 .9-2 2v11h2c0 1.66 1.34 3 3 3s3-1.34 3-3h6c0 1.66 1.34 3 3 3s3-1.34 3-3h2v-5l-3-4zM6 18.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm13.5-9l1.96 2.5H17V9.5h2.5zm-1.5 9c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_local_taxi_24px"><path d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5H15V3H9v2H6.5c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_map_24px"><path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM15 19l-6-2.11V5l6 2.11V19z"/></symbol><symbol viewBox="0 0 24 24" id="ic_my_location_24px"><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3A8.994 8.994 0 0 0 13 3.06V1h-2v2.06A8.994 8.994 0 0 0 3.06 11H1v2h2.06A8.994 8.994 0 0 0 11 20.94V23h2v-2.06A8.994 8.994 0 0 0 20.94 13H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_navigation_24px"><path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71z"/></symbol><symbol viewBox="0 0 24 24" id="ic_near_me_24px"><path d="M21 3L3 10.53v.98l6.84 2.65L12.48 21h.98L21 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_person_pin_24px"><path d="M19 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 3.3A2.7 2.7 0 0 1 14.7 8a2.7 2.7 0 0 1-2.7 2.7A2.7 2.7 0 0 1 9.3 8 2.7 2.7 0 0 1 12 5.3zM18 16H6v-.9c0-2 4-3.1 6-3.1s6 1.1 6 3.1v.9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_person_pin_circle_24px"><path d="M12 2C8.14 2 5 5.14 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.86-3.14-7-7-7zm0 2a2 2 0 1 1 0 4 2 2 0 0 1 0-4zm0 10c-1.67 0-3.14-.85-4-2.15.02-1.32 2.67-2.05 4-2.05s3.98.73 4 2.05A4.783 4.783 0 0 1 12 14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pin_drop_24px"><path d="M18 8c0-3.31-2.69-6-6-6S6 4.69 6 8c0 4.5 6 11 6 11s6-6.5 6-11zm-8 0c0-1.1.9-2 2-2s2 .9 2 2a2 2 0 0 1-4 0zM5 20v2h14v-2H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_place_24px"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rate_review_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 14v-2.47l6.88-6.88c.2-.2.51-.2.71 0l1.77 1.77c.2.2.2.51 0 .71L8.47 14H6zm12 0h-7.5l2-2H18v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_restaurant_24px"><path d="M11 9H9V2H7v7H5V2H3v7c0 2.12 1.66 3.84 3.75 3.97V22h2.5v-9.03C11.34 12.84 13 11.12 13 9V2h-2v7zm5-3v8h2.5v8H21V2c-2.76 0-5 2.24-5 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_restaurant_menu_24px"><path d="M8.1 13.34l2.83-2.83L3.91 3.5a4.008 4.008 0 0 0 0 5.66l4.19 4.18zm6.78-1.81c1.53.71 3.68.21 5.27-1.38 1.91-1.91 2.28-4.65.81-6.12-1.46-1.46-4.2-1.1-6.12.81-1.59 1.59-2.09 3.74-1.38 5.27L3.7 19.87l1.41 1.41L12 14.41l6.88 6.88 1.41-1.41L13.41 13l1.47-1.47z"/></symbol><symbol viewBox="0 0 24 24" id="ic_satellite_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.99h3C8 6.65 6.66 8 5 8V4.99zM5 12v-2c2.76 0 5-2.25 5-5.01h2C12 8.86 8.87 12 5 12zm0 6l3.5-4.5 2.5 3.01L14.5 12l4.5 6H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_store_mall_directory_24px"><path d="M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_streetview_24px"><path d="M12.56 14.33c-.34.27-.56.7-.56 1.17V21h7c1.1 0 2-.9 2-2v-5.98c-.94-.33-1.95-.52-3-.52-2.03 0-3.93.7-5.44 1.83z"/><circle cx="18" cy="6" r="5"/><path d="M11.5 6c0-1.08.27-2.1.74-3H5c-1.1 0-2 .9-2 2v14c0 .55.23 1.05.59 1.41l9.82-9.82A6.435 6.435 0 0 1 11.5 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_subway_24px"><circle cx="15.5" cy="16" r="1"/><circle cx="8.5" cy="16" r="1"/><path d="M7.01 9h10v5h-10zM17.8 2.8C16 2.09 13.86 2 12 2c-1.86 0-4 .09-5.8.8C3.53 3.84 2 6.05 2 8.86V22h20V8.86c0-2.81-1.53-5.02-4.2-6.06zm.2 13.08c0 1.45-1.18 2.62-2.63 2.62l1.13 1.12V20H15l-1.5-1.5h-2.83L9.17 20H7.5v-.38l1.12-1.12A2.63 2.63 0 0 1 6 15.88V9c0-2.63 3-3 6-3 3.32 0 6 .38 6 3v6.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_terrain_24px"><path d="M14 6l-3.75 5 2.85 3.8-1.6 1.2C9.81 13.75 7 10 7 10l-6 8h22L14 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_traffic_24px"><path d="M20 10h-3V8.86c1.72-.45 3-2 3-3.86h-3V4c0-.55-.45-1-1-1H8c-.55 0-1 .45-1 1v1H4c0 1.86 1.28 3.41 3 3.86V10H4c0 1.86 1.28 3.41 3 3.86V15H4c0 1.86 1.28 3.41 3 3.86V20c0 .55.45 1 1 1h8c.55 0 1-.45 1-1v-1.14c1.72-.45 3-2 3-3.86h-3v-1.14c1.72-.45 3-2 3-3.86zm-8 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0-5a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0-5a2 2 0 0 1-2-2c0-1.11.89-2 2-2a2 2 0 0 1 0 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_train_24px"><path d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2.23l2-2H14l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-7H6V6h5v4zm2 0V6h5v4h-5zm3.5 7c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tram_24px"><path d="M19 16.94V8.5c0-2.79-2.61-3.4-6.01-3.49l.76-1.51H17V2H7v1.5h4.75l-.76 1.52C7.86 5.11 5 5.73 5 8.5v8.44c0 1.45 1.19 2.66 2.59 2.97L6 21.5v.5h2.23l2-2H14l2 2h2v-.5L16.5 20h-.08c1.69 0 2.58-1.37 2.58-3.06zm-7 1.56c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm5-4.5H7V9h10v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_transfer_within_a_station_24px"><path d="M16.49 15.5v-1.75L14 16.25l2.49 2.5V17H22v-1.5zm3.02 4.25H14v1.5h5.51V23L22 20.5 19.51 18zM9.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM5.75 8.9L3 23h2.1l1.75-8L9 17v6h2v-7.55L8.95 13.4l.6-3C10.85 12 12.8 13 15 13v-2c-1.85 0-3.45-1-4.35-2.45l-.95-1.6C9.35 6.35 8.7 6 8 6c-.25 0-.5.05-.75.15L2 8.3V13h2V9.65l1.75-.75"/></symbol><symbol viewBox="0 0 24 24" id="ic_zoom_out_map_24px"><path d="M15 3l2.3 2.3-2.89 2.87 1.42 1.42L18.7 6.7 21 9V3zM3 9l2.3-2.3 2.87 2.89 1.42-1.42L6.7 5.3 9 3H3zm6 12l-2.3-2.3 2.89-2.87-1.42-1.42L5.3 17.3 3 15v6zm12-6l-2.3 2.3-2.87-2.89-1.42 1.42 2.89 2.87L15 21h6z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-navigation-symbol.svg b/skyquake/framework/style/icons/svg-sprite-navigation-symbol.svg
new file mode 100755 (executable)
index 0000000..780e5fb
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_apps_24px"><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_back_24px"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_downward_24px"><path fill="#010101" d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_drop_down_24px"><path d="M7 10l5 5 5-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_drop_down_circle_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_drop_up_24px"><path d="M7 14l5-5 5 5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_forward_24px"><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_arrow_upward_24px"><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_cancel_24px"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/></symbol><symbol viewBox="0 0 24 24" id="ic_check_24px"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></symbol><symbol viewBox="0 0 24 24" id="ic_chevron_left_24px"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_chevron_right_24px"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_close_24px"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_expand_less_24px"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_expand_more_24px"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_first_page_24px"><path d="M18.41 16.59L13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fullscreen_24px"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fullscreen_exit_24px"><path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_last_page_24px"><path d="M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_menu_24px"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_more_horiz_24px"><path d="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_more_vert_24px"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_refresh_24px"><path d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></symbol><symbol viewBox="0 0 24 24" id="ic_subdirectory_arrow_left_24px"><path d="M11 9l1.42 1.42L8.83 14H18V4h2v12H8.83l3.59 3.58L11 21l-6-6 6-6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_subdirectory_arrow_right_24px"><path d="M19 15l-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_unfold_less_24px"><path d="M7.41 18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z"/></symbol><symbol viewBox="0 0 24 24" id="ic_unfold_more_24px"><path d="M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-notification-symbol.svg b/skyquake/framework/style/icons/svg-sprite-notification-symbol.svg
new file mode 100755 (executable)
index 0000000..97f3ae5
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_adb_24px"><path d="M5 16c0 3.87 3.13 7 7 7s7-3.13 7-7v-4H5v4zM16.12 4.37l2.1-2.1-.82-.83-2.3 2.31C14.16 3.28 13.12 3 12 3s-2.16.28-3.09.75L6.6 1.44l-.82.83 2.1 2.1C6.14 5.64 5 7.68 5 10v1h14v-1c0-2.32-1.14-4.36-2.88-5.63zM9 9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm6 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_flat_24px"><path d="M22 11v2H9V7h9a4 4 0 0 1 4 4zM2 14v2h6v2h8v-2h6v-2H2zm5.14-1.9a3 3 0 0 0-.04-4.24 3 3 0 0 0-4.24.04 3 3 0 0 0 .04 4.24 3 3 0 0 0 4.24-.04z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_flat_angled_24px"><path d="M22.25 14.29l-.69 1.89L9.2 11.71l2.08-5.66 8.56 3.09a4 4 0 0 1 2.41 5.15zM1.5 12.14L8 14.48V19h8v-1.63L20.52 19l.69-1.89-19.02-6.86-.69 1.89zm5.8-1.94a3.01 3.01 0 0 0 1.41-4A3.005 3.005 0 0 0 4.7 4.8a2.99 2.99 0 0 0-1.4 4 2.99 2.99 0 0 0 4 1.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_individual_suite_24px"><path d="M7 13c1.65 0 3-1.35 3-3S8.65 7 7 7s-3 1.35-3 3 1.35 3 3 3zm12-6h-8v7H3V7H1v10h22v-6a4 4 0 0 0-4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_legroom_extra_24px"><path d="M4 12V3H2v9c0 2.76 2.24 5 5 5h6v-2H7c-1.66 0-3-1.34-3-3zm18.83 5.24c-.38-.72-1.29-.97-2.03-.63l-1.09.5-3.41-6.98a2.01 2.01 0 0 0-1.79-1.12L11 9V3H5v8c0 1.66 1.34 3 3 3h7l3.41 7 3.72-1.7c.77-.36 1.1-1.3.7-2.06z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_legroom_normal_24px"><path d="M5 12V3H3v9c0 2.76 2.24 5 5 5h6v-2H8c-1.66 0-3-1.34-3-3zm15.5 6H19v-7c0-1.1-.9-2-2-2h-5V3H6v8c0 1.65 1.35 3 3 3h7v7h4.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_legroom_reduced_24px"><path d="M19.97 19.2c.18.96-.55 1.8-1.47 1.8H14v-3l1-4H9c-1.65 0-3-1.35-3-3V3h6v6h5c1.1 0 2 .9 2 2l-2 7h1.44c.73 0 1.39.49 1.53 1.2zM5 12V3H3v9c0 2.76 2.24 5 5 5h4v-2H8c-1.66 0-3-1.34-3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_recline_extra_24px"><path d="M5.35 5.64c-.9-.64-1.12-1.88-.49-2.79a2.01 2.01 0 0 1 2.79-.49c.9.64 1.12 1.88.49 2.79-.64.9-1.88 1.12-2.79.49zM16 19H8.93a2.99 2.99 0 0 1-2.96-2.54L4 7H2l1.99 9.76A5.01 5.01 0 0 0 8.94 21H16v-2zm.23-4h-4.88l-1.03-4.1c1.58.89 3.28 1.54 5.15 1.22V9.99c-1.63.31-3.44-.27-4.69-1.25L9.14 7.47c-.23-.18-.49-.3-.76-.38a2.21 2.21 0 0 0-.99-.06h-.02a2.268 2.268 0 0 0-1.84 2.61l1.35 5.92A3.008 3.008 0 0 0 9.83 18h6.85l3.82 3 1.5-1.5-5.77-4.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airline_seat_recline_normal_24px"><path d="M7.59 5.41c-.78-.78-.78-2.05 0-2.83.78-.78 2.05-.78 2.83 0 .78.78.78 2.05 0 2.83-.79.79-2.05.79-2.83 0zM6 16V7H4v9c0 2.76 2.24 5 5 5h6v-2H9c-1.66 0-3-1.34-3-3zm14 4.07L14.93 15H11.5v-3.68c1.4 1.15 3.6 2.16 5.5 2.16v-2.16c-1.66.02-3.61-.87-4.67-2.04l-1.4-1.55c-.19-.21-.43-.38-.69-.5-.29-.14-.62-.23-.96-.23h-.03C8.01 7 7 8.01 7 9.25V15c0 1.66 1.34 3 3 3h5.07l3.5 3.5L20 20.07z"/></symbol><symbol viewBox="0 0 24 24" id="ic_bluetooth_audio_24px"><path d="M14.24 12.01l2.32 2.32c.28-.72.44-1.51.44-2.33 0-.82-.16-1.59-.43-2.31l-2.33 2.32zm5.29-5.3l-1.26 1.26c.63 1.21.98 2.57.98 4.02s-.36 2.82-.98 4.02l1.2 1.2a9.936 9.936 0 0 0 1.54-5.31c-.01-1.89-.55-3.67-1.48-5.19zm-3.82 1L10 2H9v7.59L4.41 5 3 6.41 8.59 12 3 17.59 4.41 19 9 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM11 5.83l1.88 1.88L11 9.59V5.83zm1.88 10.46L11 18.17v-3.76l1.88 1.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_confirmation_number_24px"><path d="M22 10V6a2 2 0 0 0-2-2H4c-1.1 0-1.99.89-1.99 2v4c1.1 0 1.99.9 1.99 2s-.89 2-2 2v4c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-4c-1.1 0-2-.9-2-2s.9-2 2-2zm-9 7.5h-2v-2h2v2zm0-4.5h-2v-2h2v2zm0-4.5h-2v-2h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_disc_full_24px"><path d="M20 16h2v-2h-2v2zm0-9v5h2V7h-2zM10 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 10c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_do_not_disturb_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31A7.902 7.902 0 0 1 12 20zm6.31-3.1L7.1 5.69A7.902 7.902 0 0 1 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_do_not_disturb_alt_24px"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zM4 12c0-4.4 3.6-8 8-8 1.8 0 3.5.6 4.9 1.7L5.7 16.9A7.88 7.88 0 0 1 4 12zm8 8c-1.8 0-3.5-.6-4.9-1.7L18.3 7.1C19.4 8.5 20 10.2 20 12c0 4.4-3.6 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_do_not_disturb_off_24px"><path d="M17 11v2h-1.46l4.68 4.68A9.92 9.92 0 0 0 22 12c0-5.52-4.48-10-10-10-2.11 0-4.07.66-5.68 1.78L13.54 11H17zM2.27 2.27L1 3.54l2.78 2.78A9.92 9.92 0 0 0 2 12c0 5.52 4.48 10 10 10 2.11 0 4.07-.66 5.68-1.78L20.46 23l1.27-1.27L11 11 2.27 2.27zM7 13v-2h1.46l2 2H7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_do_not_disturb_on_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_drive_eta_24px"><path d="M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01L3 11v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.5-4.5h11L19 10H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_enhanced_encryption_24px"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM16 16h-3v3h-2v-3H8v-2h3v-3h2v3h3v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_event_available_24px"><path d="M16.53 11.06L15.47 10l-4.88 4.88-2.12-2.12-1.06 1.06L10.59 17l5.94-5.94zM19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_event_busy_24px"><path d="M9.31 17l2.44-2.44L14.19 17l1.06-1.06-2.44-2.44 2.44-2.44L14.19 10l-2.44 2.44L9.31 10l-1.06 1.06 2.44 2.44-2.44 2.44L9.31 17zM19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z"/></symbol><symbol viewBox="0 0 24 24" id="ic_event_note_24px"><path d="M17 10H7v2h10v-2zm2-7h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zm-5-5H7v2h7v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_folder_special_24px"><path d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-2.06 11L15 15.28 12.06 17l.78-3.33-2.59-2.24 3.41-.29L15 8l1.34 3.14 3.41.29-2.59 2.24.78 3.33z"/></symbol><symbol viewBox="0 0 24 24" id="ic_live_tv_24px"><path d="M21 6h-7.59l3.29-3.29L16 2l-4 4-4-4-.71.71L10.59 6H3a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8a2 2 0 0 0-2-2zm0 14H3V8h18v12zM9 10v8l7-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mms_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM5 14l3.5-4.5 2.5 3.01L14.5 8l4.5 6H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_more_24px"><path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.97.89 1.66.89H22c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 13.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm5 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm5 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_network_check_24px"><path d="M15.9 5c-.17 0-.32.09-.41.23l-.07.15-5.18 11.65c-.16.29-.26.61-.26.96 0 1.11.9 2.01 2.01 2.01.96 0 1.77-.68 1.96-1.59l.01-.03L16.4 5.5c0-.28-.22-.5-.5-.5zM1 9l2 2c2.88-2.88 6.79-4.08 10.53-3.62l1.19-2.68C9.89 3.84 4.74 5.27 1 9zm20 2l2-2a15.367 15.367 0 0 0-5.59-3.57l-.53 2.82c1.5.62 2.9 1.53 4.12 2.75zm-4 4l2-2c-.8-.8-1.7-1.42-2.66-1.89l-.55 2.92c.42.27.83.59 1.21.97zM5 13l2 2a7.1 7.1 0 0 1 4.03-2l1.28-2.88c-2.63-.08-5.3.87-7.31 2.88z"/></symbol><symbol viewBox="0 0 24 24" id="ic_network_locked_24px"><path d="M19.5 10c.17 0 .33.03.5.05V1L1 20h13v-3c0-.89.39-1.68 1-2.23v-.27c0-2.48 2.02-4.5 4.5-4.5zm2.5 6v-1.5a2.5 2.5 0 0 0-5 0V16c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1zm-1 0h-3v-1.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_no_encryption_24px"><path d="M21 21.78L4.22 5 3 6.22l2.04 2.04C4.42 8.6 4 9.25 4 10v10c0 1.1.9 2 2 2h12c.23 0 .45-.05.66-.12L19.78 23 21 21.78zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H9.66L20 18.34V10c0-1.1-.9-2-2-2h-1V6c0-2.76-2.24-5-5-5-2.56 0-4.64 1.93-4.94 4.4L8.9 7.24V6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_ondemand_video_24px"><path d="M21 3H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5a2 2 0 0 0-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_personal_video_24px"><path d="M21 3H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5a2 2 0 0 0-2-2zm0 14H3V5h18v12z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_bluetooth_speaker_24px"><path d="M14.71 9.5L17 7.21V11h.5l2.85-2.85L18.21 6l2.15-2.15L17.5 1H17v3.79L14.71 2.5l-.71.71L16.79 6 14 8.79l.71.71zM18 2.91l.94.94-.94.94V2.91zm0 4.3l.94.94-.94.94V7.21zm2 8.29c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.045 15.045 0 0 1-6.59-6.59l2.2-2.21a.96.96 0 0 0 .25-1A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_forwarded_24px"><path d="M18 11l5-5-5-5v3h-4v4h4v3zm2 4.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.045 15.045 0 0 1-6.59-6.59l2.2-2.21a.96.96 0 0 0 .25-1A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_in_talk_24px"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.045 15.045 0 0 1-6.59-6.59l2.2-2.21a.96.96 0 0 0 .25-1A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 12h2a9 9 0 0 0-9-9v2c3.87 0 7 3.13 7 7zm-4 0h2c0-2.76-2.24-5-5-5v2c1.66 0 3 1.34 3 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_locked_24px"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.045 15.045 0 0 1-6.59-6.59l2.2-2.21a.96.96 0 0 0 .25-1A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM20 4v-.5a2.5 2.5 0 0 0-5 0V4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_missed_24px"><path d="M6.5 5.5L12 11l7-7-1-1-6 6-4.5-4.5H11V3H5v6h1.5V5.5zm17.21 11.17A16.97 16.97 0 0 0 12 12C7.46 12 3.34 13.78.29 16.67c-.18.18-.29.43-.29.71s.11.53.29.71l2.48 2.48c.18.18.43.29.71.29.27 0 .52-.11.7-.28.79-.74 1.69-1.36 2.66-1.85.33-.16.56-.5.56-.9v-3.1c1.45-.48 3-.73 4.6-.73 1.6 0 3.15.25 4.6.72v3.1c0 .39.23.74.56.9.98.49 1.87 1.12 2.67 1.85.18.18.43.28.7.28.28 0 .53-.11.71-.29l2.48-2.48c.18-.18.29-.43.29-.71s-.12-.52-.3-.7z"/></symbol><symbol viewBox="0 0 24 24" id="ic_phone_paused_24px"><path d="M17 3h-2v7h2V3zm3 12.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.045 15.045 0 0 1-6.59-6.59l2.2-2.21a.96.96 0 0 0 .25-1A11.36 11.36 0 0 1 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 3v7h2V3h-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_power_24px"><path d="M16.01 7L16 3h-2v4h-4V3H8v4h-.01C7 6.99 6 7.99 6 8.99v5.49L9.5 18v3h5v-3l3.5-3.51v-5.5c0-1-1-2-1.99-1.99z"/></symbol><symbol viewBox="0 0 24 24" id="ic_priority_high_24px"><circle cx="12" cy="19" r="2"/><path d="M10 3h4v12h-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rv_hookup_24px"><path d="M20 17v-6c0-1.1-.9-2-2-2H7V7l-3 3 3 3v-2h4v3H4v3c0 1.1.9 2 2 2h2c0 1.66 1.34 3 3 3s3-1.34 3-3h8v-2h-2zm-9 3c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm7-6h-4v-3h4v3zM17 2v2H9v2h8v2l3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sd_card_24px"><path d="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 6h-2V4h2v4zm3 0h-2V4h2v4zm3 0h-2V4h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sim_card_alert_24px"><path d="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 15h-2v-2h2v2zm0-4h-2V8h2v5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sms_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sms_failed_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sync_24px"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0 0 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 0 0 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sync_disabled_24px"><path d="M10 6.35V4.26c-.8.21-1.55.54-2.23.96l1.46 1.46c.25-.12.5-.24.77-.33zm-7.14-.94l2.36 2.36a7.925 7.925 0 0 0 1.14 9.87L4 20h6v-6l-2.24 2.24A6.003 6.003 0 0 1 6 12c0-1 .25-1.94.68-2.77l8.08 8.08c-.25.13-.5.25-.77.34v2.09c.8-.21 1.55-.54 2.23-.96l2.36 2.36 1.27-1.27L4.14 4.14 2.86 5.41zM20 4h-6v6l2.24-2.24A6.003 6.003 0 0 1 18 12c0 1-.25 1.94-.68 2.77l1.46 1.46a7.925 7.925 0 0 0-1.14-9.87L20 4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sync_problem_24px"><path d="M3 12c0 2.21.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24A6.003 6.003 0 0 1 5 12a5.99 5.99 0 0 1 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24A6.003 6.003 0 0 1 19 12a5.99 5.99 0 0 1-4 5.65v2.09c3.45-.89 6-4.01 6-7.74 0-2.21-.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_system_update_24px"><path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14zm-1-6h-3V8h-2v5H8l4 4 4-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_tap_and_play_24px"><path d="M2 16v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0 4v3h3c0-1.66-1.34-3-3-3zm0-8v2a9 9 0 0 1 9 9h2c0-6.08-4.92-11-11-11zM17 1.01L7 1c-1.1 0-2 .9-2 2v7.37c.69.16 1.36.37 2 .64V5h10v13h-3.03c.52 1.25.84 2.59.95 4H17c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99z"/></symbol><symbol viewBox="0 0 24 24" id="ic_time_to_leave_24px"><path d="M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01L3 11v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.5-4.5h11L19 10H5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vibration_24px"><path d="M0 15h2V9H0v6zm3 2h2V7H3v10zm19-8v6h2V9h-2zm-3 8h2V7h-2v10zM16.5 3h-9C6.67 3 6 3.67 6 4.5v15c0 .83.67 1.5 1.5 1.5h9c.83 0 1.5-.67 1.5-1.5v-15c0-.83-.67-1.5-1.5-1.5zM16 19H8V5h8v14z"/></symbol><symbol viewBox="0 0 24 24" id="ic_voice_chat_24px"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12l-4-3.2V14H6V6h8v3.2L18 6v8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_vpn_lock_24px"><path d="M22 4v-.5a2.5 2.5 0 0 0-5 0V4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V4zm-2.28 8c.04.33.08.66.08 1 0 2.08-.8 3.97-2.1 5.39-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H7v-2h2c.55 0 1-.45 1-1V8h2c1.1 0 2-.9 2-2V3.46c-.95-.3-1.95-.46-3-.46C5.48 3 1 7.48 1 13s4.48 10 10 10 10-4.48 10-10c0-.34-.02-.67-.05-1h-2.03zM10 20.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L8 16v1c0 1.1.9 2 2 2v1.93z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wc_24px"><path d="M5.5 22v-7.5H4V9c0-1.1.9-2 2-2h3c1.1 0 2 .9 2 2v5.5H9.5V22h-4zM18 22v-6h3l-2.54-7.63A2.01 2.01 0 0 0 16.56 7h-.12a2 2 0 0 0-1.9 1.37L12 16h3v6h3zM7.5 6c1.11 0 2-.89 2-2s-.89-2-2-2-2 .89-2 2 .89 2 2 2zm9 0c1.11 0 2-.89 2-2s-.89-2-2-2-2 .89-2 2 .89 2 2 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_wifi_24px"><path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3a4.237 4.237 0 0 0-6 0zm-4-4l2 2a7.074 7.074 0 0 1 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-places-symbol.svg b/skyquake/framework/style/icons/svg-sprite-places-symbol.svg
new file mode 100755 (executable)
index 0000000..8a242c0
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_ac_unit_24px"><path d="M22 11h-4.17l3.24-3.24-1.41-1.42L15 11h-2V9l4.66-4.66-1.42-1.41L13 6.17V2h-2v4.17L7.76 2.93 6.34 4.34 11 9v2H9L4.34 6.34 2.93 7.76 6.17 11H2v2h4.17l-3.24 3.24 1.41 1.42L9 13h2v2l-4.66 4.66 1.42 1.41L11 17.83V22h2v-4.17l3.24 3.24 1.42-1.41L13 15v-2h2l4.66 4.66 1.41-1.42L17.83 13H22z"/></symbol><symbol viewBox="0 0 24 24" id="ic_airport_shuttle_24px"><path d="M17 5H3a2 2 0 0 0-2 2v9h2c0 1.65 1.34 3 3 3s3-1.35 3-3h5.5c0 1.65 1.34 3 3 3s3-1.35 3-3H23v-5l-6-6zM3 11V7h4v4H3zm3 6.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm7-6.5H9V7h4v4zm4.5 6.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM15 11V7h1l4 4h-5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_all_inclusive_24px"><path d="M18.6 6.62c-1.44 0-2.8.56-3.77 1.53L12 10.66 10.48 12h.01L7.8 14.39c-.64.64-1.49.99-2.4.99-1.87 0-3.39-1.51-3.39-3.38S3.53 8.62 5.4 8.62c.91 0 1.76.35 2.44 1.03l1.13 1 1.51-1.34L9.22 8.2A5.37 5.37 0 0 0 5.4 6.62C2.42 6.62 0 9.04 0 12s2.42 5.38 5.4 5.38c1.44 0 2.8-.56 3.77-1.53l2.83-2.5.01.01L13.52 12h-.01l2.69-2.39c.64-.64 1.49-.99 2.4-.99 1.87 0 3.39 1.51 3.39 3.38s-1.52 3.38-3.39 3.38c-.9 0-1.76-.35-2.44-1.03l-1.14-1.01-1.51 1.34 1.27 1.12a5.386 5.386 0 0 0 3.82 1.57c2.98 0 5.4-2.41 5.4-5.38s-2.42-5.37-5.4-5.37z"/></symbol><symbol viewBox="0 0 24 24" id="ic_beach_access_24px"><path d="M13.127 14.56l1.43-1.43 6.44 6.443L19.57 21zm4.293-5.73l2.86-2.86c-3.95-3.95-10.35-3.96-14.3-.02 3.93-1.3 8.31-.25 11.44 2.88zM5.95 5.98c-3.94 3.95-3.93 10.35.02 14.3l2.86-2.86C5.7 14.29 4.65 9.91 5.95 5.98zm.02-.02l-.01.01c-.38 3.01 1.17 6.88 4.3 10.02l5.73-5.73c-3.13-3.13-7.01-4.68-10.02-4.3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_business_center_24px"><path d="M10 16v-1H3.01L3 19c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2v-4h-7v1h-4zm10-9h-4.01V5l-2-2h-4l-2 2v2H4c-1.1 0-2 .9-2 2v3c0 1.11.89 2 2 2h6v-2h4v2h6c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm-6 0h-4V5h4v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_casino_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM7.5 18c-.83 0-1.5-.67-1.5-1.5S6.67 15 7.5 15s1.5.67 1.5 1.5S8.33 18 7.5 18zm0-9C6.67 9 6 8.33 6 7.5S6.67 6 7.5 6 9 6.67 9 7.5 8.33 9 7.5 9zm4.5 4.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4.5 4.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm0-9c-.83 0-1.5-.67-1.5-1.5S15.67 6 16.5 6s1.5.67 1.5 1.5S17.33 9 16.5 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_child_care_24px"><circle cx="14.5" cy="10.5" r="1.25"/><circle cx="9.5" cy="10.5" r="1.25"/><path d="M22.94 12.66c.04-.21.06-.43.06-.66s-.02-.45-.06-.66a4.008 4.008 0 0 0-2.81-3.17 9.114 9.114 0 0 0-2.19-2.91C16.36 3.85 14.28 3 12 3s-4.36.85-5.94 2.26c-.92.81-1.67 1.8-2.19 2.91a3.994 3.994 0 0 0-2.81 3.17c-.04.21-.06.43-.06.66s.02.45.06.66a4.008 4.008 0 0 0 2.81 3.17 8.977 8.977 0 0 0 2.17 2.89C7.62 20.14 9.71 21 12 21s4.38-.86 5.97-2.28c.9-.8 1.65-1.79 2.17-2.89a3.998 3.998 0 0 0 2.8-3.17zM19 14c-.1 0-.19-.02-.29-.03-.2.67-.49 1.29-.86 1.86C16.6 17.74 14.45 19 12 19s-4.6-1.26-5.85-3.17c-.37-.57-.66-1.19-.86-1.86-.1.01-.19.03-.29.03-1.1 0-2-.9-2-2s.9-2 2-2c.1 0 .19.02.29.03.2-.67.49-1.29.86-1.86C7.4 6.26 9.55 5 12 5s4.6 1.26 5.85 3.17c.37.57.66 1.19.86 1.86.1-.01.19-.03.29-.03 1.1 0 2 .9 2 2s-.9 2-2 2zM7.5 14c.76 1.77 2.49 3 4.5 3s3.74-1.23 4.5-3h-9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_child_friendly_24px"><path d="M13 2v8h8c0-4.42-3.58-8-8-8zm6.32 13.89A7.948 7.948 0 0 0 21 11H6.44l-.95-2H2v2h2.22s1.89 4.07 2.12 4.42A3.49 3.49 0 0 0 4.5 18.5C4.5 20.43 6.07 22 8 22c1.76 0 3.22-1.3 3.46-3h2.08c.24 1.7 1.7 3 3.46 3 1.93 0 3.5-1.57 3.5-3.5 0-1.04-.46-1.97-1.18-2.61zM8 20c-.83 0-1.5-.67-1.5-1.5S7.17 17 8 17s1.5.67 1.5 1.5S8.83 20 8 20zm9 0c-.83 0-1.5-.67-1.5-1.5S16.17 17 17 17s1.5.67 1.5 1.5S17.83 20 17 20z"/></symbol><symbol viewBox="0 0 24 24" id="ic_fitness_center_24px"><path d="M20.57 14.86L22 13.43 20.57 12 17 15.57 8.43 7 12 3.43 10.57 2 9.14 3.43 7.71 2 5.57 4.14 4.14 2.71 2.71 4.14l1.43 1.43L2 7.71l1.43 1.43L2 10.57 3.43 12 7 8.43 15.57 17 12 20.57 13.43 22l1.43-1.43L16.29 22l2.14-2.14 1.43 1.43 1.43-1.43-1.43-1.43L22 16.29z"/></symbol><symbol viewBox="0 0 24 24" id="ic_free_breakfast_24px"><path d="M20 3H4v10a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4v-3h2a2 2 0 0 0 2-2V5c0-1.11-.89-2-2-2zm0 5h-2V5h2v3zM4 19h16v2H4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_golf_course_24px"><circle cx="19.5" cy="19.5" r="1.5"/><path d="M17 5.92L9 2v18H7v-1.73c-1.79.35-3 .99-3 1.73 0 1.1 2.69 2 6 2s6-.9 6-2c0-.99-2.16-1.81-5-1.97V8.98l6-3.06z"/></symbol><symbol viewBox="0 0 24 24" id="ic_hot_tub_24px"><circle cx="7" cy="6" r="2"/><path d="M11.15 12c-.31-.22-.59-.46-.82-.72l-1.4-1.55c-.19-.21-.43-.38-.69-.5-.29-.14-.62-.23-.96-.23h-.03C6.01 9 5 10.01 5 11.25V12H2v8c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-8H11.15zM7 20H5v-6h2v6zm4 0H9v-6h2v6zm4 0h-2v-6h2v6zm4 0h-2v-6h2v6zm-.35-14.14l-.07-.07c-.57-.62-.82-1.41-.67-2.2L18 3h-1.89l-.06.43c-.2 1.36.27 2.71 1.3 3.72l.07.06c.57.62.82 1.41.67 2.2l-.11.59h1.91l.06-.43c.21-1.36-.27-2.71-1.3-3.71zm-4 0l-.07-.07c-.57-.62-.82-1.41-.67-2.2L14 3h-1.89l-.06.43c-.2 1.36.27 2.71 1.3 3.72l.07.06c.57.62.82 1.41.67 2.2l-.11.59h1.91l.06-.43c.21-1.36-.27-2.71-1.3-3.71z"/></symbol><symbol viewBox="0 0 24 24" id="ic_kitchen_24px"><path d="M18 2.01L6 2a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.11-.9-1.99-2-1.99zM18 20H6v-9.02h12V20zm0-11H6V4h12v5zM8 5h2v3H8zm0 7h2v5H8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pool_24px"><path d="M22 21c-1.11 0-1.73-.37-2.18-.64-.37-.22-.6-.36-1.15-.36-.56 0-.78.13-1.15.36-.46.27-1.07.64-2.18.64s-1.73-.37-2.18-.64c-.37-.22-.6-.36-1.15-.36-.56 0-.78.13-1.15.36-.46.27-1.08.64-2.19.64-1.11 0-1.73-.37-2.18-.64-.37-.23-.6-.36-1.15-.36s-.78.13-1.15.36c-.46.27-1.08.64-2.19.64v-2c.56 0 .78-.13 1.15-.36.46-.27 1.08-.64 2.19-.64s1.73.37 2.18.64c.37.23.59.36 1.15.36.56 0 .78-.13 1.15-.36.46-.27 1.08-.64 2.19-.64 1.11 0 1.73.37 2.18.64.37.22.6.36 1.15.36s.78-.13 1.15-.36c.45-.27 1.07-.64 2.18-.64s1.73.37 2.18.64c.37.23.59.36 1.15.36v2zm0-4.5c-1.11 0-1.73-.37-2.18-.64-.37-.22-.6-.36-1.15-.36-.56 0-.78.13-1.15.36-.45.27-1.07.64-2.18.64s-1.73-.37-2.18-.64c-.37-.22-.6-.36-1.15-.36-.56 0-.78.13-1.15.36-.45.27-1.07.64-2.18.64s-1.73-.37-2.18-.64c-.37-.22-.6-.36-1.15-.36s-.78.13-1.15.36c-.47.27-1.09.64-2.2.64v-2c.56 0 .78-.13 1.15-.36.45-.27 1.07-.64 2.18-.64s1.73.37 2.18.64c.37.22.6.36 1.15.36.56 0 .78-.13 1.15-.36.45-.27 1.07-.64 2.18-.64s1.73.37 2.18.64c.37.22.6.36 1.15.36s.78-.13 1.15-.36c.45-.27 1.07-.64 2.18-.64s1.73.37 2.18.64c.37.22.6.36 1.15.36v2zM8.67 12c.56 0 .78-.13 1.15-.36.46-.27 1.08-.64 2.19-.64 1.11 0 1.73.37 2.18.64.37.22.6.36 1.15.36s.78-.13 1.15-.36c.12-.07.26-.15.41-.23L10.48 5C8.93 3.45 7.5 2.99 5 3v2.5c1.82-.01 2.89.39 4 1.5l1 1-3.25 3.25c.31.12.56.27.77.39.37.23.59.36 1.15.36z"/><circle cx="16.5" cy="5.5" r="2.5"/></symbol><symbol viewBox="0 0 24 24" id="ic_room_service_24px"><path d="M2 17h20v2H2zm11.84-9.21A2.006 2.006 0 0 0 12 5a2.006 2.006 0 0 0-1.84 2.79C6.25 8.6 3.27 11.93 3 16h18c-.27-4.07-3.25-7.4-7.16-8.21z"/></symbol><symbol viewBox="0 0 24 24" id="ic_rv_hookup_24px"><path d="M20 17v-6c0-1.1-.9-2-2-2H7V7l-3 3 3 3v-2h4v3H4v3c0 1.1.9 2 2 2h2c0 1.66 1.34 3 3 3s3-1.34 3-3h8v-2h-2zm-9 3c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm7-6h-4v-3h4v3zM17 2v2H9v2h8v2l3-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_smoke_free_24px"><path d="M2 6l6.99 7H2v3h9.99l7 7 1.26-1.25-17-17zm18.5 7H22v3h-1.5zM18 13h1.5v3H18zm.85-8.12c.62-.61 1-1.45 1-2.38h-1.5c0 1.02-.83 1.85-1.85 1.85v1.5c2.24 0 4 1.83 4 4.07V12H22V9.92c0-2.23-1.28-4.15-3.15-5.04zM14.5 8.7h1.53c1.05 0 1.97.74 1.97 2.05V12h1.5v-1.59c0-1.8-1.6-3.16-3.47-3.16H14.5c-1.02 0-1.85-.98-1.85-2s.83-1.75 1.85-1.75V2a3.35 3.35 0 0 0 0 6.7zm2.5 7.23V13h-2.93z"/></symbol><symbol viewBox="0 0 24 24" id="ic_smoking_rooms_24px"><path d="M2 16h15v3H2zm18.5 0H22v3h-1.5zM18 16h1.5v3H18zm.85-8.27c.62-.61 1-1.45 1-2.38C19.85 3.5 18.35 2 16.5 2v1.5c1.02 0 1.85.83 1.85 1.85S17.52 7.2 16.5 7.2v1.5c2.24 0 4 1.83 4 4.07V15H22v-2.24c0-2.22-1.28-4.14-3.15-5.03zm-2.82 2.47H14.5c-1.02 0-1.85-.98-1.85-2s.83-1.75 1.85-1.75v-1.5a3.35 3.35 0 0 0 0 6.7h1.53c1.05 0 1.97.74 1.97 2.05V15h1.5v-1.64c0-1.81-1.6-3.16-3.47-3.16z"/></symbol><symbol viewBox="0 0 24 24" id="ic_spa_24px"><path fill="#607D8B" d="M8.55 12zm10.43-1.61z"/><path d="M15.49 9.63c-.18-2.79-1.31-5.51-3.43-7.63a12.188 12.188 0 0 0-3.55 7.63c1.28.68 2.46 1.56 3.49 2.63 1.03-1.06 2.21-1.94 3.49-2.63zm-6.5 2.65c-.14-.1-.3-.19-.45-.29.15.11.31.19.45.29zm6.42-.25c-.13.09-.27.16-.4.26.13-.1.27-.17.4-.26zM12 15.45C9.85 12.17 6.18 10 2 10c0 5.32 3.36 9.82 8.03 11.49.63.23 1.29.4 1.97.51.68-.12 1.33-.29 1.97-.51C18.64 19.82 22 15.32 22 10c-4.18 0-7.85 2.17-10 5.45z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-social-symbol.svg b/skyquake/framework/style/icons/svg-sprite-social-symbol.svg
new file mode 100755 (executable)
index 0000000..d9f371d
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_cake_24px"><path d="M12 6a2 2 0 0 0 2-2c0-.38-.1-.73-.29-1.03L12 0l-1.71 2.97c-.19.3-.29.65-.29 1.03 0 1.1.9 2 2 2zm4.6 9.99l-1.07-1.07-1.08 1.07c-1.3 1.3-3.58 1.31-4.89 0l-1.07-1.07-1.09 1.07C6.75 16.64 5.88 17 4.96 17c-.73 0-1.4-.23-1.96-.61V21c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-4.61c-.56.38-1.23.61-1.96.61-.92 0-1.79-.36-2.44-1.01zM18 9h-5V7h-2v2H6c-1.66 0-3 1.34-3 3v1.54c0 1.08.88 1.96 1.96 1.96.52 0 1.02-.2 1.38-.57l2.14-2.13 2.13 2.13c.74.74 2.03.74 2.77 0l2.14-2.13 2.13 2.13c.37.37.86.57 1.38.57 1.08 0 1.96-.88 1.96-1.96V12C21 10.34 19.66 9 18 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_domain_24px"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_group_24px"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_group_add_24px"><path d="M8 10H5V7H3v3H0v2h3v3h2v-3h3v-2zm10 1c1.66 0 2.99-1.34 2.99-3S19.66 5 18 5c-.32 0-.63.05-.91.14.57.81.9 1.79.9 2.86s-.34 2.04-.9 2.86c.28.09.59.14.91.14zm-5 0c1.66 0 2.99-1.34 2.99-3S14.66 5 13 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm6.62 2.16c.83.73 1.38 1.66 1.38 2.84v2h3v-2c0-1.54-2.37-2.49-4.38-2.84zM13 13c-2 0-6 1-6 3v2h12v-2c0-2-4-3-6-3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_location_city_24px"><path d="M15 11V5l-3-3-3 3v2H3v14h18V11h-6zm-8 8H5v-2h2v2zm0-4H5v-2h2v2zm0-4H5V9h2v2zm6 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V9h2v2zm0-4h-2V5h2v2zm6 12h-2v-2h2v2zm0-4h-2v-2h2v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mood_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_mood_bad_24px"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 3c-2.33 0-4.31 1.46-5.11 3.5h10.22c-.8-2.04-2.78-3.5-5.11-3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_notifications_24px"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 0 0 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_notifications_active_24px"><path d="M7.58 4.08L6.15 2.65C3.75 4.48 2.17 7.3 2.03 10.5h2a8.445 8.445 0 0 1 3.55-6.42zm12.39 6.42h2a10.49 10.49 0 0 0-4.12-7.85l-1.42 1.43a8.495 8.495 0 0 1 3.54 6.42zM18 11c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2v-5zm-6 11c.14 0 .27-.01.4-.04a2.03 2.03 0 0 0 1.44-1.18c.1-.24.15-.5.15-.78h-4c.01 1.1.9 2 2.01 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_notifications_none_24px"><path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6-6v-5c0-3.07-1.63-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.64 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2zm-2 1H8v-6c0-2.48 1.51-4.5 4-4.5s4 2.02 4 4.5v6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_notifications_off_24px"><path d="M20 18.69L7.84 6.14 5.27 3.49 4 4.76l2.8 2.8v.01c-.52.99-.8 2.16-.8 3.42v5l-2 2v1h13.73l2 2L21 19.72l-1-1.03zM12 22c1.11 0 2-.89 2-2h-4c0 1.11.89 2 2 2zm6-7.32V11c0-3.08-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68c-.15.03-.29.08-.42.12-.1.03-.2.07-.3.11h-.01c-.01 0-.01 0-.02.01-.23.09-.46.2-.68.31 0 0-.01 0-.01.01L18 14.68z"/></symbol><symbol viewBox="0 0 24 24" id="ic_notifications_paused_24px"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 0 0 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.93 6 11v5l-2 2v1h16v-1l-2-2zm-3.5-6.2l-2.8 3.4h2.8V15h-5v-1.8l2.8-3.4H9.5V8h5v1.8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_pages_24px"><path d="M3 5v6h5L7 7l4 1V3H5c-1.1 0-2 .9-2 2zm5 8H3v6c0 1.1.9 2 2 2h6v-5l-4 1 1-4zm9 4l-4-1v5h6c1.1 0 2-.9 2-2v-6h-5l1 4zm2-14h-6v5l4-1-1 4h5V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_party_mode_24px"><path d="M20 4h-3.17L15 2H9L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 3c1.63 0 3.06.79 3.98 2H12c-1.66 0-3 1.34-3 3 0 .35.07.69.18 1H7.1A5.002 5.002 0 0 1 12 7zm0 10c-1.63 0-3.06-.79-3.98-2H12c1.66 0 3-1.34 3-3 0-.35-.07-.69-.18-1h2.08a5.002 5.002 0 0 1-4.9 6z"/></symbol><symbol viewBox="0 0 24 24" id="ic_people_24px"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_people_outline_24px"><path d="M16.5 13c-1.2 0-3.07.34-4.5 1-1.43-.67-3.3-1-4.5-1C5.33 13 1 14.08 1 16.25V19h22v-2.75c0-2.17-4.33-3.25-6.5-3.25zm-4 4.5h-10v-1.25c0-.54 2.56-1.75 5-1.75s5 1.21 5 1.75v1.25zm9 0H14v-1.25c0-.46-.2-.86-.52-1.22.88-.3 1.96-.53 3.02-.53 2.44 0 5 1.21 5 1.75v1.25zM7.5 12c1.93 0 3.5-1.57 3.5-3.5S9.43 5 7.5 5 4 6.57 4 8.5 5.57 12 7.5 12zm0-5.5c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 5.5c1.93 0 3.5-1.57 3.5-3.5S18.43 5 16.5 5 13 6.57 13 8.5s1.57 3.5 3.5 3.5zm0-5.5c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_person_24px"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_person_add_24px"><path d="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_person_outline_24px"><path d="M12 5.9a2.1 2.1 0 1 1 0 4.2 2.1 2.1 0 0 1 0-4.2m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_plus_one_24px"><path d="M10 8H8v4H4v2h4v4h2v-4h4v-2h-4zm4.5-1.92V7.9l2.5-.5V18h2V5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_poll_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_public_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></symbol><symbol viewBox="0 0 24 24" id="ic_school_24px"><path d="M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sentiment_dissatisfied_24px"><circle cx="15.5" cy="9.5" r="1.5"/><circle cx="8.5" cy="9.5" r="1.5"/><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-6c-2.33 0-4.32 1.45-5.12 3.5h1.67c.69-1.19 1.97-2 3.45-2s2.75.81 3.45 2h1.67c-.8-2.05-2.79-3.5-5.12-3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sentiment_neutral_24px"><path d="M9 14h6v1.5H9z"/><circle cx="15.5" cy="9.5" r="1.5"/><circle cx="8.5" cy="9.5" r="1.5"/><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sentiment_satisfied_24px"><circle cx="15.5" cy="9.5" r="1.5"/><circle cx="8.5" cy="9.5" r="1.5"/><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-4c-1.48 0-2.75-.81-3.45-2H6.88a5.495 5.495 0 0 0 10.24 0h-1.67c-.7 1.19-1.97 2-3.45 2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sentiment_very_dissatisfied_24px"><path d="M11.99 2C6.47 2 2 6.47 2 12s4.47 10 9.99 10S22 17.53 22 12 17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm4.18-12.24l-1.06 1.06-1.06-1.06L13 8.82l1.06 1.06L13 10.94 14.06 12l1.06-1.06L16.18 12l1.06-1.06-1.06-1.06 1.06-1.06zM7.82 12l1.06-1.06L9.94 12 11 10.94 9.94 9.88 11 8.82 9.94 7.76 8.88 8.82 7.82 7.76 6.76 8.82l1.06 1.06-1.06 1.06zM12 14c-2.33 0-4.31 1.46-5.11 3.5h10.22c-.8-2.04-2.78-3.5-5.11-3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_sentiment_very_satisfied_24px"><path d="M11.99 2C6.47 2 2 6.47 2 12s4.47 10 9.99 10S22 17.53 22 12 17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm1-10.06L14.06 11l1.06-1.06L16.18 11l1.06-1.06-2.12-2.12zm-4.12 0L9.94 11 11 9.94 8.88 7.82 6.76 9.94 7.82 11zM12 17.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></symbol><symbol viewBox="0 0 24 24" id="ic_share_24px"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></symbol><symbol viewBox="0 0 24 24" id="ic_whatshot_24px"><path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04a4.8 4.8 0 0 1-4.8 4.8z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/icons/svg-sprite-toggle-symbol.svg b/skyquake/framework/style/icons/svg-sprite-toggle-symbol.svg
new file mode 100755 (executable)
index 0000000..5d4705b
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="ic_check_box_24px"><path d="M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></symbol><symbol viewBox="0 0 24 24" id="ic_check_box_outline_blank_24px"><path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_indeterminate_check_box_24px"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z"/></symbol><symbol viewBox="0 0 24 24" id="ic_radio_button_checked_24px"><path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_radio_button_unchecked_24px"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="ic_star_24px"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></symbol><symbol viewBox="0 0 24 24" id="ic_star_border_24px"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></symbol><symbol viewBox="0 0 24 24" id="ic_star_half_24px"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4V6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></symbol></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/img/avatar.png b/skyquake/framework/style/img/avatar.png
new file mode 100644 (file)
index 0000000..c40cb8c
Binary files /dev/null and b/skyquake/framework/style/img/avatar.png differ
diff --git a/skyquake/framework/style/img/bargraph.png b/skyquake/framework/style/img/bargraph.png
new file mode 100644 (file)
index 0000000..2b25d7f
Binary files /dev/null and b/skyquake/framework/style/img/bargraph.png differ
diff --git a/skyquake/framework/style/img/bearer-plane-diagram.png b/skyquake/framework/style/img/bearer-plane-diagram.png
new file mode 100644 (file)
index 0000000..9eb06a4
Binary files /dev/null and b/skyquake/framework/style/img/bearer-plane-diagram.png differ
diff --git a/skyquake/framework/style/img/bg-tile-cross-small.png b/skyquake/framework/style/img/bg-tile-cross-small.png
new file mode 100644 (file)
index 0000000..0ab6c94
Binary files /dev/null and b/skyquake/framework/style/img/bg-tile-cross-small.png differ
diff --git a/skyquake/framework/style/img/catalog-default.svg b/skyquake/framework/style/img/catalog-default.svg
new file mode 100644 (file)
index 0000000..ef6efc7
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90.8 78.5"><path class="st0" d="M70.8 58.2c-0.7 0-1.4 0.1-2 0.3L51.5 42.7c0.7-1.1 1.2-2.4 1.2-3.8 0-1.4-0.4-2.7-1.2-3.8l15.1-13.9c1.1 0.9 2.6 1.5 4.2 1.5 3.7 0 6.7-3 6.7-6.6 0-3.7-3-6.6-6.7-6.6 -3.7 0-6.7 3-6.7 6.6 0 1.4 0.4 2.7 1.2 3.8L50.2 33.8c-1.1-0.9-2.6-1.5-4.2-1.5 -1.6 0-3.1 0.6-4.2 1.5L26.7 19.9c0.7-1.1 1.2-2.4 1.2-3.8 0-3.7-3-6.6-6.7-6.6 -3.7 0-6.7 3-6.7 6.6 0 3.3 2.5 6.1 5.7 6.6v35.6c-3.2 0.5-5.7 3.2-5.7 6.6 0 3.7 3 6.6 6.7 6.6 3.1 0 5.8-2.2 6.5-5.1h36.7c0.7 2.9 3.3 5.1 6.5 5.1 3.7 0 6.7-3 6.7-6.6C77.5 61.2 74.5 58.2 70.8 58.2zM64.2 64.5H27.8c-0.1-2.1-1.2-4-2.8-5.1l16.7-15.4c1.1 0.9 2.6 1.5 4.2 1.5 1.6 0 3.1-0.6 4.2-1.5L67 59.4C65.3 60.6 64.3 62.4 64.2 64.5zM25.4 21.3l15.1 13.9c-0.7 1.1-1.2 2.4-1.2 3.8 0 1.4 0.4 2.7 1.2 3.8L23.2 58.5c-0.3-0.1-0.7-0.2-1.1-0.2V22.7C23.4 22.5 24.5 22 25.4 21.3z"/></svg>
\ No newline at end of file
diff --git a/skyquake/framework/style/img/catalog-nsd-default.svg b/skyquake/framework/style/img/catalog-nsd-default.svg
new file mode 100644 (file)
index 0000000..e2a4a89
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90.8 78.5" preserveAspectRatio="none"><path class="st0" d="M325.55,87.34c0,34.54-27.71,62.55-61.89,62.55s-61.89-28-61.89-62.55S229.48,24.8,263.66,24.8,325.55,52.8,325.55,87.34Zm-220.1,96.09c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S139.63,183.43,105.45,183.43ZM259,235.18c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S293.23,235.18,259,235.18Zm153.6-51.74c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S446.83,183.43,412.64,183.43ZM213,127.14l-66,80.5m116.59-57.75v85.29m42.76-104.42,64,64.68" transform="scale(0.15, 0.15)"/></svg>
diff --git a/skyquake/framework/style/img/catalog-vnfd-default.svg b/skyquake/framework/style/img/catalog-vnfd-default.svg
new file mode 100644 (file)
index 0000000..4dafa78
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90.8 78.5" preserveAspectRatio="none"><path class="st0" d="M241.72,51.26c-92.14,0-166.83,75.48-166.83,168.59s74.69,168.59,166.83,168.59S408.55,313,408.55,219.85,333.86,51.26,241.72,51.26Z" transform="scale(0.15, 0.15)"/></svg>
diff --git a/skyquake/framework/style/img/create-account.png b/skyquake/framework/style/img/create-account.png
new file mode 100644 (file)
index 0000000..16aeeb4
Binary files /dev/null and b/skyquake/framework/style/img/create-account.png differ
diff --git a/skyquake/framework/style/img/create-fleet-params-temp.png b/skyquake/framework/style/img/create-fleet-params-temp.png
new file mode 100644 (file)
index 0000000..d5b7498
Binary files /dev/null and b/skyquake/framework/style/img/create-fleet-params-temp.png differ
diff --git a/skyquake/framework/style/img/create-fleet-pool-temp.png b/skyquake/framework/style/img/create-fleet-pool-temp.png
new file mode 100644 (file)
index 0000000..2a330ec
Binary files /dev/null and b/skyquake/framework/style/img/create-fleet-pool-temp.png differ
diff --git a/skyquake/framework/style/img/create-fleet-services-temp.png b/skyquake/framework/style/img/create-fleet-services-temp.png
new file mode 100644 (file)
index 0000000..2b4578b
Binary files /dev/null and b/skyquake/framework/style/img/create-fleet-services-temp.png differ
diff --git a/skyquake/framework/style/img/diameter-openflow-lte-icon.png b/skyquake/framework/style/img/diameter-openflow-lte-icon.png
new file mode 100644 (file)
index 0000000..39156d1
Binary files /dev/null and b/skyquake/framework/style/img/diameter-openflow-lte-icon.png differ
diff --git a/skyquake/framework/style/img/firewall-icon.png b/skyquake/framework/style/img/firewall-icon.png
new file mode 100644 (file)
index 0000000..c65caf4
Binary files /dev/null and b/skyquake/framework/style/img/firewall-icon.png differ
diff --git a/skyquake/framework/style/img/gbps-10.png b/skyquake/framework/style/img/gbps-10.png
new file mode 100644 (file)
index 0000000..1327ab9
Binary files /dev/null and b/skyquake/framework/style/img/gbps-10.png differ
diff --git a/skyquake/framework/style/img/gbps-50.png b/skyquake/framework/style/img/gbps-50.png
new file mode 100644 (file)
index 0000000..9cfb805
Binary files /dev/null and b/skyquake/framework/style/img/gbps-50.png differ
diff --git a/skyquake/framework/style/img/green-page-icon.png b/skyquake/framework/style/img/green-page-icon.png
new file mode 100644 (file)
index 0000000..87bc437
Binary files /dev/null and b/skyquake/framework/style/img/green-page-icon.png differ
diff --git a/skyquake/framework/style/img/header-logo.png b/skyquake/framework/style/img/header-logo.png
new file mode 100644 (file)
index 0000000..09b47c7
Binary files /dev/null and b/skyquake/framework/style/img/header-logo.png differ
diff --git a/skyquake/framework/style/img/host-icon.png b/skyquake/framework/style/img/host-icon.png
new file mode 100644 (file)
index 0000000..0c508a1
Binary files /dev/null and b/skyquake/framework/style/img/host-icon.png differ
diff --git a/skyquake/framework/style/img/icon-host-sm.png b/skyquake/framework/style/img/icon-host-sm.png
new file mode 100644 (file)
index 0000000..1254c22
Binary files /dev/null and b/skyquake/framework/style/img/icon-host-sm.png differ
diff --git a/skyquake/framework/style/img/icon-host.png b/skyquake/framework/style/img/icon-host.png
new file mode 100644 (file)
index 0000000..0c508a1
Binary files /dev/null and b/skyquake/framework/style/img/icon-host.png differ
diff --git a/skyquake/framework/style/img/icon-open-viewport.png b/skyquake/framework/style/img/icon-open-viewport.png
new file mode 100644 (file)
index 0000000..4ed206e
Binary files /dev/null and b/skyquake/framework/style/img/icon-open-viewport.png differ
diff --git a/skyquake/framework/style/img/icon-switch.png b/skyquake/framework/style/img/icon-switch.png
new file mode 100644 (file)
index 0000000..88a7715
Binary files /dev/null and b/skyquake/framework/style/img/icon-switch.png differ
diff --git a/skyquake/framework/style/img/iot-industry-icon.png b/skyquake/framework/style/img/iot-industry-icon.png
new file mode 100644 (file)
index 0000000..1e10ac0
Binary files /dev/null and b/skyquake/framework/style/img/iot-industry-icon.png differ
diff --git a/skyquake/framework/style/img/iot-medical-icon.png b/skyquake/framework/style/img/iot-medical-icon.png
new file mode 100644 (file)
index 0000000..352f787
Binary files /dev/null and b/skyquake/framework/style/img/iot-medical-icon.png differ
diff --git a/skyquake/framework/style/img/iot-transportation-icon-active.png b/skyquake/framework/style/img/iot-transportation-icon-active.png
new file mode 100644 (file)
index 0000000..6eb2c19
Binary files /dev/null and b/skyquake/framework/style/img/iot-transportation-icon-active.png differ
diff --git a/skyquake/framework/style/img/ip-lte-icon.png b/skyquake/framework/style/img/ip-lte-icon.png
new file mode 100644 (file)
index 0000000..b90ca15
Binary files /dev/null and b/skyquake/framework/style/img/ip-lte-icon.png differ
diff --git a/skyquake/framework/style/img/ip-softgre-icon.png b/skyquake/framework/style/img/ip-softgre-icon.png
new file mode 100644 (file)
index 0000000..0a7f5f9
Binary files /dev/null and b/skyquake/framework/style/img/ip-softgre-icon.png differ
diff --git a/skyquake/framework/style/img/latency.png b/skyquake/framework/style/img/latency.png
new file mode 100644 (file)
index 0000000..fd3371e
Binary files /dev/null and b/skyquake/framework/style/img/latency.png differ
diff --git a/skyquake/framework/style/img/latency_graph.png b/skyquake/framework/style/img/latency_graph.png
new file mode 100644 (file)
index 0000000..03e6de7
Binary files /dev/null and b/skyquake/framework/style/img/latency_graph.png differ
diff --git a/skyquake/framework/style/img/launchpad-add-fleet-icon.png b/skyquake/framework/style/img/launchpad-add-fleet-icon.png
new file mode 100644 (file)
index 0000000..ab89e52
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-add-fleet-icon.png differ
diff --git a/skyquake/framework/style/img/launchpad-graph-temp.png b/skyquake/framework/style/img/launchpad-graph-temp.png
new file mode 100644 (file)
index 0000000..04d91a3
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graph-temp.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/10.09.png b/skyquake/framework/style/img/launchpad-graphs-temp/10.09.png
new file mode 100644 (file)
index 0000000..6e7e370
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/10.09.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/17.23.png b/skyquake/framework/style/img/launchpad-graphs-temp/17.23.png
new file mode 100644 (file)
index 0000000..1bbe9fe
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/17.23.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/20.05.png b/skyquake/framework/style/img/launchpad-graphs-temp/20.05.png
new file mode 100644 (file)
index 0000000..2d78371
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/20.05.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/23.08.png b/skyquake/framework/style/img/launchpad-graphs-temp/23.08.png
new file mode 100644 (file)
index 0000000..ee05baf
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/23.08.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/25.03.png b/skyquake/framework/style/img/launchpad-graphs-temp/25.03.png
new file mode 100644 (file)
index 0000000..87931d8
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/25.03.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/30.56.png b/skyquake/framework/style/img/launchpad-graphs-temp/30.56.png
new file mode 100644 (file)
index 0000000..8c8be88
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/30.56.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/7.08.png b/skyquake/framework/style/img/launchpad-graphs-temp/7.08.png
new file mode 100644 (file)
index 0000000..8cc9c1a
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/7.08.png differ
diff --git a/skyquake/framework/style/img/launchpad-graphs-temp/9.24.png b/skyquake/framework/style/img/launchpad-graphs-temp/9.24.png
new file mode 100644 (file)
index 0000000..e724306
Binary files /dev/null and b/skyquake/framework/style/img/launchpad-graphs-temp/9.24.png differ
diff --git a/skyquake/framework/style/img/link.png b/skyquake/framework/style/img/link.png
new file mode 100644 (file)
index 0000000..33210cc
Binary files /dev/null and b/skyquake/framework/style/img/link.png differ
diff --git a/skyquake/framework/style/img/loadbalance-icon.png b/skyquake/framework/style/img/loadbalance-icon.png
new file mode 100644 (file)
index 0000000..4164786
Binary files /dev/null and b/skyquake/framework/style/img/loadbalance-icon.png differ
diff --git a/skyquake/framework/style/img/lte-mme-icon.png b/skyquake/framework/style/img/lte-mme-icon.png
new file mode 100644 (file)
index 0000000..6eb898b
Binary files /dev/null and b/skyquake/framework/style/img/lte-mme-icon.png differ
diff --git a/skyquake/framework/style/img/osm_header.png b/skyquake/framework/style/img/osm_header.png
new file mode 100644 (file)
index 0000000..c67dca3
Binary files /dev/null and b/skyquake/framework/style/img/osm_header.png differ
diff --git a/skyquake/framework/style/img/osm_header_253x50.png b/skyquake/framework/style/img/osm_header_253x50.png
new file mode 100644 (file)
index 0000000..3055122
Binary files /dev/null and b/skyquake/framework/style/img/osm_header_253x50.png differ
diff --git a/skyquake/framework/style/img/osm_header_506x100.png b/skyquake/framework/style/img/osm_header_506x100.png
new file mode 100644 (file)
index 0000000..4b7a344
Binary files /dev/null and b/skyquake/framework/style/img/osm_header_506x100.png differ
diff --git a/skyquake/framework/style/img/page_loader.gif b/skyquake/framework/style/img/page_loader.gif
new file mode 100644 (file)
index 0000000..07b9f3f
Binary files /dev/null and b/skyquake/framework/style/img/page_loader.gif differ
diff --git a/skyquake/framework/style/img/platform-nav-temp.png b/skyquake/framework/style/img/platform-nav-temp.png
new file mode 100644 (file)
index 0000000..06f3510
Binary files /dev/null and b/skyquake/framework/style/img/platform-nav-temp.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-resources.png b/skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-resources.png
new file mode 100644 (file)
index 0000000..f7f2866
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-resources.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-traffic.png b/skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-traffic.png
new file mode 100644 (file)
index 0000000..041325d
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/1a-fleet-platform-traffic.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-resources.png b/skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-resources.png
new file mode 100644 (file)
index 0000000..f7f2866
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-resources.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-traffic.png b/skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-traffic.png
new file mode 100644 (file)
index 0000000..041325d
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/1b-fleet-platform-traffic.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-resources.png b/skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-resources.png
new file mode 100644 (file)
index 0000000..f7f2866
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-resources.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-traffic.png b/skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-traffic.png
new file mode 100644 (file)
index 0000000..041325d
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/2a-fleet-platform-traffic.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-resources.png b/skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-resources.png
new file mode 100644 (file)
index 0000000..f7f2866
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-resources.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-traffic.png b/skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-traffic.png
new file mode 100644 (file)
index 0000000..041325d
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/2b-fleet-platform-traffic.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-resources.png b/skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-resources.png
new file mode 100644 (file)
index 0000000..f7f2866
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-resources.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-traffic.png b/skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-traffic.png
new file mode 100644 (file)
index 0000000..041325d
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/3a-fleet-platform-traffic.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-resources.png b/skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-resources.png
new file mode 100644 (file)
index 0000000..f7f2866
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-resources.png differ
diff --git a/skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-traffic.png b/skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-traffic.png
new file mode 100644 (file)
index 0000000..041325d
Binary files /dev/null and b/skyquake/framework/style/img/platform-pages-temp/3b-fleet-platform-traffic.png differ
diff --git a/skyquake/framework/style/img/router-icon.png b/skyquake/framework/style/img/router-icon.png
new file mode 100644 (file)
index 0000000..93282df
Binary files /dev/null and b/skyquake/framework/style/img/router-icon.png differ
diff --git a/skyquake/framework/style/img/so-pages-temp/ipTrafTemp.png b/skyquake/framework/style/img/so-pages-temp/ipTrafTemp.png
new file mode 100644 (file)
index 0000000..1a6566d
Binary files /dev/null and b/skyquake/framework/style/img/so-pages-temp/ipTrafTemp.png differ
diff --git a/skyquake/framework/style/img/so-pages-temp/securityTemp.png b/skyquake/framework/style/img/so-pages-temp/securityTemp.png
new file mode 100644 (file)
index 0000000..f22abf4
Binary files /dev/null and b/skyquake/framework/style/img/so-pages-temp/securityTemp.png differ
diff --git a/skyquake/framework/style/img/svg/launch-fleet-icn-close.svg b/skyquake/framework/style/img/svg/launch-fleet-icn-close.svg
new file mode 100644 (file)
index 0000000..d364ff8
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 51 51" enable-background="new 0 0 51 51" xml:space="preserve">\r
+<polygon id="XMLID_5_" fill-rule="evenodd" clip-rule="evenodd" fill="#333333" points="40.7,7.9 39.3,6.5 23,22.8 6.7,6.5 5.3,7.9 \r
+       21.6,24.2 5.3,40.4 6.7,41.8 23,25.6 39.3,41.8 40.7,40.4 24.4,24.2 "/>\r
+<polygon id="XMLID_4_" opacity="0.15" fill-rule="evenodd" clip-rule="evenodd" fill="#333333" points="45.1,41.7 28.8,25.4 \r
+       43.7,10.6 40.8,7.7 26,22.6 11.2,7.7 8.3,10.6 23.2,25.4 6.9,41.7 9.7,44.5 26,28.2 42.3,44.5 "/>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-icn-edit.svg b/skyquake/framework/style/img/svg/launch-fleet-icn-edit.svg
new file mode 100644 (file)
index 0000000..b62dc8a
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 28 35.3" enable-background="new 0 0 28 35.3" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_22_">\r
+               <path id="XMLID_23_" fill="none" stroke="#333333" stroke-linejoin="round" stroke-miterlimit="10" d="M22.9,8.9l-5-3.4\r
+                       C17.3,5,16.4,5.1,16,5.7l-1.2,1.7l7.3,5l1.2-1.7C23.7,10.1,23.5,9.3,22.9,8.9z M6.5,19.1c-0.3,2.2,5.1,6,7.3,5L21,13.9l-7.3-5\r
+                       L6.5,19.1z M5.3,20.8c-0.5,1.1-1,6.4-0.8,7.8c0,0.3,0.1,0.4,0.2,0.5c0.5,0.4,6.8-2.6,7.8-3.4C10.3,26.4,5.3,22.9,5.3,20.8z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-01-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-01-active.svg
new file mode 100755 (executable)
index 0000000..f3de69a
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_70_">\r
+               <path id="XMLID_71_" class="st0" d="M71.1,57.3V21.2c3.3-0.5,5.8-3.3,5.8-6.7c0-3.7-3-6.7-6.8-6.7c-3.4,0-6.2,2.5-6.7,5.8h-37\r
+                       c-0.5-3.3-3.3-5.8-6.7-5.8c-3.7,0-6.8,3-6.8,6.7c0,3.4,2.5,6.2,5.8,6.7v36.2c-3.3,0.5-5.8,3.3-5.8,6.7c0,3.7,3,6.7,6.8,6.7\r
+                       c3.2,0,5.9-2.2,6.6-5.1h37.3c0.7,3,3.4,5.1,6.6,5.1c3.7,0,6.8-3,6.8-6.7C76.9,60.6,74.4,57.8,71.1,57.3z M68,57.6L50.5,41.5\r
+                       c0.8-1.1,1.2-2.4,1.2-3.8c0-1.4-0.4-2.7-1.2-3.8l15.3-14.1c0.9,0.8,2.1,1.3,3.3,1.4v36.2C68.7,57.4,68.4,57.4,68,57.6z M64.5,18.3\r
+                       L49.2,32.4c-1.2-0.9-2.7-1.5-4.3-1.5s-3.1,0.6-4.3,1.5L25.3,18.3c0.6-0.8,1-1.8,1.1-2.9h37C63.5,16.5,63.9,17.5,64.5,18.3z\r
+                        M23.9,19.7l15.3,14.1c-0.8,1.1-1.2,2.4-1.2,3.8c0,1.4,0.4,2.7,1.2,3.8L21.7,57.6c-0.4-0.1-0.7-0.2-1.1-0.2V21.2\r
+                       C21.9,21,23,20.5,23.9,19.7z M23.6,58.5l17-15.6c1.2,0.9,2.7,1.5,4.3,1.5s3.1-0.6,4.3-1.5l17,15.6c-1.6,1.2-2.7,3-2.8,5.2H26.4\r
+                       C26.3,61.5,25.2,59.7,23.6,58.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-01-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-01-inactive.svg
new file mode 100755 (executable)
index 0000000..19700d2
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_44_">\r
+               <path id="XMLID_45_" class="st0" d="M71.1,57.3V21.2c3.3-0.5,5.8-3.3,5.8-6.7c0-3.7-3-6.7-6.8-6.7c-3.4,0-6.2,2.5-6.7,5.8h-37\r
+                       c-0.5-3.3-3.3-5.8-6.7-5.8c-3.7,0-6.8,3-6.8,6.7c0,3.4,2.5,6.2,5.8,6.7v36.2c-3.3,0.5-5.8,3.3-5.8,6.7c0,3.7,3,6.7,6.8,6.7\r
+                       c3.2,0,5.9-2.2,6.6-5.1h37.3c0.7,3,3.4,5.1,6.6,5.1c3.7,0,6.8-3,6.8-6.7C76.9,60.6,74.4,57.8,71.1,57.3z M68,57.6L50.5,41.5\r
+                       c0.8-1.1,1.2-2.4,1.2-3.8c0-1.4-0.4-2.7-1.2-3.8l15.3-14.1c0.9,0.8,2.1,1.3,3.3,1.4v36.2C68.7,57.4,68.4,57.4,68,57.6z M64.5,18.3\r
+                       L49.2,32.4c-1.2-0.9-2.7-1.5-4.3-1.5s-3.1,0.6-4.3,1.5L25.3,18.3c0.6-0.8,1-1.8,1.1-2.9h37C63.5,16.5,63.9,17.5,64.5,18.3z\r
+                        M23.9,19.7l15.3,14.1c-0.8,1.1-1.2,2.4-1.2,3.8c0,1.4,0.4,2.7,1.2,3.8L21.7,57.6c-0.4-0.1-0.7-0.2-1.1-0.2V21.2\r
+                       C21.9,21,23,20.5,23.9,19.7z M23.6,58.5l17-15.6c1.2,0.9,2.7,1.5,4.3,1.5s3.1-0.6,4.3-1.5l17,15.6c-1.6,1.2-2.7,3-2.8,5.2H26.4\r
+                       C26.3,61.5,25.2,59.7,23.6,58.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-02-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-02-active.svg
new file mode 100755 (executable)
index 0000000..c29934b
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_40_">\r
+               <path id="XMLID_41_" class="st0" d="M65.9,41.2c0.2,1.1,0.6,2.1,1.5,3c2.1,2.1,5.4,2.1,7.5,0c2.1-2.1,2.1-5.4,0-7.5\r
+                       c-2.1-2.1-5.4-2.1-7.5,0c-0.8,0.8-1.3,1.9-1.5,3l-15.2,0c-0.1-0.8-0.5-1.7-1-2.4L68,19c2.1,1.6,5,1.4,6.9-0.5\r
+                       c2.1-2.1,2.1-5.4,0-7.5c-2.1-2.1-5.4-2.1-7.5,0c-1.9,1.9-2,4.8-0.5,6.9L48.6,36.3c-0.7-0.5-1.5-0.9-2.3-1L46.2,20\r
+                       c1.1-0.2,2.1-0.6,3-1.5c2.1-2.1,2.1-5.4,0-7.5c-2.1-2.1-5.4-2.1-7.5,0c-2.1,2.1-2.1,5.4,0,7.5c0.8,0.8,1.9,1.3,3,1.5l0.1,15.3\r
+                       c-1,0.1-2,0.6-2.8,1.3L23.5,18.5c2-2.1,2-5.4,0-7.5C21.4,9,18.1,9,16,11c-2.1,2.1-2.1,5.4,0,7.5c1.7,1.7,4.3,2,6.3,0.9L41,37.7\r
+                       c-0.4,0.6-0.6,1.3-0.8,2.1l-15.2,0c-0.2-1.1-0.6-2.2-1.5-3c-2.1-2.1-5.4-2.1-7.5,0c-2.1,2.1-2.1,5.4,0,7.5c2.1,2.1,5.4,2.1,7.5,0\r
+                       c0.8-0.8,1.3-1.9,1.5-2.9l15.2,0c0.1,0.9,0.5,1.7,1,2.4L22.9,62c-2.1-1.6-5-1.4-6.9,0.5c-2.1,2.1-2.1,5.4,0,7.5\r
+                       c2.1,2.1,5.4,2.1,7.5,0c1.9-1.9,2-4.8,0.5-6.9l18.3-18.3c0.8,0.6,1.6,0.9,2.5,1l0.1,15.2c-1.2,0.1-2.3,0.6-3.2,1.5\r
+                       c-2.1,2.1-2.1,5.4,0,7.5c2.1,2.1,5.4,2.1,7.5,0c2.1-2.1,2.1-5.4,0-7.5c-0.8-0.8-1.8-1.3-2.8-1.5l-0.1-15.2\r
+                       c0.7-0.1,1.4-0.4,2.1-0.8l18.5,18.1c-1.5,2.1-1.4,5,0.5,6.9c2.1,2.1,5.4,2.1,7.5,0c2.1-2.1,2.1-5.4,0-7.5c-1.9-1.9-4.9-2-6.9-0.4\r
+                       L49.5,43.9c0.7-0.8,1.1-1.7,1.2-2.7L65.9,41.2z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-02-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-02-inactive.svg
new file mode 100755 (executable)
index 0000000..4d15e2b
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_40_">\r
+               <path id="XMLID_41_" class="st0" d="M65.9,41.2c0.2,1.1,0.6,2.1,1.5,3c2.1,2.1,5.4,2.1,7.5,0c2.1-2.1,2.1-5.4,0-7.5\r
+                       c-2.1-2.1-5.4-2.1-7.5,0c-0.8,0.8-1.3,1.9-1.5,3l-15.2,0c-0.1-0.8-0.5-1.7-1-2.4L68,19c2.1,1.6,5,1.4,6.9-0.5\r
+                       c2.1-2.1,2.1-5.4,0-7.5c-2.1-2.1-5.4-2.1-7.5,0c-1.9,1.9-2,4.8-0.5,6.9L48.6,36.3c-0.7-0.5-1.5-0.9-2.3-1L46.2,20\r
+                       c1.1-0.2,2.1-0.6,3-1.5c2.1-2.1,2.1-5.4,0-7.5c-2.1-2.1-5.4-2.1-7.5,0c-2.1,2.1-2.1,5.4,0,7.5c0.8,0.8,1.9,1.3,3,1.5l0.1,15.3\r
+                       c-1,0.1-2,0.6-2.8,1.3L23.5,18.5c2-2.1,2-5.4,0-7.5C21.4,9,18.1,9,16,11c-2.1,2.1-2.1,5.4,0,7.5c1.7,1.7,4.3,2,6.3,0.9L41,37.7\r
+                       c-0.4,0.6-0.6,1.3-0.8,2.1l-15.2,0c-0.2-1.1-0.6-2.2-1.5-3c-2.1-2.1-5.4-2.1-7.5,0c-2.1,2.1-2.1,5.4,0,7.5c2.1,2.1,5.4,2.1,7.5,0\r
+                       c0.8-0.8,1.3-1.9,1.5-2.9l15.2,0c0.1,0.9,0.5,1.7,1,2.4L22.9,62c-2.1-1.6-5-1.4-6.9,0.5c-2.1,2.1-2.1,5.4,0,7.5\r
+                       c2.1,2.1,5.4,2.1,7.5,0c1.9-1.9,2-4.8,0.5-6.9l18.3-18.3c0.8,0.6,1.6,0.9,2.5,1l0.1,15.2c-1.2,0.1-2.3,0.6-3.2,1.5\r
+                       c-2.1,2.1-2.1,5.4,0,7.5c2.1,2.1,5.4,2.1,7.5,0c2.1-2.1,2.1-5.4,0-7.5c-0.8-0.8-1.8-1.3-2.8-1.5l-0.1-15.2\r
+                       c0.7-0.1,1.4-0.4,2.1-0.8l18.5,18.1c-1.5,2.1-1.4,5,0.5,6.9c2.1,2.1,5.4,2.1,7.5,0c2.1-2.1,2.1-5.4,0-7.5c-1.9-1.9-4.9-2-6.9-0.4\r
+                       L49.5,43.9c0.7-0.8,1.1-1.7,1.2-2.7L65.9,41.2z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-03-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-03-active.svg
new file mode 100755 (executable)
index 0000000..d1b1aec
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_58_">\r
+               <path id="XMLID_59_" class="st0" d="M70.8,58.2c-0.7,0-1.4,0.1-2,0.3L51.5,42.7c0.7-1.1,1.2-2.4,1.2-3.8c0-1.4-0.4-2.7-1.2-3.8\r
+                       l15.1-13.9c1.1,0.9,2.6,1.5,4.2,1.5c3.7,0,6.7-3,6.7-6.6c0-3.7-3-6.6-6.7-6.6c-3.7,0-6.7,3-6.7,6.6c0,1.4,0.4,2.7,1.2,3.8\r
+                       L50.2,33.8c-1.1-0.9-2.6-1.5-4.2-1.5c-1.6,0-3.1,0.6-4.2,1.5L26.7,19.9c0.7-1.1,1.2-2.4,1.2-3.8c0-3.7-3-6.6-6.7-6.6\r
+                       c-3.7,0-6.7,3-6.7,6.6c0,3.3,2.5,6.1,5.7,6.6v35.6c-3.2,0.5-5.7,3.2-5.7,6.6c0,3.7,3,6.6,6.7,6.6c3.1,0,5.8-2.2,6.5-5.1h36.7\r
+                       c0.7,2.9,3.3,5.1,6.5,5.1c3.7,0,6.7-3,6.7-6.6C77.5,61.2,74.5,58.2,70.8,58.2z M64.2,64.5H27.8c-0.1-2.1-1.2-4-2.8-5.1l16.7-15.4\r
+                       c1.1,0.9,2.6,1.5,4.2,1.5c1.6,0,3.1-0.6,4.2-1.5L67,59.4C65.3,60.6,64.3,62.4,64.2,64.5z M25.4,21.3l15.1,13.9\r
+                       c-0.7,1.1-1.2,2.4-1.2,3.8c0,1.4,0.4,2.7,1.2,3.8L23.2,58.5c-0.3-0.1-0.7-0.2-1.1-0.2V22.7C23.4,22.5,24.5,22,25.4,21.3z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-03-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-03-inactive.svg
new file mode 100755 (executable)
index 0000000..03c74fd
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_58_">\r
+               <path id="XMLID_59_" class="st0" d="M70.8,58.2c-0.7,0-1.4,0.1-2,0.3L51.5,42.7c0.7-1.1,1.2-2.4,1.2-3.8c0-1.4-0.4-2.7-1.2-3.8\r
+                       l15.1-13.9c1.1,0.9,2.6,1.5,4.2,1.5c3.7,0,6.7-3,6.7-6.6c0-3.7-3-6.6-6.7-6.6c-3.7,0-6.7,3-6.7,6.6c0,1.4,0.4,2.7,1.2,3.8\r
+                       L50.2,33.8c-1.1-0.9-2.6-1.5-4.2-1.5c-1.6,0-3.1,0.6-4.2,1.5L26.7,19.9c0.7-1.1,1.2-2.4,1.2-3.8c0-3.7-3-6.6-6.7-6.6\r
+                       c-3.7,0-6.7,3-6.7,6.6c0,3.3,2.5,6.1,5.7,6.6v35.6c-3.2,0.5-5.7,3.2-5.7,6.6c0,3.7,3,6.6,6.7,6.6c3.1,0,5.8-2.2,6.5-5.1h36.7\r
+                       c0.7,2.9,3.3,5.1,6.5,5.1c3.7,0,6.7-3,6.7-6.6C77.5,61.2,74.5,58.2,70.8,58.2z M64.2,64.5H27.8c-0.1-2.1-1.2-4-2.8-5.1l16.7-15.4\r
+                       c1.1,0.9,2.6,1.5,4.2,1.5c1.6,0,3.1-0.6,4.2-1.5L67,59.4C65.3,60.6,64.3,62.4,64.2,64.5z M25.4,21.3l15.1,13.9\r
+                       c-0.7,1.1-1.2,2.4-1.2,3.8c0,1.4,0.4,2.7,1.2,3.8L23.2,58.5c-0.3-0.1-0.7-0.2-1.1-0.2V22.7C23.4,22.5,24.5,22,25.4,21.3z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-04-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-04-active.svg
new file mode 100755 (executable)
index 0000000..774653a
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_76_">\r
+               <path id="XMLID_77_" class="st0" d="M17,26.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,26.5,17,26.5z\r
+                        M17,64.4c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,64.4,17,64.4z M36,18.6c1.2,0,2.4-0.4,3.3-1.1\r
+                       l11.2,11.2c-0.7,0.9-1.1,2.1-1.1,3.3c0,3.1,2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S58,26.5,55,26.5c-1.2,0-2.4,0.4-3.3,1.1\r
+                       L40.4,16.3c0.7-0.9,1.1-2.1,1.1-3.3c0-3.1-2.5-5.5-5.5-5.5c-3.1,0-5.5,2.5-5.5,5.5S33,18.6,36,18.6z M74,18.6\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,7.5,74,7.5S68.4,10,68.4,13S70.9,18.6,74,18.6z M36,45.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5\r
+                       c3.1,0,5.5-2.5,5.5-5.5S39.1,45.5,36,45.5z M74,45.5c-3.1,0-5.5,2.5-5.5,5.5c0,1.5,0.6,2.9,1.6,3.9L58.9,66c-1-1-2.4-1.6-3.9-1.6\r
+                       c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5c0-1-0.3-1.9-0.7-2.7l11.5-11.5c0.8,0.4,1.7,0.7,2.7,0.7\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,45.5,74,45.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-04-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-04-inactive.svg
new file mode 100755 (executable)
index 0000000..3897a1e
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_76_">\r
+               <path id="XMLID_77_" class="st0" d="M17,26.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,26.5,17,26.5z\r
+                        M17,64.4c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,64.4,17,64.4z M36,18.6c1.2,0,2.4-0.4,3.3-1.1\r
+                       l11.2,11.2c-0.7,0.9-1.1,2.1-1.1,3.3c0,3.1,2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S58,26.5,55,26.5c-1.2,0-2.4,0.4-3.3,1.1\r
+                       L40.4,16.3c0.7-0.9,1.1-2.1,1.1-3.3c0-3.1-2.5-5.5-5.5-5.5c-3.1,0-5.5,2.5-5.5,5.5S33,18.6,36,18.6z M74,18.6\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,7.5,74,7.5S68.4,10,68.4,13S70.9,18.6,74,18.6z M36,45.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5\r
+                       c3.1,0,5.5-2.5,5.5-5.5S39.1,45.5,36,45.5z M74,45.5c-3.1,0-5.5,2.5-5.5,5.5c0,1.5,0.6,2.9,1.6,3.9L58.9,66c-1-1-2.4-1.6-3.9-1.6\r
+                       c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5c0-1-0.3-1.9-0.7-2.7l11.5-11.5c0.8,0.4,1.7,0.7,2.7,0.7\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,45.5,74,45.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-05-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-05-active.svg
new file mode 100755 (executable)
index 0000000..774653a
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_76_">\r
+               <path id="XMLID_77_" class="st0" d="M17,26.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,26.5,17,26.5z\r
+                        M17,64.4c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,64.4,17,64.4z M36,18.6c1.2,0,2.4-0.4,3.3-1.1\r
+                       l11.2,11.2c-0.7,0.9-1.1,2.1-1.1,3.3c0,3.1,2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S58,26.5,55,26.5c-1.2,0-2.4,0.4-3.3,1.1\r
+                       L40.4,16.3c0.7-0.9,1.1-2.1,1.1-3.3c0-3.1-2.5-5.5-5.5-5.5c-3.1,0-5.5,2.5-5.5,5.5S33,18.6,36,18.6z M74,18.6\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,7.5,74,7.5S68.4,10,68.4,13S70.9,18.6,74,18.6z M36,45.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5\r
+                       c3.1,0,5.5-2.5,5.5-5.5S39.1,45.5,36,45.5z M74,45.5c-3.1,0-5.5,2.5-5.5,5.5c0,1.5,0.6,2.9,1.6,3.9L58.9,66c-1-1-2.4-1.6-3.9-1.6\r
+                       c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5c0-1-0.3-1.9-0.7-2.7l11.5-11.5c0.8,0.4,1.7,0.7,2.7,0.7\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,45.5,74,45.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-05-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-05-inactive.svg
new file mode 100755 (executable)
index 0000000..3897a1e
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_76_">\r
+               <path id="XMLID_77_" class="st0" d="M17,26.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,26.5,17,26.5z\r
+                        M17,64.4c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S20.1,64.4,17,64.4z M36,18.6c1.2,0,2.4-0.4,3.3-1.1\r
+                       l11.2,11.2c-0.7,0.9-1.1,2.1-1.1,3.3c0,3.1,2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5S58,26.5,55,26.5c-1.2,0-2.4,0.4-3.3,1.1\r
+                       L40.4,16.3c0.7-0.9,1.1-2.1,1.1-3.3c0-3.1-2.5-5.5-5.5-5.5c-3.1,0-5.5,2.5-5.5,5.5S33,18.6,36,18.6z M74,18.6\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,7.5,74,7.5S68.4,10,68.4,13S70.9,18.6,74,18.6z M36,45.5c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5\r
+                       c3.1,0,5.5-2.5,5.5-5.5S39.1,45.5,36,45.5z M74,45.5c-3.1,0-5.5,2.5-5.5,5.5c0,1.5,0.6,2.9,1.6,3.9L58.9,66c-1-1-2.4-1.6-3.9-1.6\r
+                       c-3.1,0-5.5,2.5-5.5,5.5s2.5,5.5,5.5,5.5c3.1,0,5.5-2.5,5.5-5.5c0-1-0.3-1.9-0.7-2.7l11.5-11.5c0.8,0.4,1.7,0.7,2.7,0.7\r
+                       c3.1,0,5.5-2.5,5.5-5.5S77,45.5,74,45.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-06-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-06-active.svg
new file mode 100755 (executable)
index 0000000..31d7ae3
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g id="XMLID_28_">\r
+       <g id="XMLID_88_">\r
+               <path id="XMLID_89_" class="st0" d="M76.9,65.5v-9.7c1.1-0.1,2.2-0.6,3.1-1.4c2-2,2-5.2,0-7.1c-1.7-1.7-4.4-1.9-6.4-0.6L60.4,34\r
+                       c1.4-2,1.2-4.7-0.5-6.5c-1-1-2.3-1.5-3.6-1.5l-5.9-13.3c0.3-0.2,0.6-0.4,0.9-0.7c2-2,2-5.2,0-7.1c-2-2-5.2-2-7.1,0\r
+                       c-2,2-2,5.2,0,7.1c0.3,0.3,0.6,0.5,0.9,0.7l-6,13.4c-1.9-1.1-4.4-0.8-6,0.8c-1.9,1.9-1.9,4.9-0.2,6.8L18.5,46.7\r
+                       c-2-1.4-4.7-1.3-6.5,0.5c-2,2-2,5.2,0,7.1c0.7,0.7,1.7,1.2,2.6,1.4v9.8c-1,0.2-1.9,0.6-2.6,1.4c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0\r
+                       c2-2,2-5.2,0-7.1c-0.9-0.9-2-1.3-3.1-1.4v-9.7c1.1-0.1,2.2-0.6,3.1-1.4c1.8-1.8,1.9-4.7,0.4-6.6l14.4-12.9\r
+                       c0.6,0.4,1.2,0.6,1.8,0.7v10.3c-1,0.2-1.9,0.6-2.7,1.4c-2,2-2,5.2,0,7.1c0.8,0.8,1.7,1.2,2.7,1.4v9.8c-1,0.2-1.9,0.6-2.7,1.4\r
+                       c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0c2-2,2-5.2,0-7.1c-0.8-0.8-1.9-1.3-3-1.4v-9.7c1.1-0.1,2.2-0.6,3-1.4c2-2,2-5.2,0-7.1\r
+                       c-0.8-0.8-1.9-1.3-3-1.4V35.6c1.1-0.1,2.2-0.6,3-1.4c1.9-1.9,2-5.1,0.1-7.1l6.1-13.8c0.9,0.2,1.8,0.2,2.7,0l5.8,12.9\r
+                       c-0.7,0.2-1.4,0.6-2,1.2c-2,2-2,5.2,0,7.1c0.8,0.8,1.8,1.2,2.8,1.4l0,9.7c-1.1,0.1-2.1,0.6-3,1.4c-2,2-2,5.2,0,7.1\r
+                       c0.8,0.8,1.8,1.2,2.8,1.4v9.8c-1,0.2-2,0.6-2.8,1.4c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0c2-2,2-5.2,0-7.1c-0.8-0.8-1.9-1.3-2.9-1.4\r
+                       v-9.7c1.1-0.1,2.1-0.6,2.9-1.4c2-2,2-5.2,0-7.1C58.9,46.4,58,46,57,45.8l0-9.7c0.9-0.1,1.7-0.5,2.4-1l13.2,12.6\r
+                       c-1.6,2-1.5,4.9,0.3,6.7c0.7,0.7,1.7,1.2,2.6,1.4v9.8c-1,0.2-1.9,0.6-2.6,1.4c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0c2-2,2-5.2,0-7.1\r
+                       C79.2,66,78.1,65.6,76.9,65.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-06-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-06-inactive.svg
new file mode 100755 (executable)
index 0000000..e5a845b
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g id="XMLID_28_">\r
+       <g id="XMLID_88_">\r
+               <path id="XMLID_89_" class="st0" d="M76.9,65.5v-9.7c1.1-0.1,2.2-0.6,3.1-1.4c2-2,2-5.2,0-7.1c-1.7-1.7-4.4-1.9-6.4-0.6L60.4,34\r
+                       c1.4-2,1.2-4.7-0.5-6.5c-1-1-2.3-1.5-3.6-1.5l-5.9-13.3c0.3-0.2,0.6-0.4,0.9-0.7c2-2,2-5.2,0-7.1c-2-2-5.2-2-7.1,0\r
+                       c-2,2-2,5.2,0,7.1c0.3,0.3,0.6,0.5,0.9,0.7l-6,13.4c-1.9-1.1-4.4-0.8-6,0.8c-1.9,1.9-1.9,4.9-0.2,6.8L18.5,46.7\r
+                       c-2-1.4-4.7-1.3-6.5,0.5c-2,2-2,5.2,0,7.1c0.7,0.7,1.7,1.2,2.6,1.4v9.8c-1,0.2-1.9,0.6-2.6,1.4c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0\r
+                       c2-2,2-5.2,0-7.1c-0.9-0.9-2-1.3-3.1-1.4v-9.7c1.1-0.1,2.2-0.6,3.1-1.4c1.8-1.8,1.9-4.7,0.4-6.6l14.4-12.9\r
+                       c0.6,0.4,1.2,0.6,1.8,0.7v10.3c-1,0.2-1.9,0.6-2.7,1.4c-2,2-2,5.2,0,7.1c0.8,0.8,1.7,1.2,2.7,1.4v9.8c-1,0.2-1.9,0.6-2.7,1.4\r
+                       c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0c2-2,2-5.2,0-7.1c-0.8-0.8-1.9-1.3-3-1.4v-9.7c1.1-0.1,2.2-0.6,3-1.4c2-2,2-5.2,0-7.1\r
+                       c-0.8-0.8-1.9-1.3-3-1.4V35.6c1.1-0.1,2.2-0.6,3-1.4c1.9-1.9,2-5.1,0.1-7.1l6.1-13.8c0.9,0.2,1.8,0.2,2.7,0l5.8,12.9\r
+                       c-0.7,0.2-1.4,0.6-2,1.2c-2,2-2,5.2,0,7.1c0.8,0.8,1.8,1.2,2.8,1.4l0,9.7c-1.1,0.1-2.1,0.6-3,1.4c-2,2-2,5.2,0,7.1\r
+                       c0.8,0.8,1.8,1.2,2.8,1.4v9.8c-1,0.2-2,0.6-2.8,1.4c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0c2-2,2-5.2,0-7.1c-0.8-0.8-1.9-1.3-2.9-1.4\r
+                       v-9.7c1.1-0.1,2.1-0.6,2.9-1.4c2-2,2-5.2,0-7.1C58.9,46.4,58,46,57,45.8l0-9.7c0.9-0.1,1.7-0.5,2.4-1l13.2,12.6\r
+                       c-1.6,2-1.5,4.9,0.3,6.7c0.7,0.7,1.7,1.2,2.6,1.4v9.8c-1,0.2-1.9,0.6-2.6,1.4c-2,2-2,5.2,0,7.1c2,2,5.2,2,7.1,0c2-2,2-5.2,0-7.1\r
+                       C79.2,66,78.1,65.6,76.9,65.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-07-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-07-active.svg
new file mode 100755 (executable)
index 0000000..4888d81
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_70_">\r
+               <path id="XMLID_71_" class="st0" d="M68.4,56.8V25.2c2.9-0.4,5.1-2.9,5.1-5.8c0-3.3-2.7-5.9-5.9-5.9c-3,0-5.5,2.2-5.9,5.1H29.3\r
+                       c-0.4-2.9-2.9-5.1-5.9-5.1c-3.3,0-5.9,2.6-5.9,5.9c0,3,2.2,5.4,5.1,5.8v31.6c-2.9,0.4-5.1,2.9-5.1,5.8c0,3.3,2.7,5.9,5.9,5.9\r
+                       c2.8,0,5.1-1.9,5.8-4.5h32.6c0.6,2.6,3,4.5,5.8,4.5c3.3,0,5.9-2.6,5.9-5.9C73.5,59.6,71.3,57.2,68.4,56.8z M65.7,57L50.4,42.9\r
+                       c0.7-0.9,1-2.1,1-3.3c0-1.2-0.4-2.4-1-3.3L63.8,24c0.8,0.7,1.8,1.1,2.9,1.3v31.6C66.4,56.8,66.1,56.9,65.7,57z M62.7,22.7L49.2,35\r
+                       c-1-0.8-2.3-1.3-3.7-1.3c-1.4,0-2.7,0.5-3.7,1.3L28.3,22.7c0.5-0.7,0.8-1.6,1-2.5h32.4C61.8,21.2,62.2,22,62.7,22.7z M27.2,24\r
+                       l13.4,12.3c-0.7,0.9-1,2.1-1,3.3c0,1.2,0.4,2.4,1,3.3L25.3,57c-0.3-0.1-0.6-0.2-1-0.2V25.2C25.4,25.1,26.4,24.6,27.2,24z\r
+                        M26.9,57.8l14.9-13.6c1,0.8,2.3,1.3,3.7,1.3c1.4,0,2.7-0.5,3.7-1.3l14.9,13.6c-1.4,1-2.4,2.7-2.5,4.5H29.4\r
+                       C29.3,60.5,28.3,58.8,26.9,57.8z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-07-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-07-inactive.svg
new file mode 100755 (executable)
index 0000000..81ee3cc
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_70_">\r
+               <path id="XMLID_71_" class="st0" d="M68.4,56.8V25.2c2.9-0.4,5.1-2.9,5.1-5.8c0-3.3-2.7-5.9-5.9-5.9c-3,0-5.5,2.2-5.9,5.1H29.3\r
+                       c-0.4-2.9-2.9-5.1-5.9-5.1c-3.3,0-5.9,2.6-5.9,5.9c0,3,2.2,5.4,5.1,5.8v31.6c-2.9,0.4-5.1,2.9-5.1,5.8c0,3.3,2.7,5.9,5.9,5.9\r
+                       c2.8,0,5.1-1.9,5.8-4.5h32.6c0.6,2.6,3,4.5,5.8,4.5c3.3,0,5.9-2.6,5.9-5.9C73.5,59.6,71.3,57.2,68.4,56.8z M65.7,57L50.4,42.9\r
+                       c0.7-0.9,1-2.1,1-3.3c0-1.2-0.4-2.4-1-3.3L63.8,24c0.8,0.7,1.8,1.1,2.9,1.3v31.6C66.4,56.8,66.1,56.9,65.7,57z M62.7,22.7L49.2,35\r
+                       c-1-0.8-2.3-1.3-3.7-1.3c-1.4,0-2.7,0.5-3.7,1.3L28.3,22.7c0.5-0.7,0.8-1.6,1-2.5h32.4C61.8,21.2,62.2,22,62.7,22.7z M27.2,24\r
+                       l13.4,12.3c-0.7,0.9-1,2.1-1,3.3c0,1.2,0.4,2.4,1,3.3L25.3,57c-0.3-0.1-0.6-0.2-1-0.2V25.2C25.4,25.1,26.4,24.6,27.2,24z\r
+                        M26.9,57.8l14.9-13.6c1,0.8,2.3,1.3,3.7,1.3c1.4,0,2.7-0.5,3.7-1.3l14.9,13.6c-1.4,1-2.4,2.7-2.5,4.5H29.4\r
+                       C29.3,60.5,28.3,58.8,26.9,57.8z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-08-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-08-active.svg
new file mode 100755 (executable)
index 0000000..9ce2e16
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g id="XMLID_28_">\r
+       <g id="XMLID_99_">\r
+               <path id="XMLID_100_" class="st0" d="M78.1,67.1c-1,0-1.9,0.3-2.7,0.8l-7.8-7.7c0.5-0.8,0.9-1.8,0.9-2.8c0-2.5-1.8-4.5-4.2-4.9\r
+                       V25.9c2.4-0.3,4.2-2.4,4.2-4.9c0-1.1-0.4-2.2-1-3l8.2-8.2c0.8,0.6,1.8,1,3,1c2.7,0,4.9-2.2,4.9-5s-2.2-5-4.9-5\r
+                       c-2.7,0-4.9,2.2-4.9,5c0,1.1,0.4,2.1,1,2.9l-8.2,8.2c-0.8-0.6-1.8-1-2.9-1c-2.5,0-4.5,1.8-4.9,4.2H31.8c-0.3-2.4-2.4-4.2-4.9-4.2\r
+                       c-1.1,0-2,0.3-2.9,0.9l-7.7-7.7c0.6-0.8,1-1.8,1-2.9c0-2.7-2.2-5-4.9-5s-4.9,2.2-4.9,5c0,2.7,2.2,5,4.9,5c1.1,0,2.1-0.4,3-1\r
+                       l7.7,7.7c-0.7,0.8-1.1,1.9-1.1,3c0,2.5,1.8,4.5,4.2,4.9v26.6c-2.4,0.3-4.2,2.4-4.2,4.9c0,1.1,0.4,2.2,1,3l-6.8,6.7\r
+                       c-0.8-0.6-1.8-1-3-1c-2.7,0-4.9,2.2-4.9,5s2.2,5,4.9,5c2.7,0,4.9-2.2,4.9-5c0-1.1-0.4-2.1-1-2.9l6.8-6.8c0.8,0.6,1.8,1,2.9,1\r
+                       c2.3,0,4.2-1.6,4.8-3.8h27.1c0.5,2.2,2.5,3.8,4.8,3.8c1.2,0,2.3-0.4,3.1-1.1l7.7,7.6c-0.7,0.9-1.2,2-1.2,3.2c0,2.7,2.2,5,4.9,5\r
+                       s4.9-2.2,4.9-5C83,69.3,80.8,67.1,78.1,67.1z M48.8,41.5c0.9-0.9,1.4-2.1,1.4-3.4c0-0.8-0.2-1.5-0.5-2.2L60.6,25\r
+                       c0.7,0.5,1.4,0.9,2.3,1v26.6c-0.8,0.1-1.5,0.4-2.1,0.8L48.8,41.5z M59.6,23.9L48.8,34.7c-0.9-1-2.2-1.6-3.6-1.6\r
+                       c-1.4,0-2.6,0.6-3.5,1.5L31,23.9c0.4-0.6,0.7-1.3,0.8-2.1h26.9C58.8,22.6,59.1,23.3,59.6,23.9z M30,24.9l10.9,10.8\r
+                       c-0.4,0.7-0.6,1.5-0.6,2.3c0,1.4,0.6,2.7,1.5,3.6L30,53.5c-0.7-0.5-1.4-0.9-2.3-1V25.9C28.6,25.8,29.4,25.4,30,24.9z M31,54.5\r
+                       L43,42.5c0.7,0.3,1.4,0.6,2.2,0.6c0.9,0,1.7-0.2,2.4-0.6l12.1,12c-0.6,0.8-1,1.8-1.1,2.8H31.9C31.8,56.2,31.5,55.3,31,54.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-08-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-08-inactive.svg
new file mode 100755 (executable)
index 0000000..02525a6
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 90.8 78.5" style="enable-background:new 0 0 90.8 78.5;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g id="XMLID_28_">\r
+       <g id="XMLID_99_">\r
+               <path id="XMLID_100_" class="st0" d="M78.1,67.1c-1,0-1.9,0.3-2.7,0.8l-7.8-7.7c0.5-0.8,0.9-1.8,0.9-2.8c0-2.5-1.8-4.5-4.2-4.9\r
+                       V25.9c2.4-0.3,4.2-2.4,4.2-4.9c0-1.1-0.4-2.2-1-3l8.2-8.2c0.8,0.6,1.8,1,3,1c2.7,0,4.9-2.2,4.9-5s-2.2-5-4.9-5\r
+                       c-2.7,0-4.9,2.2-4.9,5c0,1.1,0.4,2.1,1,2.9l-8.2,8.2c-0.8-0.6-1.8-1-2.9-1c-2.5,0-4.5,1.8-4.9,4.2H31.8c-0.3-2.4-2.4-4.2-4.9-4.2\r
+                       c-1.1,0-2,0.3-2.9,0.9l-7.7-7.7c0.6-0.8,1-1.8,1-2.9c0-2.7-2.2-5-4.9-5s-4.9,2.2-4.9,5c0,2.7,2.2,5,4.9,5c1.1,0,2.1-0.4,3-1\r
+                       l7.7,7.7c-0.7,0.8-1.1,1.9-1.1,3c0,2.5,1.8,4.5,4.2,4.9v26.6c-2.4,0.3-4.2,2.4-4.2,4.9c0,1.1,0.4,2.2,1,3l-6.8,6.7\r
+                       c-0.8-0.6-1.8-1-3-1c-2.7,0-4.9,2.2-4.9,5s2.2,5,4.9,5c2.7,0,4.9-2.2,4.9-5c0-1.1-0.4-2.1-1-2.9l6.8-6.8c0.8,0.6,1.8,1,2.9,1\r
+                       c2.3,0,4.2-1.6,4.8-3.8h27.1c0.5,2.2,2.5,3.8,4.8,3.8c1.2,0,2.3-0.4,3.1-1.1l7.7,7.6c-0.7,0.9-1.2,2-1.2,3.2c0,2.7,2.2,5,4.9,5\r
+                       s4.9-2.2,4.9-5C83,69.3,80.8,67.1,78.1,67.1z M48.8,41.5c0.9-0.9,1.4-2.1,1.4-3.4c0-0.8-0.2-1.5-0.5-2.2L60.6,25\r
+                       c0.7,0.5,1.4,0.9,2.3,1v26.6c-0.8,0.1-1.5,0.4-2.1,0.8L48.8,41.5z M59.6,23.9L48.8,34.7c-0.9-1-2.2-1.6-3.6-1.6\r
+                       c-1.4,0-2.6,0.6-3.5,1.5L31,23.9c0.4-0.6,0.7-1.3,0.8-2.1h26.9C58.8,22.6,59.1,23.3,59.6,23.9z M30,24.9l10.9,10.8\r
+                       c-0.4,0.7-0.6,1.5-0.6,2.3c0,1.4,0.6,2.7,1.5,3.6L30,53.5c-0.7-0.5-1.4-0.9-2.3-1V25.9C28.6,25.8,29.4,25.4,30,24.9z M31,54.5\r
+                       L43,42.5c0.7,0.3,1.4,0.6,2.2,0.6c0.9,0,1.7-0.2,2.4-0.6l12.1,12c-0.6,0.8-1,1.8-1.1,2.8H31.9C31.8,56.2,31.5,55.3,31,54.5z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-09-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-09-active.svg
new file mode 100755 (executable)
index 0000000..a703d2e
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 80 80" style="enable-background:new 0 0 80 80;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g id="XMLID_28_">\r
+       <g id="XMLID_113_">\r
+               <path id="XMLID_114_" class="st0" d="M6.5,22.3c-3.6,0-6.5,2.9-6.5,6.5c0,3.6,2.9,6.5,6.5,6.5c3.6,0,6.5-2.9,6.5-6.5\r
+                       C13,25.2,10.1,22.3,6.5,22.3z M6.5,67C2.9,67,0,69.9,0,73.5C0,77.1,2.9,80,6.5,80c3.6,0,6.5-2.9,6.5-6.5C13,69.9,10.1,67,6.5,67z\r
+                        M28.8,13c1.5,0,2.8-0.5,3.9-1.3L46,24.9c-0.8,1.1-1.3,2.4-1.3,3.9c0,3.6,2.9,6.5,6.5,6.5c3.6,0,6.5-2.9,6.5-6.5\r
+                       c0-3.6-2.9-6.5-6.5-6.5c-1.5,0-2.8,0.5-3.9,1.3L34,10.4c0.8-1.1,1.3-2.4,1.3-3.9c0-3.6-2.9-6.5-6.5-6.5c-3.6,0-6.5,2.9-6.5,6.5\r
+                       C22.3,10.1,25.2,13,28.8,13z M73.5,13c3.6,0,6.5-2.9,6.5-6.5C80,2.9,77.1,0,73.5,0C69.9,0,67,2.9,67,6.5C67,10.1,69.9,13,73.5,13z\r
+                        M28.8,44.7c-3.6,0-6.5,2.9-6.5,6.5c0,3.6,2.9,6.5,6.5,6.5c3.6,0,6.5-2.9,6.5-6.5C35.3,47.6,32.4,44.7,28.8,44.7z M73.5,44.7\r
+                       c-3.6,0-6.5,2.9-6.5,6.5c0,1.8,0.7,3.4,1.9,4.6L55.7,68.8c-1.2-1.2-2.8-1.9-4.6-1.9c-3.6,0-6.5,2.9-6.5,6.5c0,3.6,2.9,6.5,6.5,6.5\r
+                       c3.6,0,6.5-2.9,6.5-6.5c0-1.1-0.3-2.2-0.8-3.1l13.5-13.5c0.9,0.5,2,0.8,3.1,0.8c3.6,0,6.5-2.9,6.5-6.5\r
+                       C80,47.6,77.1,44.7,73.5,44.7z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-09-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-09-inactive.svg
new file mode 100755 (executable)
index 0000000..8e1d702
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 80 80" style="enable-background:new 0 0 80 80;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g id="XMLID_28_">\r
+       <g id="XMLID_100_">\r
+               <path id="XMLID_101_" class="st0" d="M6.5,22.3c-3.6,0-6.5,2.9-6.5,6.5c0,3.6,2.9,6.5,6.5,6.5c3.6,0,6.5-2.9,6.5-6.5\r
+                       C13,25.2,10.1,22.3,6.5,22.3z M6.5,67C2.9,67,0,69.9,0,73.5C0,77.1,2.9,80,6.5,80c3.6,0,6.5-2.9,6.5-6.5C13,69.9,10.1,67,6.5,67z\r
+                        M28.8,13c1.5,0,2.8-0.5,3.9-1.3L46,24.9c-0.8,1.1-1.3,2.4-1.3,3.9c0,3.6,2.9,6.5,6.5,6.5c3.6,0,6.5-2.9,6.5-6.5\r
+                       c0-3.6-2.9-6.5-6.5-6.5c-1.5,0-2.8,0.5-3.9,1.3L34,10.4c0.8-1.1,1.3-2.4,1.3-3.9c0-3.6-2.9-6.5-6.5-6.5c-3.6,0-6.5,2.9-6.5,6.5\r
+                       C22.3,10.1,25.2,13,28.8,13z M73.5,13c3.6,0,6.5-2.9,6.5-6.5C80,2.9,77.1,0,73.5,0C69.9,0,67,2.9,67,6.5C67,10.1,69.9,13,73.5,13z\r
+                        M28.8,44.7c-3.6,0-6.5,2.9-6.5,6.5c0,3.6,2.9,6.5,6.5,6.5c3.6,0,6.5-2.9,6.5-6.5C35.3,47.6,32.4,44.7,28.8,44.7z M73.5,44.7\r
+                       c-3.6,0-6.5,2.9-6.5,6.5c0,1.8,0.7,3.4,1.9,4.6L55.7,68.8c-1.2-1.2-2.8-1.9-4.6-1.9c-3.6,0-6.5,2.9-6.5,6.5c0,3.6,2.9,6.5,6.5,6.5\r
+                       c3.6,0,6.5-2.9,6.5-6.5c0-1.1-0.3-2.2-0.8-3.1l13.5-13.5c0.9,0.5,2,0.8,3.1,0.8c3.6,0,6.5-2.9,6.5-6.5\r
+                       C80,47.6,77.1,44.7,73.5,44.7z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-10-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-10-active.svg
new file mode 100755 (executable)
index 0000000..a9b5496
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 94 74" style="enable-background:new 0 0 94 74;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#FFFFFF;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_96_">\r
+               <path id="XMLID_97_" class="st0" d="M89.1,54.9l-9.6-13c0.2-0.1,0.3-0.3,0.4-0.4c2.3-2.3,2.4-5.9,0.5-8.3L89.6,20\r
+                       c1.1,0.6,2.6,0.5,3.6-0.5c1.2-1.2,1.2-3.1,0-4.3c-1.2-1.2-3-1.2-4.2,0c-1.2,1.2-1.2,3.1,0,4.3c0.1,0.1,0.1,0.1,0.2,0.1l-9,13\r
+                       c0,0-0.1-0.1-0.1-0.1c-1.8-1.9-4.6-2.3-6.8-1.4L51,8.8c0.9-2.3,0.5-5-1.3-6.9c-2.4-2.5-6.4-2.5-8.8,0c-1.9,1.9-2.3,4.8-1.2,7.2\r
+                       l-22,22.2c-1.8-0.9-4-0.8-5.7,0.2L4.8,19.8c0.1-0.1,0.2-0.2,0.3-0.2c1.2-1.2,1.2-3.1,0-4.3c-1.2-1.2-3-1.2-4.2,0\r
+                       c-1.2,1.2-1.2,3.1,0,4.3c0.9,0.9,2.3,1.1,3.4,0.6l7.2,11.7c-0.3,0.2-0.6,0.5-0.9,0.7c-2.4,2.5-2.4,6.5,0,8.9\r
+                       c0.3,0.3,0.6,0.6,0.9,0.8L4.2,54.5c-1.1-0.5-2.5-0.3-3.4,0.6c-1.2,1.2-1.2,3.1,0,4.3c1.2,1.2,3,1.2,4.2,0c1.2-1.2,1.2-3.1,0-4.3\r
+                       c-0.1-0.1-0.2-0.2-0.3-0.3L12,42.6c1.5,0.8,3.2,1,4.7,0.5l22.5,22.8c-0.6,2.2-0.1,4.6,1.6,6.3c2.4,2.5,6.4,2.5,8.8,0\r
+                       c1.6-1.6,2.1-3.9,1.7-5.9l22.8-23.1c1.7,0.4,3.5,0.1,4.9-0.9l9.6,13l0.2-0.2c-1.2,1.2-1.2,3.1,0,4.3c1.2,1.2,3,1.2,4.2,0\r
+                       c1.2-1.2,1.2-3.1,0-4.3C92,53.9,90.3,53.9,89.1,54.9z M71.6,32.1c-0.2,0.1-0.3,0.3-0.4,0.4c-1.5,1.5-2.1,3.6-1.7,5.6h-18\r
+                       c0.3-2-0.2-4-1.7-5.6c-1-1-2.3-1.6-3.6-1.8V12.6c1.3-0.2,2.6-0.8,3.6-1.8c0.1-0.1,0.3-0.3,0.4-0.4L71.6,32.1z M40.7,10.6\r
+                       c0.1,0.1,0.1,0.1,0.2,0.2c1,1,2.2,1.6,3.4,1.8v18.2c-1.3,0.2-2.5,0.8-3.4,1.8c-1.5,1.5-2.1,3.6-1.7,5.6h-18c0.4-2-0.2-4.1-1.7-5.6\r
+                       c-0.1-0.1-0.1-0.1-0.2-0.2L40.7,10.6z M18.5,42.2c0.3-0.2,0.6-0.5,0.9-0.8c0.5-0.5,0.8-1,1.1-1.5h19.2c0.3,0.6,0.7,1.1,1.1,1.6\r
+                       c1,1,2.2,1.6,3.4,1.8v18.1c-1.3,0.2-2.5,0.8-3.4,1.8c-0.3,0.3-0.5,0.6-0.8,0.9L18.5,42.2z M50.6,64.4c-0.3-0.4-0.6-0.8-0.9-1.2\r
+                       c-1-1-2.3-1.6-3.6-1.8V43.3c1.3-0.2,2.6-0.8,3.6-1.8c0.5-0.5,0.9-1,1.1-1.6H70c0.3,0.6,0.7,1.1,1.1,1.5c0.4,0.4,0.8,0.7,1.2,0.9\r
+                       L50.6,64.4z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-10-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-10-inactive.svg
new file mode 100755 (executable)
index 0000000..91b2b59
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 94 74" style="enable-background:new 0 0 94 74;" xml:space="preserve">\r
+<style type="text/css">\r
+       .st0{fill:#CCCCCC;}\r
+</style>\r
+<g>\r
+       <g id="XMLID_96_">\r
+               <path id="XMLID_97_" class="st0" d="M89.1,54.9l-9.6-13c0.2-0.1,0.3-0.3,0.4-0.4c2.3-2.3,2.4-5.9,0.5-8.3L89.6,20\r
+                       c1.1,0.6,2.6,0.5,3.6-0.5c1.2-1.2,1.2-3.1,0-4.3c-1.2-1.2-3-1.2-4.2,0c-1.2,1.2-1.2,3.1,0,4.3c0.1,0.1,0.1,0.1,0.2,0.1l-9,13\r
+                       c0,0-0.1-0.1-0.1-0.1c-1.8-1.9-4.6-2.3-6.8-1.4L51,8.8c0.9-2.3,0.5-5-1.3-6.9c-2.4-2.5-6.4-2.5-8.8,0c-1.9,1.9-2.3,4.8-1.2,7.2\r
+                       l-22,22.2c-1.8-0.9-4-0.8-5.7,0.2L4.8,19.8c0.1-0.1,0.2-0.2,0.3-0.2c1.2-1.2,1.2-3.1,0-4.3c-1.2-1.2-3-1.2-4.2,0\r
+                       c-1.2,1.2-1.2,3.1,0,4.3c0.9,0.9,2.3,1.1,3.4,0.6l7.2,11.7c-0.3,0.2-0.6,0.5-0.9,0.7c-2.4,2.5-2.4,6.5,0,8.9\r
+                       c0.3,0.3,0.6,0.6,0.9,0.8L4.2,54.5c-1.1-0.5-2.5-0.3-3.4,0.6c-1.2,1.2-1.2,3.1,0,4.3c1.2,1.2,3,1.2,4.2,0c1.2-1.2,1.2-3.1,0-4.3\r
+                       c-0.1-0.1-0.2-0.2-0.3-0.3L12,42.6c1.5,0.8,3.2,1,4.7,0.5l22.5,22.8c-0.6,2.2-0.1,4.6,1.6,6.3c2.4,2.5,6.4,2.5,8.8,0\r
+                       c1.6-1.6,2.1-3.9,1.7-5.9l22.8-23.1c1.7,0.4,3.5,0.1,4.9-0.9l9.6,13l0.2-0.2c-1.2,1.2-1.2,3.1,0,4.3c1.2,1.2,3,1.2,4.2,0\r
+                       c1.2-1.2,1.2-3.1,0-4.3C92,53.9,90.3,53.9,89.1,54.9z M71.6,32.1c-0.2,0.1-0.3,0.3-0.4,0.4c-1.5,1.5-2.1,3.6-1.7,5.6h-18\r
+                       c0.3-2-0.2-4-1.7-5.6c-1-1-2.3-1.6-3.6-1.8V12.6c1.3-0.2,2.6-0.8,3.6-1.8c0.1-0.1,0.3-0.3,0.4-0.4L71.6,32.1z M40.7,10.6\r
+                       c0.1,0.1,0.1,0.1,0.2,0.2c1,1,2.2,1.6,3.4,1.8v18.2c-1.3,0.2-2.5,0.8-3.4,1.8c-1.5,1.5-2.1,3.6-1.7,5.6h-18c0.4-2-0.2-4.1-1.7-5.6\r
+                       c-0.1-0.1-0.1-0.1-0.2-0.2L40.7,10.6z M18.5,42.2c0.3-0.2,0.6-0.5,0.9-0.8c0.5-0.5,0.8-1,1.1-1.5h19.2c0.3,0.6,0.7,1.1,1.1,1.6\r
+                       c1,1,2.2,1.6,3.4,1.8v18.1c-1.3,0.2-2.5,0.8-3.4,1.8c-0.3,0.3-0.5,0.6-0.8,0.9L18.5,42.2z M50.6,64.4c-0.3-0.4-0.6-0.8-0.9-1.2\r
+                       c-1-1-2.3-1.6-3.6-1.8V43.3c1.3-0.2,2.6-0.8,3.6-1.8c0.5-0.5,0.9-1,1.1-1.6H70c0.3,0.6,0.7,1.1,1.1,1.5c0.4,0.4,0.8,0.7,1.2,0.9\r
+                       L50.6,64.4z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-11-active.svg b/skyquake/framework/style/img/svg/launch-fleet-network-11-active.svg
new file mode 100644 (file)
index 0000000..e18114c
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 92.6 93.7" enable-background="new 0 0 92.6 93.7" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_40_">\r
+               <path id="XMLID_41_" fill="#FFFFFF" d="M77.5,73.7c-1,0-1.9,0.3-2.6,0.8L67.3,67c0.5-0.8,0.8-1.7,0.8-2.7c0-2.7-2.1-4.8-4.8-4.8\r
+                       c-1,0-2,0.3-2.7,0.9L49,48.8c0.8-0.9,1.4-2.1,1.4-3.4c0-0.8-0.2-1.5-0.5-2.2l10.6-10.6c0.8,0.6,1.8,1,2.9,1c2.6,0,4.8-2.2,4.8-4.8\r
+                       c0-1.1-0.4-2.1-1-2.9l8-7.9c0.8,0.6,1.8,1,2.9,1c2.6,0,4.8-2.2,4.8-4.8c0-2.7-2.1-4.8-4.8-4.8c-2.6,0-4.8,2.2-4.8,4.8\r
+                       c0,1.1,0.4,2.1,1,2.9l-8,8c-0.8-0.6-1.8-0.9-2.8-0.9c-2.6,0-4.8,2.2-4.8,4.8c0,1.1,0.3,2,0.9,2.8L49,42.1\r
+                       c-0.9-0.9-2.1-1.5-3.5-1.5c-1.3,0-2.5,0.5-3.4,1.4L31.7,31.6c0.5-0.8,0.9-1.7,0.9-2.7c0-2.7-2.1-4.8-4.8-4.8c-1,0-2,0.3-2.8,0.9\r
+                       l-7.5-7.5c0.6-0.8,0.9-1.8,0.9-2.9c0-2.7-2.1-4.8-4.8-4.8c-2.6,0-4.8,2.2-4.8,4.8c0,2.7,2.1,4.8,4.8,4.8c1.1,0,2.1-0.4,2.9-1\r
+                       l7.5,7.5c-0.6,0.8-1,1.8-1,3c0,2.7,2.1,4.8,4.8,4.8c1.1,0,2.2-0.4,3-1.1l10.6,10.5c-0.4,0.7-0.6,1.5-0.6,2.3\r
+                       c0,1.4,0.6,2.6,1.5,3.5L30.7,60.5c-0.8-0.6-1.8-1-2.9-1c-2.6,0-4.8,2.2-4.8,4.8c0,1.1,0.4,2.1,1,2.9l-6.6,6.6\r
+                       c-0.8-0.6-1.8-1-2.9-1c-2.6,0-4.8,2.2-4.8,4.8c0,2.7,2.1,4.8,4.8,4.8c2.6,0,4.8-2.2,4.8-4.8c0-1.1-0.4-2.1-1-2.9l6.6-6.6\r
+                       c0.8,0.6,1.8,0.9,2.8,0.9c2.6,0,4.8-2.2,4.8-4.8c0-1.1-0.3-2-0.9-2.8l11.8-11.8c0.7,0.3,1.4,0.5,2.2,0.5c0.8,0,1.6-0.2,2.3-0.6\r
+                       l11.8,11.7c-0.7,0.8-1.1,1.9-1.1,3c0,2.7,2.1,4.8,4.8,4.8c1.2,0,2.2-0.4,3-1.1l7.5,7.4c-0.7,0.8-1.2,1.9-1.2,3.1\r
+                       c0,2.7,2.1,4.8,4.8,4.8s4.8-2.2,4.8-4.8C82.3,75.9,80.2,73.7,77.5,73.7z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-network-11-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-network-11-inactive.svg
new file mode 100644 (file)
index 0000000..173d3b1
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 92.6 93.7" enable-background="new 0 0 92.6 93.7" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_14_">\r
+               <path id="XMLID_15_" fill="#CCCCCC" d="M77.5,73.7c-1,0-1.9,0.3-2.6,0.8L67.3,67c0.5-0.8,0.8-1.7,0.8-2.7c0-2.7-2.1-4.8-4.8-4.8\r
+                       c-1,0-2,0.3-2.7,0.9L49,48.8c0.8-0.9,1.4-2.1,1.4-3.4c0-0.8-0.2-1.5-0.5-2.2l10.6-10.6c0.8,0.6,1.8,1,2.9,1c2.6,0,4.8-2.2,4.8-4.8\r
+                       c0-1.1-0.4-2.1-1-2.9l8-7.9c0.8,0.6,1.8,1,2.9,1c2.6,0,4.8-2.2,4.8-4.8c0-2.7-2.1-4.8-4.8-4.8c-2.6,0-4.8,2.2-4.8,4.8\r
+                       c0,1.1,0.4,2.1,1,2.9l-8,8c-0.8-0.6-1.8-0.9-2.8-0.9c-2.6,0-4.8,2.2-4.8,4.8c0,1.1,0.3,2,0.9,2.8L49,42.1\r
+                       c-0.9-0.9-2.1-1.5-3.5-1.5c-1.3,0-2.5,0.5-3.4,1.4L31.7,31.6c0.5-0.8,0.9-1.7,0.9-2.7c0-2.7-2.1-4.8-4.8-4.8c-1,0-2,0.3-2.8,0.9\r
+                       l-7.5-7.5c0.6-0.8,0.9-1.8,0.9-2.9c0-2.7-2.1-4.8-4.8-4.8c-2.6,0-4.8,2.2-4.8,4.8c0,2.7,2.1,4.8,4.8,4.8c1.1,0,2.1-0.4,2.9-1\r
+                       l7.5,7.5c-0.6,0.8-1,1.8-1,3c0,2.7,2.1,4.8,4.8,4.8c1.1,0,2.2-0.4,3-1.1l10.6,10.5c-0.4,0.7-0.6,1.5-0.6,2.3\r
+                       c0,1.4,0.6,2.6,1.5,3.5L30.7,60.5c-0.8-0.6-1.8-1-2.9-1c-2.6,0-4.8,2.2-4.8,4.8c0,1.1,0.4,2.1,1,2.9l-6.6,6.6\r
+                       c-0.8-0.6-1.8-1-2.9-1c-2.6,0-4.8,2.2-4.8,4.8c0,2.7,2.1,4.8,4.8,4.8c2.6,0,4.8-2.2,4.8-4.8c0-1.1-0.4-2.1-1-2.9l6.6-6.6\r
+                       c0.8,0.6,1.8,0.9,2.8,0.9c2.6,0,4.8-2.2,4.8-4.8c0-1.1-0.3-2-0.9-2.8l11.8-11.8c0.7,0.3,1.4,0.5,2.2,0.5c0.8,0,1.6-0.2,2.3-0.6\r
+                       l11.8,11.7c-0.7,0.8-1.1,1.9-1.1,3c0,2.7,2.1,4.8,4.8,4.8c1.2,0,2.2-0.4,3-1.1l7.5,7.4c-0.7,0.8-1.2,1.9-1.2,3.1\r
+                       c0,2.7,2.1,4.8,4.8,4.8s4.8-2.2,4.8-4.8C82.3,75.9,80.2,73.7,77.5,73.7z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-pool-01-active.svg b/skyquake/framework/style/img/svg/launch-fleet-pool-01-active.svg
new file mode 100644 (file)
index 0000000..b555087
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 339.3 128.7" enable-background="new 0 0 339.3 128.7" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_412_">\r
+               <path id="XMLID_413_" fill="#FFFFFF" d="M34.7,119.8h37.4V7.8H34.7V119.8z M81.5,119.8H119V7.8H81.5V119.8z M175.1,119.8h37.4V7.8\r
+                       h-37.4V119.8z M222,119.8h37.4V7.8H222V119.8z M268.8,119.8h37.4V7.8h-37.4V119.8z M322.2,108.2h-0.9v0.9h1.9v-1.9h-0.9V108.2z\r
+                        M171.5,109.1h2.8v-0.9h-2.8V109.1z M29.2,109.1H32v-0.9h-2.8V109.1z M216.4,109.1h2.8v-0.9h-2.8V109.1z M261.4,109.1h2.8v-0.9\r
+                       h-2.8V109.1z M164,109.1h2.8v-0.9H164V109.1z M74.1,109.1H77v-0.9h-2.8V109.1z M119.1,109.1h2.8v-0.9h-2.8V109.1z M126.6,109.1\r
+                       h2.8v-0.9h-2.8V109.1z M134.1,109.1h2.8v-0.9h-2.8V109.1z M156.5,109.1h2.8v-0.9h-2.8V109.1z M149,109.1h2.8v-0.9H149V109.1z\r
+                        M141.5,109.1h2.8v-0.9h-2.8V109.1z M21.7,109.1h2.8v-0.9h-2.8V109.1z M306.3,109.1h2.8v-0.9h-2.8V109.1z M313.8,109.1h2.8v-0.9\r
+                       h-2.8V109.1z M16.1,107.2h-0.9v1.9H17v-0.9h-0.9V107.2z M16.1,56.1h-0.9v2.7h0.9V56.1z M16.1,48.8h-0.9v2.7h0.9V48.8z M16.1,41.5\r
+                       h-0.9v2.7h0.9V41.5z M16.1,34.2h-0.9v2.7h0.9V34.2z M16.1,26.9h-0.9v2.7h0.9V26.9z M16.1,92.6h-0.9v2.7h0.9V92.6z M16.1,78h-0.9\r
+                       v2.7h0.9V78z M16.1,85.3h-0.9v2.7h0.9V85.3z M16.1,63.4h-0.9v2.7h0.9V63.4z M16.1,70.7h-0.9v2.7h0.9V70.7z M16.1,99.9h-0.9v2.7\r
+                       h0.9V99.9z M15.2,22.3h0.9v-0.9H17v-0.9h-1.9V22.3z M21.7,21.4h2.8v-0.9h-2.8V21.4z M159.3,20.4h-2.8v0.9h2.8V20.4z M166.8,20.4\r
+                       H164v0.9h2.8V20.4z M151.8,20.4H149v0.9h2.8V20.4z M136.9,20.4h-2.8v0.9h2.8V20.4z M144.4,20.4h-2.8v0.9h2.8V20.4z M129.4,20.4\r
+                       h-2.8v0.9h2.8V20.4z M313.8,21.4h2.8v-0.9h-2.8V21.4z M261.4,21.4h2.8v-0.9h-2.8V21.4z M171.5,21.4h2.8v-0.9h-2.8V21.4z\r
+                        M306.3,21.4h2.8v-0.9h-2.8V21.4z M216.4,21.4h2.8v-0.9h-2.8V21.4z M74.1,21.4H77v-0.9h-2.8V21.4z M119.1,21.4h2.8v-0.9h-2.8V21.4\r
+                       z M29.2,21.4H32v-0.9h-2.8V21.4z M321.3,20.4v0.9h0.9v0.9h0.9v-1.9H321.3z M322.2,44.2h0.9v-2.7h-0.9V44.2z M322.2,51.5h0.9v-2.7\r
+                       h-0.9V51.5z M322.2,36.9h0.9v-2.7h-0.9V36.9z M322.2,29.6h0.9v-2.7h-0.9V29.6z M322.2,58.8h0.9v-2.7h-0.9V58.8z M322.2,95.4h0.9\r
+                       v-2.7h-0.9V95.4z M322.2,102.7h0.9v-2.7h-0.9V102.7z M322.2,88.1h0.9v-2.7h-0.9V88.1z M322.2,73.4h0.9v-2.7h-0.9V73.4z\r
+                        M322.2,66.1h0.9v-2.7h-0.9V66.1z M322.2,80.7h0.9V78h-0.9V80.7z M126.1,99.1h42.1V28.4h-42.1V99.1z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-pool-01-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-pool-01-inactive.svg
new file mode 100644 (file)
index 0000000..c8041db
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 339.3 128.7" enable-background="new 0 0 339.3 128.7" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_412_">\r
+               <path id="XMLID_413_" fill="#CCCCCC" d="M34.7,119.8h37.4V7.8H34.7V119.8z M81.5,119.8H119V7.8H81.5V119.8z M175.1,119.8h37.4V7.8\r
+                       h-37.4V119.8z M222,119.8h37.4V7.8H222V119.8z M268.8,119.8h37.4V7.8h-37.4V119.8z M322.2,108.2h-0.9v0.9h1.9v-1.9h-0.9V108.2z\r
+                        M216.4,109.1h2.8v-0.9h-2.8V109.1z M74.1,109.1H77v-0.9h-2.8V109.1z M126.6,109.1h2.8v-0.9h-2.8V109.1z M119.1,109.1h2.8v-0.9\r
+                       h-2.8V109.1z M141.5,109.1h2.8v-0.9h-2.8V109.1z M171.5,109.1h2.8v-0.9h-2.8V109.1z M134.1,109.1h2.8v-0.9h-2.8V109.1z M149,109.1\r
+                       h2.8v-0.9H149V109.1z M164,109.1h2.8v-0.9H164V109.1z M156.5,109.1h2.8v-0.9h-2.8V109.1z M261.4,109.1h2.8v-0.9h-2.8V109.1z\r
+                        M306.3,109.1h2.8v-0.9h-2.8V109.1z M21.7,109.1h2.8v-0.9h-2.8V109.1z M29.2,109.1H32v-0.9h-2.8V109.1z M313.8,109.1h2.8v-0.9\r
+                       h-2.8V109.1z M16.1,107.2h-0.9v1.9H17v-0.9h-0.9V107.2z M16.1,41.5h-0.9v2.7h0.9V41.5z M16.1,48.8h-0.9v2.7h0.9V48.8z M16.1,26.9\r
+                       h-0.9v2.7h0.9V26.9z M16.1,56.1h-0.9v2.7h0.9V56.1z M16.1,34.2h-0.9v2.7h0.9V34.2z M16.1,92.6h-0.9v2.7h0.9V92.6z M16.1,99.9h-0.9\r
+                       v2.7h0.9V99.9z M16.1,78h-0.9v2.7h0.9V78z M16.1,85.3h-0.9v2.7h0.9V85.3z M16.1,63.4h-0.9v2.7h0.9V63.4z M16.1,70.7h-0.9v2.7h0.9\r
+                       V70.7z M15.2,22.3h0.9v-0.9H17v-0.9h-1.9V22.3z M151.8,20.4H149v0.9h2.8V20.4z M159.3,20.4h-2.8v0.9h2.8V20.4z M313.8,21.4h2.8\r
+                       v-0.9h-2.8V21.4z M144.4,20.4h-2.8v0.9h2.8V20.4z M129.4,20.4h-2.8v0.9h2.8V20.4z M21.7,21.4h2.8v-0.9h-2.8V21.4z M136.9,20.4\r
+                       h-2.8v0.9h2.8V20.4z M216.4,21.4h2.8v-0.9h-2.8V21.4z M74.1,21.4H77v-0.9h-2.8V21.4z M171.5,21.4h2.8v-0.9h-2.8V21.4z M166.8,20.4\r
+                       H164v0.9h2.8V20.4z M29.2,21.4H32v-0.9h-2.8V21.4z M119.1,21.4h2.8v-0.9h-2.8V21.4z M306.3,21.4h2.8v-0.9h-2.8V21.4z M261.4,21.4\r
+                       h2.8v-0.9h-2.8V21.4z M321.3,20.4v0.9h0.9v0.9h0.9v-1.9H321.3z M322.2,36.9h0.9v-2.7h-0.9V36.9z M322.2,29.6h0.9v-2.7h-0.9V29.6z\r
+                        M322.2,44.2h0.9v-2.7h-0.9V44.2z M322.2,95.4h0.9v-2.7h-0.9V95.4z M322.2,88.1h0.9v-2.7h-0.9V88.1z M322.2,102.7h0.9v-2.7h-0.9\r
+                       V102.7z M322.2,80.7h0.9V78h-0.9V80.7z M322.2,66.1h0.9v-2.7h-0.9V66.1z M322.2,58.8h0.9v-2.7h-0.9V58.8z M322.2,51.5h0.9v-2.7\r
+                       h-0.9V51.5z M322.2,73.4h0.9v-2.7h-0.9V73.4z M126.1,99.1h42.1V28.4h-42.1V99.1z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-pool-02-active.svg b/skyquake/framework/style/img/svg/launch-fleet-pool-02-active.svg
new file mode 100644 (file)
index 0000000..229a451
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 354.1 137.3" enable-background="new 0 0 354.1 137.3" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_466_">\r
+               <path id="XMLID_467_" fill="#FFFFFF" d="M125.9,48.9h-45v37.6h45V48.9z M225.9,48.9h-45v37.6h45V48.9z M283.4,42.2h-10V8.1h-40\r
+                       v34.1h-60V22.6h1.1v-1h-1.1V8.1h-40v13.5h-1.9v1h1.9v19.6h-60V8.1h-40v120h40v-35h60v22.5h-1.9v1h1.9v11.5h40v-11.5h1.1v-1h-1.1\r
+                       V93.1h60v35h40v-35h10v35h40V8.1h-40V42.2z M133.4,92.1h-60V43.2h60V92.1z M233.4,92.1h-60V43.2h60V92.1z M283.4,92.1h-10V43.2h10\r
+                       V92.1z M340.6,115.6h-1v1h2v-2h-1V115.6z M187.6,116.6h3v-1h-3V116.6z M195.6,116.6h3v-1h-3V116.6z M203.6,116.6h3v-1h-3V116.6z\r
+                        M227.6,116.6h3v-1h-3V116.6z M219.6,116.6h3v-1h-3V116.6z M179.6,116.6h3v-1h-3V116.6z M211.6,116.6h3v-1h-3V116.6z M107.6,116.6\r
+                       h3v-1h-3V116.6z M75.6,116.6h3v-1h-3V116.6z M27.6,116.6h3v-1h-3V116.6z M19.6,116.6h3v-1h-3V116.6z M123.6,116.6h3v-1h-3V116.6z\r
+                        M91.6,116.6h3v-1h-3V116.6z M115.6,116.6h3v-1h-3V116.6z M99.6,116.6h3v-1h-3V116.6z M275.6,116.6h3v-1h-3V116.6z M83.6,116.6h3\r
+                       v-1h-3V116.6z M331.6,116.6h3v-1h-3V116.6z M323.6,116.6h3v-1h-3V116.6z M13.6,114.6h-1v2h2v-1h-1V114.6z M13.6,91.2h-1v2.9h1\r
+                       V91.2z M13.6,99h-1v2.9h1V99z M13.6,83.3h-1v2.9h1V83.3z M13.6,36.4h-1v2.9h1V36.4z M13.6,106.8h-1v2.9h1V106.8z M13.6,44.2h-1\r
+                       v2.9h1V44.2z M13.6,28.5h-1v2.9h1V28.5z M13.6,52h-1V55h1V52z M13.6,59.8h-1v2.9h1V59.8z M13.6,67.7h-1v2.9h1V67.7z M13.6,75.5h-1\r
+                       v2.9h1V75.5z M12.6,23.6h1v-1h1v-1h-2V23.6z M198.6,21.6h-3v1h3V21.6z M206.6,21.6h-3v1h3V21.6z M182.6,21.6h-3v1h3V21.6z\r
+                        M190.6,21.6h-3v1h3V21.6z M86.6,21.6h-3v1h3V21.6z M214.6,21.6h-3v1h3V21.6z M222.6,21.6h-3v1h3V21.6z M230.6,21.6h-3v1h3V21.6z\r
+                        M94.6,21.6h-3v1h3V21.6z M102.6,21.6h-3v1h3V21.6z M78.6,21.6h-3v1h3V21.6z M126.6,21.6h-3v1h3V21.6z M118.6,21.6h-3v1h3V21.6z\r
+                        M110.6,21.6h-3v1h3V21.6z M278.6,21.6h-3v1h3V21.6z M27.6,22.6h3v-1h-3V22.6z M331.6,22.6h3v-1h-3V22.6z M323.6,22.6h3v-1h-3\r
+                       V22.6z M19.6,22.6h3v-1h-3V22.6z M339.6,21.6v1h1v1h1v-2H339.6z M340.6,47.1h1v-2.9h-1V47.1z M340.6,109.7h1v-2.9h-1V109.7z\r
+                        M340.6,31.5h1v-2.9h-1V31.5z M340.6,39.3h1v-2.9h-1V39.3z M340.6,55h1V52h-1V55z M340.6,78.4h1v-2.9h-1V78.4z M340.6,62.8h1v-2.9\r
+                       h-1V62.8z M340.6,70.6h1v-2.9h-1V70.6z M340.6,94.1h1v-2.9h-1V94.1z M340.6,86.3h1v-2.9h-1V86.3z M340.6,101.9h1V99h-1V101.9z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launch-fleet-pool-02-inactive.svg b/skyquake/framework/style/img/svg/launch-fleet-pool-02-inactive.svg
new file mode 100644 (file)
index 0000000..4e45a01
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 354.1 137.3" enable-background="new 0 0 354.1 137.3" xml:space="preserve">\r
+<g>\r
+       <g id="XMLID_440_">\r
+               <path id="XMLID_441_" fill="#CCCCCC" d="M125.9,48.9h-45v37.6h45V48.9z M225.9,48.9h-45v37.6h45V48.9z M283.4,42.2h-10V8.1h-40\r
+                       v34.1h-60V22.6h1.1v-1h-1.1V8.1h-40v13.5h-1.9v1h1.9v19.6h-60V8.1h-40v120h40v-35h60v22.5h-1.9v1h1.9v11.5h40v-11.5h1.1v-1h-1.1\r
+                       V93.1h60v35h40v-35h10v35h40V8.1h-40V42.2z M133.4,92.1h-60V43.2h60V92.1z M233.4,92.1h-60V43.2h60V92.1z M283.4,92.1h-10V43.2h10\r
+                       V92.1z M340.6,115.6h-1v1h2v-2h-1V115.6z M275.6,116.6h3v-1h-3V116.6z M203.6,116.6h3v-1h-3V116.6z M323.6,116.6h3v-1h-3V116.6z\r
+                        M219.6,116.6h3v-1h-3V116.6z M227.6,116.6h3v-1h-3V116.6z M331.6,116.6h3v-1h-3V116.6z M75.6,116.6h3v-1h-3V116.6z M83.6,116.6h3\r
+                       v-1h-3V116.6z M91.6,116.6h3v-1h-3V116.6z M211.6,116.6h3v-1h-3V116.6z M195.6,116.6h3v-1h-3V116.6z M99.6,116.6h3v-1h-3V116.6z\r
+                        M27.6,116.6h3v-1h-3V116.6z M19.6,116.6h3v-1h-3V116.6z M187.6,116.6h3v-1h-3V116.6z M179.6,116.6h3v-1h-3V116.6z M123.6,116.6h3\r
+                       v-1h-3V116.6z M107.6,116.6h3v-1h-3V116.6z M115.6,116.6h3v-1h-3V116.6z M13.6,114.6h-1v2h2v-1h-1V114.6z M13.6,91.2h-1v2.9h1\r
+                       V91.2z M13.6,83.3h-1v2.9h1V83.3z M13.6,99h-1v2.9h1V99z M13.6,106.8h-1v2.9h1V106.8z M13.6,28.5h-1v2.9h1V28.5z M13.6,75.5h-1\r
+                       v2.9h1V75.5z M13.6,59.8h-1v2.9h1V59.8z M13.6,67.7h-1v2.9h1V67.7z M13.6,36.4h-1v2.9h1V36.4z M13.6,44.2h-1v2.9h1V44.2z M13.6,52\r
+                       h-1V55h1V52z M12.6,23.6h1v-1h1v-1h-2V23.6z M278.6,21.6h-3v1h3V21.6z M198.6,21.6h-3v1h3V21.6z M118.6,21.6h-3v1h3V21.6z\r
+                        M110.6,21.6h-3v1h3V21.6z M126.6,21.6h-3v1h3V21.6z M230.6,21.6h-3v1h3V21.6z M182.6,21.6h-3v1h3V21.6z M94.6,21.6h-3v1h3V21.6z\r
+                        M102.6,21.6h-3v1h3V21.6z M78.6,21.6h-3v1h3V21.6z M222.6,21.6h-3v1h3V21.6z M214.6,21.6h-3v1h3V21.6z M190.6,21.6h-3v1h3V21.6z\r
+                        M206.6,21.6h-3v1h3V21.6z M86.6,21.6h-3v1h3V21.6z M19.6,22.6h3v-1h-3V22.6z M331.6,22.6h3v-1h-3V22.6z M323.6,22.6h3v-1h-3V22.6\r
+                       z M27.6,22.6h3v-1h-3V22.6z M339.6,21.6v1h1v1h1v-2H339.6z M340.6,47.1h1v-2.9h-1V47.1z M340.6,55h1V52h-1V55z M340.6,31.5h1v-2.9\r
+                       h-1V31.5z M340.6,39.3h1v-2.9h-1V39.3z M340.6,62.8h1v-2.9h-1V62.8z M340.6,101.9h1V99h-1V101.9z M340.6,109.7h1v-2.9h-1V109.7z\r
+                        M340.6,94.1h1v-2.9h-1V94.1z M340.6,86.3h1v-2.9h-1V86.3z M340.6,70.6h1v-2.9h-1V70.6z M340.6,78.4h1v-2.9h-1V78.4z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launchpad-icn-create-environment-large.svg b/skyquake/framework/style/img/svg/launchpad-icn-create-environment-large.svg
new file mode 100644 (file)
index 0000000..f1ef102
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 98.7 98" enable-background="new 0 0 98.7 98" xml:space="preserve">\r
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M45.8,4.5h2v84h-2V4.5z"/>\r
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M4.8,45.5h84v2h-84V45.5z"/>\r
+<polygon id="XMLID_4_" opacity="0.15" fill-rule="evenodd" clip-rule="evenodd" fill="#333333" points="92.8,47.5 51.8,47.5 \r
+       51.8,8.5 47.8,8.5 47.8,47.5 8.8,47.5 8.8,51.5 47.8,51.5 47.8,92.5 51.8,92.5 51.8,51.5 92.8,51.5 "/>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launchpad-icn-newTab.svg b/skyquake/framework/style/img/svg/launchpad-icn-newTab.svg
new file mode 100644 (file)
index 0000000..ab00cfa
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 43 46.4" enable-background="new 0 0 43 46.4" xml:space="preserve">\r
+<g>\r
+       <path fill="#FFFFFF" d="M27.5,15.9v12h-12v-12H27.5 M29.5,13.9h-16v16h16V13.9L29.5,13.9z"/>\r
+</g>\r
+<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" d="M22.5,34.9\r
+       h-14v-14"/>\r
+<path opacity="0.15" fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M12.5,35.9h15v4h-15V35.9z"/>\r
+<path opacity="0.15" fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M17.5,29.9h12v4h-12V29.9z"/>\r
+<path opacity="0.15" fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M29.5,17.9h4v16h-4V17.9z"/>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launchpad-icn-play.svg b/skyquake/framework/style/img/svg/launchpad-icn-play.svg
new file mode 100644 (file)
index 0000000..696e698
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 31.3 31.3" enable-background="new 0 0 31.3 31.3" xml:space="preserve">\r
+<g id="XMLID_1_">\r
+       <path id="XMLID_20_" fill="#FFFFFF" d="M9.2,8.9l10.2,6.7L9.2,21.6V8.9 M7.2,5.2v20l16-9.5L7.2,5.2L7.2,5.2z"/>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/launchpad-icn-sliders.svg b/skyquake/framework/style/img/svg/launchpad-icn-sliders.svg
new file mode 100644 (file)
index 0000000..103c9ba
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        viewBox="0 0 33.4 32.4" enable-background="new 0 0 33.4 32.4" xml:space="preserve">\r
+<g>\r
+       <g>\r
+               <path fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M24.7,8.7h-1.5v-2c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1v2h-1.5\r
+                       c-0.8,0-1.5,0.7-1.5,1.5c0,0.8,0.7,1.5,1.5,1.5h1.5v14c0,0.6,0.4,1,1,1c0.6,0,1-0.4,1-1v-14h1.5c0.8,0,1.5-0.7,1.5-1.5\r
+                       C26.2,9.4,25.5,8.7,24.7,8.7z M14.7,19.7h-1.5v-13c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1v13H9.7c-0.8,0-1.5,0.7-1.5,1.5\r
+                       c0,0.8,0.7,1.5,1.5,1.5h1.5v3c0,0.6,0.4,1,1,1c0.6,0,1-0.4,1-1v-3h1.5c0.8,0,1.5-0.7,1.5-1.5C16.2,20.4,15.5,19.7,14.7,19.7z"/>\r
+       </g>\r
+</g>\r
+</svg>\r
diff --git a/skyquake/framework/style/img/svg/riftio_logo.svg b/skyquake/framework/style/img/svg/riftio_logo.svg
new file mode 100644 (file)
index 0000000..d2955f4
--- /dev/null
@@ -0,0 +1 @@
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" x="0px" y="0px" width="117.272px" height="79.447px" viewBox="0 0 117.272 79.447" style="enable-background:new 0 0 117.272 79.447;" xml:space="preserve"><defs></defs><path id="XMLID_2_" style="fill:#0080C8;" d="M87.178,46.6c-0.262-0.379-0.536-0.75-0.822-1.112c-0.143-0.181-0.29-0.359-0.439-0.535c-0.299-0.352-0.609-0.694-0.932-1.027c-0.161-0.166-0.325-0.33-0.492-0.491c-0.167-0.161-0.337-0.319-0.509-0.475c-1.208-1.089-2.552-2.045-4.016-2.842c0.008-0.222,0.012-0.443,0.012-0.663c0-10.05-8.176-18.227-18.227-18.227c-2.779,0-5.462,0.615-7.909,1.799c-1.498-2.115-3.31-3.944-5.356-5.436c-0.898,1.836-1.404,3.898-1.404,6.076c0,0.491,0.032,0.98,0.083,1.467c1.043,1.139,1.944,2.43,2.668,3.855l1.766,3.476l3.112-2.35c0.255-0.193,0.516-0.374,0.783-0.544c0.4-0.255,0.813-0.484,1.237-0.686c0.424-0.202,0.859-0.378,1.303-0.527c0.296-0.099,0.596-0.186,0.9-0.261c0.456-0.112,0.919-0.197,1.389-0.254c0.47-0.057,0.946-0.085,1.427-0.085c2.016,0,3.914,0.512,5.571,1.414c0.331,0.18,0.653,0.376,0.965,0.587c0.778,0.526,1.49,1.143,2.119,1.836c0.252,0.277,0.491,0.566,0.716,0.867c0.337,0.451,0.643,0.926,0.913,1.423c0.18,0.331,0.345,0.673,0.493,1.022c0.148,0.35,0.28,0.708,0.394,1.074c0.057,0.183,0.11,0.368,0.158,0.555c0.096,0.373,0.175,0.754,0.234,1.141c0.089,0.58,0.135,1.174,0.135,1.779c0,0.673-0.062,1.365-0.184,2.056l-0.462,2.613l2.463,0.986c0.645,0.258,1.264,0.559,1.853,0.897c0.196,0.113,0.39,0.23,0.579,0.351c0.455,0.291,0.892,0.605,1.307,0.941c0.277,0.224,0.545,0.457,0.803,0.7c0.258,0.242,0.507,0.494,0.746,0.754c0.358,0.39,0.694,0.799,1.006,1.224c1.404,1.917,2.324,4.179,2.644,6.606c0.083,0.628,0.128,1.267,0.128,1.915c0,0.455-0.022,0.905-0.064,1.35c-0.226,2.383-1.044,4.61-2.305,6.529c-0.808,1.229-1.797,2.332-2.932,3.265c-2.189,1.798-4.913,2.97-7.903,3.219l-5.312,0.056H25.045l-5.311-0.056C12.321,72.245,6.529,65.956,6.529,58.5c0-1.314,0.181-2.6,0.523-3.83c0.098-0.351,0.208-0.698,0.332-1.04c0.494-1.366,1.19-2.648,2.058-3.802c0.217-0.288,0.445-0.569,0.683-0.841c0.119-0.136,0.241-0.27,0.365-0.401c0.372-0.394,0.768-0.768,1.184-1.12c0.555-0.469,1.147-0.897,1.773-1.28c0.156-0.096,0.315-0.189,0.476-0.279c0.321-0.18,0.651-0.348,0.988-0.504c0.169-0.078,0.339-0.153,0.511-0.224c0.172-0.072,0.346-0.14,0.522-0.205l2.773-1.027l-0.748-2.861c-0.37-1.416-0.558-2.879-0.558-4.35c0-9.378,7.572-17.016,16.922-17.133c0.344-2.263,0.971-4.435,1.844-6.478c-0.539-0.036-1.081-0.057-1.627-0.057c-13.05,0-23.668,10.617-23.668,23.668c0,1.095,0.076,2.188,0.226,3.27C4.367,43.606,0,50.724,0,58.5c0,5.314,1.994,10.381,5.613,14.267c2.475,2.657,5.552,4.597,8.94,5.681c0.616,0.197,1.242,0.366,1.877,0.505c0.317,0.07,0.637,0.132,0.958,0.187c0.643,0.11,1.294,0.191,1.95,0.241l5.654,0.066l40.858,0l5.458-0.058l0.213-0.009c0.656-0.05,1.307-0.13,1.95-0.241c0.321-0.055,0.641-0.117,0.958-0.187c0.635-0.139,1.261-0.308,1.877-0.505c3.388-1.083,6.466-3.024,8.94-5.681c0.906-0.972,1.709-2.019,2.406-3.124c0.655-1.039,1.21-2.133,1.67-3.265c0.839-2.067,1.345-4.268,1.489-6.529c0.029-0.448,0.048-0.898,0.048-1.35c0-0.644-0.032-1.283-0.089-1.915C90.445,52.933,89.186,49.511,87.178,46.6z"/><path id="XMLID_1_" style="fill:#135296;" d="M106.378,27.051c0.008-0.222,0.012-0.443,0.012-0.663c0-10.05-8.176-18.227-18.227-18.227c-2.779,0-5.462,0.615-7.909,1.799C75.853,3.743,68.733,0,60.959,0c-1.414,0-2.8,0.125-4.147,0.364c-2.02,0.359-3.952,0.975-5.762,1.813c-0.201,0.093-0.401,0.189-0.599,0.287c-0.167,0.083-0.332,0.168-0.497,0.255c-0.882,0.465-1.732,0.984-2.544,1.554c-0.09,0.063-0.179,0.126-0.268,0.19c-0.23,0.166-0.458,0.336-0.682,0.511c-0.064,0.05-0.128,0.1-0.191,0.15c-1.888,1.498-3.542,3.278-4.9,5.275c-0.688,1.012-1.298,2.08-1.825,3.195c-0.116,0.245-0.227,0.492-0.335,0.742c-0.752,1.746-1.3,3.6-1.613,5.532c-0.187,1.156-0.29,2.339-0.303,3.544c-0.001,0.085-0.003,0.171-0.003,0.256c0,1.095,0.076,2.188,0.226,3.27c-6.741,3.6-11.108,10.718-11.108,18.494c0,1.661,0.195,3.297,0.573,4.881c0.832,3.485,2.552,6.715,5.04,9.386c0.264,0.284,0.536,0.559,0.813,0.826c1.944,1.87,4.209,3.328,6.67,4.322c0.69,0.279,1.396,0.522,2.115,0.726c0.168,0.048,0.336,0.094,0.505,0.137c0.205,0.053,0.411,0.102,0.617,0.149c0.377,0.085,0.756,0.158,1.139,0.222c0.247,0.041,0.495,0.08,0.744,0.112c0.372,0.049,0.746,0.09,1.123,0.119l5.654,0.066l25.984,0c1.787-1.7,3.001-3.991,3.322-6.529H51.455l-5.311-0.056c-1.158-0.096-2.277-0.331-3.34-0.688c-0.851-0.285-1.666-0.648-2.437-1.079c-0.193-0.108-0.383-0.22-0.57-0.336c-0.375-0.233-0.738-0.482-1.088-0.747c-1.052-0.795-1.992-1.729-2.793-2.774c-0.534-0.697-1.005-1.442-1.407-2.228c-1.004-1.965-1.57-4.181-1.57-6.511c0-6.006,3.783-11.442,9.414-13.526l2.773-1.027l-0.748-2.861c-0.078-0.298-0.146-0.599-0.208-0.901c-0.173-0.849-0.284-1.712-0.328-2.58c-0.015-0.289-0.022-0.579-0.022-0.869c0-0.222,0.006-0.443,0.015-0.663s0.024-0.439,0.04-0.657c0.178-2.325,0.821-4.52,1.838-6.495c0.544-1.057,1.193-2.052,1.936-2.967c3.145-3.874,7.942-6.356,13.309-6.356c4.054,0,7.862,1.406,10.866,3.874c1.202,0.987,2.275,2.145,3.184,3.451c0.114,0.163,0.225,0.329,0.333,0.497c0.325,0.503,0.627,1.027,0.903,1.57l1.766,3.476l3.112-2.35c2.041-1.542,4.476-2.357,7.04-2.357c0.266,0,0.531,0.009,0.793,0.027c1.31,0.089,2.561,0.395,3.719,0.881c0.463,0.195,0.911,0.418,1.342,0.668c0.128,0.074,0.254,0.15,0.378,0.229c0.41,0.259,0.803,0.543,1.177,0.85c0.374,0.307,0.728,0.636,1.061,0.986c0.167,0.175,0.328,0.355,0.483,0.54c1.089,1.294,1.904,2.827,2.352,4.508c0.256,0.96,0.393,1.969,0.393,3.009c0,0.673-0.062,1.365-0.184,2.056l-0.462,2.613l0.986,0.395l1.477,0.591c0.264,0.106,0.522,0.22,0.776,0.34c0.163,0.076,0.324,0.155,0.483,0.237c0.15,0.077,0.298,0.157,0.445,0.238c0.353,0.197,0.695,0.407,1.027,0.631c0.092,0.062,0.183,0.124,0.273,0.188c3.526,2.494,5.768,6.454,6.035,10.865c0.018,0.294,0.027,0.59,0.027,0.888c0,1.207-0.152,2.383-0.438,3.51c-0.858,3.379-2.923,6.311-5.717,8.281c-0.113,0.079-0.227,0.157-0.342,0.233c-0.4,0.266-0.815,0.511-1.242,0.737c-0.196,0.103-0.394,0.202-0.594,0.296c-0.178,0.084-0.358,0.164-0.54,0.24c-0.251,0.106-0.506,0.204-0.764,0.296c-1.131,0.401-2.326,0.667-3.568,0.77l-3.178,0.034c-0.121,2.247-0.544,4.446-1.255,6.543l4.614-0.049l0.213-0.009c0.328-0.025,0.655-0.058,0.98-0.098c1.95-0.241,3.84-0.752,5.621-1.51c2.672-1.138,5.1-2.832,7.125-5.006c2.489-2.672,4.209-5.902,5.04-9.386c0.378-1.584,0.573-3.22,0.573-4.881C117.272,37.665,113.069,30.694,106.378,27.051z"/></svg>
diff --git a/skyquake/framework/style/img/svg/riftio_logo_white.svg b/skyquake/framework/style/img/svg/riftio_logo_white.svg
new file mode 100644 (file)
index 0000000..d456d76
--- /dev/null
@@ -0,0 +1 @@
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" x="0px" y="0px" width="117.272px" height="79.447px" viewBox="0 0 117.272 79.447" style="enable-background:new 0 0 117.272 79.447;" xml:space="preserve"><defs></defs><path id="XMLID_2_" style="fill:#fff;" d="M87.178,46.6c-0.262-0.379-0.536-0.75-0.822-1.112c-0.143-0.181-0.29-0.359-0.439-0.535c-0.299-0.352-0.609-0.694-0.932-1.027c-0.161-0.166-0.325-0.33-0.492-0.491c-0.167-0.161-0.337-0.319-0.509-0.475c-1.208-1.089-2.552-2.045-4.016-2.842c0.008-0.222,0.012-0.443,0.012-0.663c0-10.05-8.176-18.227-18.227-18.227c-2.779,0-5.462,0.615-7.909,1.799c-1.498-2.115-3.31-3.944-5.356-5.436c-0.898,1.836-1.404,3.898-1.404,6.076c0,0.491,0.032,0.98,0.083,1.467c1.043,1.139,1.944,2.43,2.668,3.855l1.766,3.476l3.112-2.35c0.255-0.193,0.516-0.374,0.783-0.544c0.4-0.255,0.813-0.484,1.237-0.686c0.424-0.202,0.859-0.378,1.303-0.527c0.296-0.099,0.596-0.186,0.9-0.261c0.456-0.112,0.919-0.197,1.389-0.254c0.47-0.057,0.946-0.085,1.427-0.085c2.016,0,3.914,0.512,5.571,1.414c0.331,0.18,0.653,0.376,0.965,0.587c0.778,0.526,1.49,1.143,2.119,1.836c0.252,0.277,0.491,0.566,0.716,0.867c0.337,0.451,0.643,0.926,0.913,1.423c0.18,0.331,0.345,0.673,0.493,1.022c0.148,0.35,0.28,0.708,0.394,1.074c0.057,0.183,0.11,0.368,0.158,0.555c0.096,0.373,0.175,0.754,0.234,1.141c0.089,0.58,0.135,1.174,0.135,1.779c0,0.673-0.062,1.365-0.184,2.056l-0.462,2.613l2.463,0.986c0.645,0.258,1.264,0.559,1.853,0.897c0.196,0.113,0.39,0.23,0.579,0.351c0.455,0.291,0.892,0.605,1.307,0.941c0.277,0.224,0.545,0.457,0.803,0.7c0.258,0.242,0.507,0.494,0.746,0.754c0.358,0.39,0.694,0.799,1.006,1.224c1.404,1.917,2.324,4.179,2.644,6.606c0.083,0.628,0.128,1.267,0.128,1.915c0,0.455-0.022,0.905-0.064,1.35c-0.226,2.383-1.044,4.61-2.305,6.529c-0.808,1.229-1.797,2.332-2.932,3.265c-2.189,1.798-4.913,2.97-7.903,3.219l-5.312,0.056H25.045l-5.311-0.056C12.321,72.245,6.529,65.956,6.529,58.5c0-1.314,0.181-2.6,0.523-3.83c0.098-0.351,0.208-0.698,0.332-1.04c0.494-1.366,1.19-2.648,2.058-3.802c0.217-0.288,0.445-0.569,0.683-0.841c0.119-0.136,0.241-0.27,0.365-0.401c0.372-0.394,0.768-0.768,1.184-1.12c0.555-0.469,1.147-0.897,1.773-1.28c0.156-0.096,0.315-0.189,0.476-0.279c0.321-0.18,0.651-0.348,0.988-0.504c0.169-0.078,0.339-0.153,0.511-0.224c0.172-0.072,0.346-0.14,0.522-0.205l2.773-1.027l-0.748-2.861c-0.37-1.416-0.558-2.879-0.558-4.35c0-9.378,7.572-17.016,16.922-17.133c0.344-2.263,0.971-4.435,1.844-6.478c-0.539-0.036-1.081-0.057-1.627-0.057c-13.05,0-23.668,10.617-23.668,23.668c0,1.095,0.076,2.188,0.226,3.27C4.367,43.606,0,50.724,0,58.5c0,5.314,1.994,10.381,5.613,14.267c2.475,2.657,5.552,4.597,8.94,5.681c0.616,0.197,1.242,0.366,1.877,0.505c0.317,0.07,0.637,0.132,0.958,0.187c0.643,0.11,1.294,0.191,1.95,0.241l5.654,0.066l40.858,0l5.458-0.058l0.213-0.009c0.656-0.05,1.307-0.13,1.95-0.241c0.321-0.055,0.641-0.117,0.958-0.187c0.635-0.139,1.261-0.308,1.877-0.505c3.388-1.083,6.466-3.024,8.94-5.681c0.906-0.972,1.709-2.019,2.406-3.124c0.655-1.039,1.21-2.133,1.67-3.265c0.839-2.067,1.345-4.268,1.489-6.529c0.029-0.448,0.048-0.898,0.048-1.35c0-0.644-0.032-1.283-0.089-1.915C90.445,52.933,89.186,49.511,87.178,46.6z"/><path id="XMLID_1_" style="fill:#fff;" d="M106.378,27.051c0.008-0.222,0.012-0.443,0.012-0.663c0-10.05-8.176-18.227-18.227-18.227c-2.779,0-5.462,0.615-7.909,1.799C75.853,3.743,68.733,0,60.959,0c-1.414,0-2.8,0.125-4.147,0.364c-2.02,0.359-3.952,0.975-5.762,1.813c-0.201,0.093-0.401,0.189-0.599,0.287c-0.167,0.083-0.332,0.168-0.497,0.255c-0.882,0.465-1.732,0.984-2.544,1.554c-0.09,0.063-0.179,0.126-0.268,0.19c-0.23,0.166-0.458,0.336-0.682,0.511c-0.064,0.05-0.128,0.1-0.191,0.15c-1.888,1.498-3.542,3.278-4.9,5.275c-0.688,1.012-1.298,2.08-1.825,3.195c-0.116,0.245-0.227,0.492-0.335,0.742c-0.752,1.746-1.3,3.6-1.613,5.532c-0.187,1.156-0.29,2.339-0.303,3.544c-0.001,0.085-0.003,0.171-0.003,0.256c0,1.095,0.076,2.188,0.226,3.27c-6.741,3.6-11.108,10.718-11.108,18.494c0,1.661,0.195,3.297,0.573,4.881c0.832,3.485,2.552,6.715,5.04,9.386c0.264,0.284,0.536,0.559,0.813,0.826c1.944,1.87,4.209,3.328,6.67,4.322c0.69,0.279,1.396,0.522,2.115,0.726c0.168,0.048,0.336,0.094,0.505,0.137c0.205,0.053,0.411,0.102,0.617,0.149c0.377,0.085,0.756,0.158,1.139,0.222c0.247,0.041,0.495,0.08,0.744,0.112c0.372,0.049,0.746,0.09,1.123,0.119l5.654,0.066l25.984,0c1.787-1.7,3.001-3.991,3.322-6.529H51.455l-5.311-0.056c-1.158-0.096-2.277-0.331-3.34-0.688c-0.851-0.285-1.666-0.648-2.437-1.079c-0.193-0.108-0.383-0.22-0.57-0.336c-0.375-0.233-0.738-0.482-1.088-0.747c-1.052-0.795-1.992-1.729-2.793-2.774c-0.534-0.697-1.005-1.442-1.407-2.228c-1.004-1.965-1.57-4.181-1.57-6.511c0-6.006,3.783-11.442,9.414-13.526l2.773-1.027l-0.748-2.861c-0.078-0.298-0.146-0.599-0.208-0.901c-0.173-0.849-0.284-1.712-0.328-2.58c-0.015-0.289-0.022-0.579-0.022-0.869c0-0.222,0.006-0.443,0.015-0.663s0.024-0.439,0.04-0.657c0.178-2.325,0.821-4.52,1.838-6.495c0.544-1.057,1.193-2.052,1.936-2.967c3.145-3.874,7.942-6.356,13.309-6.356c4.054,0,7.862,1.406,10.866,3.874c1.202,0.987,2.275,2.145,3.184,3.451c0.114,0.163,0.225,0.329,0.333,0.497c0.325,0.503,0.627,1.027,0.903,1.57l1.766,3.476l3.112-2.35c2.041-1.542,4.476-2.357,7.04-2.357c0.266,0,0.531,0.009,0.793,0.027c1.31,0.089,2.561,0.395,3.719,0.881c0.463,0.195,0.911,0.418,1.342,0.668c0.128,0.074,0.254,0.15,0.378,0.229c0.41,0.259,0.803,0.543,1.177,0.85c0.374,0.307,0.728,0.636,1.061,0.986c0.167,0.175,0.328,0.355,0.483,0.54c1.089,1.294,1.904,2.827,2.352,4.508c0.256,0.96,0.393,1.969,0.393,3.009c0,0.673-0.062,1.365-0.184,2.056l-0.462,2.613l0.986,0.395l1.477,0.591c0.264,0.106,0.522,0.22,0.776,0.34c0.163,0.076,0.324,0.155,0.483,0.237c0.15,0.077,0.298,0.157,0.445,0.238c0.353,0.197,0.695,0.407,1.027,0.631c0.092,0.062,0.183,0.124,0.273,0.188c3.526,2.494,5.768,6.454,6.035,10.865c0.018,0.294,0.027,0.59,0.027,0.888c0,1.207-0.152,2.383-0.438,3.51c-0.858,3.379-2.923,6.311-5.717,8.281c-0.113,0.079-0.227,0.157-0.342,0.233c-0.4,0.266-0.815,0.511-1.242,0.737c-0.196,0.103-0.394,0.202-0.594,0.296c-0.178,0.084-0.358,0.164-0.54,0.24c-0.251,0.106-0.506,0.204-0.764,0.296c-1.131,0.401-2.326,0.667-3.568,0.77l-3.178,0.034c-0.121,2.247-0.544,4.446-1.255,6.543l4.614-0.049l0.213-0.009c0.328-0.025,0.655-0.058,0.98-0.098c1.95-0.241,3.84-0.752,5.621-1.51c2.672-1.138,5.1-2.832,7.125-5.006c2.489-2.672,4.209-5.902,5.04-9.386c0.378-1.584,0.573-3.22,0.573-4.881C117.272,37.665,113.069,30.694,106.378,27.051z"/></svg>
diff --git a/skyquake/framework/style/img/switch-icon.png b/skyquake/framework/style/img/switch-icon.png
new file mode 100644 (file)
index 0000000..88a7715
Binary files /dev/null and b/skyquake/framework/style/img/switch-icon.png differ
diff --git a/skyquake/framework/style/img/table-cell-bg.png b/skyquake/framework/style/img/table-cell-bg.png
new file mode 100644 (file)
index 0000000..8f4c8a8
Binary files /dev/null and b/skyquake/framework/style/img/table-cell-bg.png differ
diff --git a/skyquake/framework/style/img/traffic-sim-diagram.png b/skyquake/framework/style/img/traffic-sim-diagram.png
new file mode 100644 (file)
index 0000000..db63b6e
Binary files /dev/null and b/skyquake/framework/style/img/traffic-sim-diagram.png differ
diff --git a/skyquake/framework/style/img/tunnels.png b/skyquake/framework/style/img/tunnels.png
new file mode 100644 (file)
index 0000000..b4fe6d9
Binary files /dev/null and b/skyquake/framework/style/img/tunnels.png differ
diff --git a/skyquake/framework/style/img/viewport-dash-temp.png b/skyquake/framework/style/img/viewport-dash-temp.png
new file mode 100644 (file)
index 0000000..0690c8e
Binary files /dev/null and b/skyquake/framework/style/img/viewport-dash-temp.png differ
diff --git a/skyquake/framework/style/img/viewport-dash-v2-temp.png b/skyquake/framework/style/img/viewport-dash-v2-temp.png
new file mode 100644 (file)
index 0000000..144bdc3
Binary files /dev/null and b/skyquake/framework/style/img/viewport-dash-v2-temp.png differ
diff --git a/skyquake/framework/style/img/viewport-dash-v3-temp.png b/skyquake/framework/style/img/viewport-dash-v3-temp.png
new file mode 100644 (file)
index 0000000..cbdfd6e
Binary files /dev/null and b/skyquake/framework/style/img/viewport-dash-v3-temp.png differ
diff --git a/skyquake/framework/style/img/viewport-nav-bottom.png b/skyquake/framework/style/img/viewport-nav-bottom.png
new file mode 100644 (file)
index 0000000..d9f7669
Binary files /dev/null and b/skyquake/framework/style/img/viewport-nav-bottom.png differ
diff --git a/skyquake/framework/style/img/viewport-nav-center.png b/skyquake/framework/style/img/viewport-nav-center.png
new file mode 100644 (file)
index 0000000..2edeb3f
Binary files /dev/null and b/skyquake/framework/style/img/viewport-nav-center.png differ
diff --git a/skyquake/framework/style/img/viewport-nav-left.png b/skyquake/framework/style/img/viewport-nav-left.png
new file mode 100644 (file)
index 0000000..9b017de
Binary files /dev/null and b/skyquake/framework/style/img/viewport-nav-left.png differ
diff --git a/skyquake/framework/style/img/viewport-nav-right.png b/skyquake/framework/style/img/viewport-nav-right.png
new file mode 100644 (file)
index 0000000..5fc43b4
Binary files /dev/null and b/skyquake/framework/style/img/viewport-nav-right.png differ
diff --git a/skyquake/framework/style/img/viewport-nav-top.png b/skyquake/framework/style/img/viewport-nav-top.png
new file mode 100644 (file)
index 0000000..7c0717d
Binary files /dev/null and b/skyquake/framework/style/img/viewport-nav-top.png differ
diff --git a/skyquake/framework/style/img/viewport-platform-temp.png b/skyquake/framework/style/img/viewport-platform-temp.png
new file mode 100644 (file)
index 0000000..cbdfd6e
Binary files /dev/null and b/skyquake/framework/style/img/viewport-platform-temp.png differ
diff --git a/skyquake/framework/style/img/viewport-sla-graph.svg b/skyquake/framework/style/img/viewport-sla-graph.svg
new file mode 100644 (file)
index 0000000..cd120cc
--- /dev/null
@@ -0,0 +1,45 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="176" height="176" viewBox="0 0 176 176">
+  <defs>
+    <style>
+
+      .cls-3 {
+        stroke: #7cc118;
+        stroke-width: 16px;
+        fill: none;
+      }
+
+      .cls-4 {
+        font-size: 48px;
+      }
+
+      .cls-5 {
+        fill: #333333;
+        font-size: 48px;
+        font-family: "Roboto-Light";
+      }
+
+      .cls-6 {
+        font-size: 14px;
+      }
+
+      .cls-7 {
+        fill: #333333;
+        font-size: 14px;
+        font-family: "Roboto-Bold";
+        font-weight: bold;
+      }
+
+      .cls-8 {
+        fill: #ffffff;
+        stroke: #bcbec0;
+        stroke-width: 1px;
+      }
+    </style>
+  </defs>
+  <g id="circle-chart">
+    <circle id="circle-1" class="cls-3" cx="88" cy="88" r="80"/>
+    <text class="cls-4" x="45px" y="105px"><tspan class="cls-5">100</tspan></text>
+    <text class="cls-6" x="121px" y="104px"><tspan class="cls-7">%</tspan></text>
+    <path d="M85.500,0.500 C85.500,0.500 75.500,0.500 75.500,0.500 C75.500,0.500 75.500,31.500 75.500,31.500 C75.500,31.500 80.500,37.500 80.500,37.500 C80.500,37.500 85.500,30.500 85.500,30.500 C85.500,30.500 85.500,0.500 85.500,0.500 Z" id="path-1" class="cls-8" fill-rule="evenodd"/>
+  </g>
+</svg>
diff --git a/skyquake/framework/style/img/viewport-vim-temp.png b/skyquake/framework/style/img/viewport-vim-temp.png
new file mode 100644 (file)
index 0000000..0f8709f
Binary files /dev/null and b/skyquake/framework/style/img/viewport-vim-temp.png differ
diff --git a/skyquake/framework/style/img/viewport-vnf-10.svg b/skyquake/framework/style/img/viewport-vnf-10.svg
new file mode 100644 (file)
index 0000000..4b7c77c
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="232" height="212" viewBox="0 0 232 212">
+  <image xlink:href="data:img/png;base64,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" width="232" height="212"/>
+</svg>
diff --git a/skyquake/framework/style/img/viewport-vnf-50.svg b/skyquake/framework/style/img/viewport-vnf-50.svg
new file mode 100644 (file)
index 0000000..895fff8
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="232" height="212" viewBox="0 0 232 212">
+  <image xlink:href="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOgAAADUCAYAAACWEW+uAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsSAAALEgHS3X78AAArUElEQVR42u2deZwUxfn/P1XdM7OzB7CzIAuKXIIaNR7jgVEMKkK+XjFm0ASPqFE8QaMo+/P4mlPBK4rGCCoazyCdxOubmLBBEo3xGu8DF1lQFJBdes+5u7t+f3QPO7vMzM7V1bO79X695iXb01NPVTufqeup5wEEg5rGNWulxjVrZafrISgM8T9uANO4Zu1EAI8CqALgAlCd8l8ZQI1163QArzpdX0H+CIEObKq9Xu8xB+y3LwihkCQJhBLIkgRCCCRJQvCd99De0eF0PQUFIgQ6wJEoRU1NTfEFCcoS6nQFBFwgTldAUBhCoIMdU5rDnK6GoDDEELccUdTdAOyZ8hoDwAegDsBI69/VF3dERjxZtSVrUbIk4+fhCS9UvdAalyhiMmURiSIkUdYuUfa1RNEsU/axRPEBIfiw6ej6sNPNF/QgBOoUiuoBsC+AfQB8y/r3vgD2AuDJpQgjx5FrQgcJJajHKje1Nz0k9T5CgMrnW+MVLqa6ZfalS2IfuyT2qizh2aaj61WnH9lQRAiUB4oqAdgPwGHWyw/gIJTZ82cMCMepOxxHPYB6AIcDOJ8QPFz1Qmu00m1s9rjYu26JvSRLeLrp6Pqo03Ue7JTVF2TQYAryYAAzrNd0DOB5IGNAKEYrQjE6BcAUAGdIlK2o/WtLa6WHveORjedkCY+K4XHpEQItFYo6CsBJAE4BMBMcBKmBQDd0R5qrGwRtYWlkWxizAMySKbuv7qWWrZVu4+8VLnb3+un1HzhSsUGGEGgxKOpUAHNgCnMaOG9nxBgFY8zppwAA0AxCdnRLY3dAOh/A+dUvtkaGe/V/e11syefH1L/sdP0GKkKg+aKoewA4E8Bc9FlkEfTQHaXe7iidDWB2zYut4WFe/RWXhJs3zRj9htN1G0gIgeaColbA7ClPhClOsfGfB11RWtkVpbNHaNsPIg83NRGCh6kWX6nN218sMvWDEGg2FPVbAOYBOBdALYAdEOIsCA9N6B0hMpqBjWYM0w3JdQ9Z0bSSUHq/cd5e7ztdv3JFCLQvikpgzikXAvhun3frADQDmOR0NQcaNSTU0mpu3SQZzhibx3R9Hnm46V+E4B5j2MhnEfCVx6S6TBACTWIOY88BcA2AvbPcKY6GFEC4O+bN5FnKwL7LGL5LOlo2kBVN9xKwB/UL9hZbNhC+uICiVkNRGwB8AWA5sosTML19DKerPZColqKxcJwO7+8+Bkw2GLtbZ9hIVzRdJ634rNLpujvN0BWoonqhqFcB2ATgVgC75fjJCgCfOF39gYSXhXbk+ZHdDMaW6Axf0RVN/yv9YcOQPU839ASqqG4o6pUw55K/hTmvzJeh99wKhDCGji69kGcMALUGY7/QNW0jXfHZ1VDUITclG1pfNEU9DcBHAO5G7wWLfNkXgJgj5cBwV7g7rpGcnP+zUGcw3Ek6WtbRFU1nON0mngwNgSrqIVDUtQD+AtOXtFgIgHVON2sgIGnhzlKVZc1RV5KHm96gj6w/wum28WBwC1RRR0BRHwDwNnbdMimWQodtQwYJOmvvZGNKXS4DO9wwjNfIw03L5Qc/qXW6nXYyeAWqqHNh9nIXwx7ngvEAWpxuZjkzXA616YzY5dhBGdhFGpWa6Iqm863960HH4BOook6Eov4DwJMARtts7Qunm1vO6NFogoOZkQZjK0hH67+kR9ZPdLrNpWbwCFRRCRT1EgAfAjiBk9UJTje7XPHQhNEZInb/QO6EgU3XDeMDuqLp8sHUmw4OgSrq7gD+BuD3MIM482IkgI1ONz8blFJUEP7eczUktN0Bn71qg7H7SEfrmsHSmw58gSrqmTB7zdkO1aDd6UeQDUoJJPCXSjgU9zrVZgY2QzeM9+jDn811qg6lYuBu/Jq+s3fDXARykn1guv4N/B+7ElEtRWPdMdKva5/NDDOAJ8mKpuMlpl+h/XTfiNPPpRAG5pdKUacAeB3OixMAvAA+dboS5UQBrn22wRi7QAcNSo+s38/puhTCwBOoOaR9B8CBTleFMwmYq8ZvA/g7gKdriPaHXD5Y59VafFV6yzCv0VXpNhLUxiUUy7XP5/TDSoUB++qG8eZAHPIOnNUuRaUAfgOgwemqpIEBiAAo9vRFAube7SfW6zOYovwSwNa+ZyUb16wd53a7v5x+1JEZC/z4k0+x7ZvtZ808bsZTqdenvLJtH93AgbpBDtYMcnBcI5NjCVIfipNK3Sh873KEHO5u3xGqtvFZFwUl5HZj2MgGBHwD4kTSwJiDKuowmPuaJztdlQwQmGI6OI/PGAA+APAmzF7xDQCfIODT8iij0zAK+56tn16/DuaPwcrU61Nf3SbrBmYldHJyXCPTQjG6d3eMVuYam0zSQp0w0x+WJQZj15KO1gPJY5vOMM6dUPZne8tfoOZ881mY0dfLmVxczj4A8LL1WouAr+y+IE1H12sA/mq9AABTXtk2OqGTi6IJcnJ3lH67O0bTrtBKREd7B6sv94EZA5uFcOef5WUfXqJdfMB6p+uTjfIWqKIeBuBPMJPSljsTALTC3BtNEgOwBsCLAF5AwLfZ6UoWwvrp9d8A+LX1wl6vbDssliDzQzE6qz0sjTas3nW4FFZVRspq/pkO0t3+GdMTx+mE/Nd131vfT1xx2H+crlMmylegivo/ABSY87ptMOd4ju2t5cgmmImNVgN4CsCzCPhKdpqjXPh8ev1bMAOpYcor28bFNHJDV5T+UO+Ixp2uW79Ew18xLb4XCAFjrC4Rj62Wl75+rrZgmuJ01dJRnqu4inoegOfRs+hSD2Az4MCOe+40wZwnj0HA9z0EfI9xEGdC1/VwdyiU9s14PAG1rV2HOT+2hfXT6zd/eezoS9r+Z9SorpjrUErIjQT43OZ2F/i0Yh2Ido8AIVLKVa+m6Svlpa9f6XT10lF+kwVFvQ7Akgzvvgcz6VC5kIDZyy8H8C8nItI1rll7qsfj+fNh/oMlj6f3uej3P/wIra07bpl53IwbeNeLrlh/LGPsCgb2fQBS0QUWi2EkSGerykhm/2BZlq/XFky71emqplJeAjWDd/X3gN6D8yLthCnKexDwfeVwXdC4Zu3C6qqq2/2HHARZNmctX2/ZinWfNQUBfGfmcTMcG3pKj6yfYDB2JWPsAjiVQIoxkI7tGxihk/utryzfoi+Yxv0HLRPlI1BFvQHWIkQOrIPpYsebFgC3AVhebnPLxjVr76+tHXHpQd/+NqLRKN58OxjWdd0/87gZZRH5QfrDhhqm6z8zGLsKua14lwzS0fIpM8PU5FZXSf6tfuW0q3k/o7R1d7oCAABFXQxgUR6fiAJog5l5mgc7ANwB4D4EfN2cn05ONK5ZKwH4c/3o3U4NRyLo7OyaP/O4Gfc5Xa++8BYq7W77zNC1/kKp7lpPSb5Xv3LaAieeUSrOCzS/njOV7TAXkezcFI8AuB3A7eUqzFQa16ythLmtowI4aeZxM8p2UY0+tmk4tPgNBmMLkGNG8byJhr5ENLQHCCloMbQchrvOClRRLwdQzK/85zDTMNixGv0EgP9XDnPMfGhcs3YUAGnmcTO2OV2XXJBWNI03gFsYY6X1k03E2hDq8ICQotwvJVm+Tl8w7Xanno9zAlXUswE8XoKS3kdpHeffBXApAj6RJo8j0oqmYwyG3zOw4j3GDD1OOlraGZVyDUaeFdnlukKbf8TvnHguzghUUU+Cuc9Zqp7vXeTnB5uOEID/BbA0T39YQalQVJl2tCw0gBtQ6NSFMZCOb5oZkUqZ4MqQZflMJ5wZ+AtUUQ8B8AqKP/nRl0+Rx0pdH/4OYB4Cvi+5Pw/BLkiPrJ9oGOwPDGx6vp8lnS2fMlbw9yAbEZfLdXxi/hH/5fks+ApUUcfBPLVhx+prDOY2yB55fCYM4FoAvxdp78oMRSW0s/Uqg7FfI8cfc9Ldto7pmm3bb4SQVll2TUvMP3wDr8fAT6DmkbF/w96D1jsAuAHkkmznDQDnIOAr69MMQx3p4XVTDZBnWH/fm2j3JkTDexa6YpsrhJANLlk+LD7/iDYe7efji2setn4a9kdBqIO5/dLfIcm7AEwX4ix/9J/u0yQnokdQM2JjehKxHYiERtstTgBgjE3WdF3hFdqTl7P8zQBO5GRrMswESeloB3A6Ar5rEPDxCKosKAGJSw6MGT/d+zJKSACmm2UPhh4j3W0GKOV20skwjOOkr5vu4GHL/l8BRT0ZwAs8GtOHviu7nwA4BQFfswN1EZQIaUXTvgZjzzFgiuVju4kROsGJusiyPFdbMO1pO23YK1BF3QvAWwBG2GonMx8D2A/mgem5CPi6HKqHoITQxzYNZ4n4H9G+fQIjjvhkmxAScsmu7yTmH/6BbW21rfJm3No/wTlxAsBUmIHGThPiHDwY507oYMNHnkRl+RVHK8JYlaYlnpGXf1Rhlwk756C3Afi2jeX3hwHgagR8NyLg0x2sh8AOAj5Dv3LaPEmWb0T/i4K2wRjbm0W677erfHuGuKan0It2VToHEgDOQsC3ysE6CDghL33jXE1LPAwHQ/jILvePtPmHryy+pN6UXqCKOhpmrpRRHJ5LOiIATkbAt8Yh+wIHkO9982QtkVAAZs/JmH4ghHTILve3E1ccVlJvNDuGuI/COXF2AjhJiHPooc0//EXZ5fohQELFl5Y/jLHhupZbpP98KK1AzWBf3+P0TPrSCWAWAr6XHbIvcBht/uH/J7tcJzslUsPQZ8hL37iilGWWboirqPUwQ5E4kdUqAuB4BHxcHZkF5Yl831uztXj8OUeGu4R0u9ye/ROXH1qS7Oul7EEfgDPiTMDcRhHiFAAAtCsO+7ssyz8CwP/YIGPVeiLxaKmKK41AFXUOgO9zfxjm8vpcBHz/cMC2oIzRFhzxrOxyXwAHtmAMQ58h3/vmBaUoq/ghrqLWwBzajuX9IABcgYDPkZPugoGBtPT1G3RNKyTmVVEQkBaXRKbGr/xOezHllKIHvQnOiPMeIU5Bf+gLpv1GkqSHedtlYKN00MXFllOcQBV1HwBX8W48TOf7axywKxiAuCJdl1AqNfK2q+vahfLyD4s6YllsD3oP+Gce+wTmvFO47wlyItowS5MJm0MI4X2SSdLjsaKG14ULVFFPgZlqL8KxwV0AfjAQYtQKyov4ld9pl2X5NBA+e6QkFmkl6rav2PbNJ7sX/+Osgssp6FNmhIT3ABwAoBvAehQfVS8XTkfA9xcOdgSDFPneN+ZqicSTthnQtTjtbN1kEDIFoAQAKKUbvXp0SuhXZ+Y96iu0Bz0bpjgBMzziwTDTA9qZdu4OIU5BsWjzj3hKkuQHS14wY6AdrZ+TjlbdINLUpDgBwDCMifHKEQWlN8y/B1VUN8wec88Md3wEM2pfXQmb/y6AaQj4yj9BrKDskZd/VKGHOt9hzChJeE4S7tyCaMjFqJzRB51Q0urxVk2MLjohr+lZIT3oZcgsTgDYH6ZHURCml0+xhAH8WIhTUCq0eftHZVk6E8Wun8SjnVTduonFY2OziRMAmMFG6rqeT4IwAPn2oGbvuRG573u2wRz6FnNw+xIEfMuK+LxAkBZp6RuLdC2R/16loWu0c8dGg7FJIDTn5MRmL1o5LrpoVjTXz+Tbg16A/JwSamGKsxlAIc7Da2EmyhUISo4+dsptlEpv5vwBxkC71GbSvj1igEzJR5yA1YsaLK+8o7n3oIoqA2gCMLGIZ/IezGxkuWRajgDYX0ThE9iJa+kbeye0xLsAsobtJNHubxDuYozK9cXYI5S2VMh0XOTGU2K53J9PD3oWihMnYKau98Ccn/a35HyDEKfAbhILjvhMkuXfZL4hHqJt2zawaHh0seIEAGYYozTJfVmu9+cj0IUleiYeAH6YaRo+zXDPBwCWlsieQJAVydBvI4Q29brIDIN2tDShW3UbRJpcyqPTejx2ea735iZQRT0W5upsKdkNZjayJgBb+7x3hXDlE/AiftVRCUmWd0ZCIKH2L0jb9i6DYSqIVHJXVkPXJ7sX/+O0XO7NtQddYOPzmQqgHsA7MOedTyHgczbeqWDIoc0/fDV1e54gHdu/YonEeEYlW4MP6InEVbnc179AFXUCgFNtfj4EwCEwk+g22GxLIEgLdVXcyBgpSVbu/tAT8WM8t/2z32ziufSgl+Z4Xyl4CAHfZk62BIJeaBcf8IXsqXiUkzmiJ+L9brlkF565tfITThVuA7CEky2BIC2yy3UjobSz+JL6R0/ETnff/Z+sc9z+esYTAYzm9GxuRcDXzsmWQJCW6HUzW2S35/fFl9Q/zGC1iHbPzXZPfwI9j9Nz2QHAtvwWAkE+SJQs5teLaudnez+zQBV1FIBTOD2T3yLgcyTYsEDQl2jD7HbJ7eHiYqon4kdXLGkcl+n9bD3oj8AnGU0HABH8S1BWyJQuIZRL9AVJ17WfZnozm0DP4PQsHhBzT0G5EW2Y1Sq5PbZmz06ia4kfZHovvUAVdSyAo3jUDWLuKShTJNl9OzgEvjY07YCKJavT+rln6kF/CLtyh/bmOQR8JU3XJhCUith1xzdJLjePTHlE1/W025mZBHo6p2cgHOIFZY3k8dzNw46uJU5Ld33XXlJR6wBsh/3eQ58i4OvX1UkgcBryi+e/ZLo+rviSshkhzFMzvD628NjtqZfTifAE8HHte5SDDYGgaGTZZf9iEWOEaYldRq7phMgjAa8B4HEOdgSCoqEuz+/AZ7HoxL7Xeg9xFZUA2ALz+Jed/A0B34nFFzNw8fv9iwAUm1ynORgMTi7A9jyY8aLS2V9ilStiQaUg/er/XtUTcVt3NgglbWz/Y+oQ8LHktb496IGwX5wAwGV/qcyp5W3Q7/fP8fv9GwAsQ+Yfh0UAlvn9ftUSsgCA5HKtstsGM1itZ0Nweuq1vgI9nkNb4wCe52Cn3OEqUKvHfgZm0LZc67fM7/eLkKcAKPAkCLE9Y7eh67NS/+7rysfDOWENAr4ODnbKnZ1CCQaDtu45pxlOJ4/2rQoGg80p900CMAfAvJT6zfP7/QgGgxc7/cCcJNowq1X61Yuv64nE0XbaMXStlwb7CtRW4xZ/4mBjIJAUQJudRvx+/0z0FueqYDCY1o3TEusSAEv8fv9imMNdwBRpcKjPS6kkP8dBoL2SkPUMcRV1bwCj8i2wAP7KwcZAIDnEtTu0aOoQNaM4+xIMBhvQ+wD9Yr/fz33eXE5IkmR758IMNtxzW+Mhyb9T56A8es8PEfBt4WCnrLG+6Mkvu209qN/vn4OenroZQF7DVEukQevPWphD3yFLdNEJG6kk2R6r2dD1nWtBqQI9nEMbX+JgYyCQ2hPZ+T98Tsq/lwSDwUJ+DFKDuM0p4PODCiq7XrbbBtO1nVpMFehBHNr3Dw42BgKpK6m2CNTqpWdaf7YBKGibIBgMNqbU0e/3+/28HlI5QiXJ9k7GMIydLrCmQBVVQk9CXrvQAfzX7sYNEFIFatcQdxJ6eurGAnvPJKninllwKYMACtYIm72KDF3by9Lkzh50KvpJHlMC3hVhTXaSOsS1S6CpQgoWXIpJai8/pBeKog2z26ksNxVfUhYY3FL7N/sBPQI9iEPb/sPBxkCBxxy0lD8CqXXM1dFh0EIl6S27bTBmHAn07IPuBzORUZd1rQ7AHgDyyn/YD2J42wOPIW4pfwRED5oCpdLrAM4pSWF6PE7isR1Ui0WYroMxo5qB1Ml6/LA4sCwp0L1hJjLqy1aYZ0NjMIfAYwCMLLAq73J9iuXNzi950pPHWnyZmfJKJQhzHrg8j7mkXUIa8j0ooVL+nY2hM5KIqjQR62S6psMwvIzAx4jkZQRjdACgFMlBraFpU4CeHnSvDMWOsV6pJGCmtW+DOVkeDrO3rcxSvRCAz51+sGXEzr1Ja7V1GbJvYfit12K/398QDAZzicA/5Hs6u5C7d3wQo54YGPPs8iZjIFq0myTibdDiMWLoLsNgwxmVRjBK6nSgDoQAUvbBqaEn9gT6F2g6XEj/K9oFU7jdVrmjAOwO8yfhQwR8tp+nG0CkPr8NyE9Mi/1+/8xgMHiC040YqoR+daZOf/H8eiMW2ZskYjuoFg8zQwMzjGoG4mOSVM2AagAAlQoKf8A0bQwAyFDUeiQLK44aAOlCmGyFWCDaSR93uVShpj2Had0/D70d2Gf6/f5ncnXbE5QeGo9sNMId+zOgXgcAQgGpdIFIGAyP95fPTaIAxtvcljHYNUHvUKbv6KMRwORgMNiQzhk9GAy2BYPBJdbB7NT354jzms5BCezdagHADGMqBTCWQ3vE/LOH1B40COCM1CNf2bCOfKWKdMg7sDsFodJndttgjI2n2HURyA6EQHtIXYVtKMDDpwE92x61EP6xjkAk+SO7bTBDGycDsDecoMlGDjYGBMFgMIgigoIHg8E2v9+/HD1nPGeid68q4ACR5I/ttsF0Yw8K+/N/diDgC9vdmCFGY8q/h7RvrFNEbjy5kxAasdWIoY+iML2G7EQsEJUYqxdODo1rxTzUGYgkqXaWz4BaCmCEze34yubyhyqpDvDpBGprKBUBQKi8vfhSMsMMfRgPgYoviv2kcxyx67nbHlFgoEAI7bKzfGbo1TwE2m5z+YL0Yky9Vqz/LA/n/oEHJZ22ls9YNYXpS2sn7TaXP1Tp7ziZXQIVPagFIbTdzvKZYVTySHEvVnBT8Pv9q2GuvBaUtiGF1Li66USTutJbbJgS0YOmgRBi+3ebwvShtZN2uxsxQCm4V7OOpiV70EzREprRI6aZRa70pjpDNBZcymCDEFsDsDNmeHoOoAl4kRrJvdCeLXXvM61gLA+l1PcK8tu1Al/vPB5nbfEIAACMFV9GVqgQJ39Sh6N5i8bqCRelXMommNRgX4sK7EVTo9ILjyXO8BBozOlGlhmpopln9VD5sAgpUemDwWDGcJrWe6l+u8/kY8hK/5Ds5dsgBNobSm3/bvMQqKf4IgYP1oJO6hd9tRUBvl/65EsBegeVzkRqNPmZfr9/dS49aRpbhQa+HrwYhu3fbR6ruIJdaYA5j0zO7Z7x+/2NMOPX9gpnkiHjGGDGJ+o3GHUwGGz0+/0N6O1cr1rXGlPnlFlsrcoxzIqgxBAoajvs3Qu9GQHfL51uaLlhiWE1ClvNbcw35EkRGb1zTrg01HDf8Mdl8VCnbYfmCaERHkPcUobuHDQEg8HkPmi+PVNDIfGIrB7wBOTnaHCxEGdWbNePDDNKn5347G7EQMbKINZg9XCTkH5ldwmAtmKHmVaelckpWc/S9aglsTUUYIzZfYpIkwGoKDzWbS6Io1A5kCII2zNZp8xdhQiLgBn6CDvLJ5IUorDfdUv0oIJBCWPMVj92QmgnD4GKHlQwODGMYbaWT02B2noqHGbUeYFg0MEM3dZoJAS0g0cPOgaKKvZbBYOKqptWug1ds3V0SCTaTmF/zCAJfEJ7CgTcMOSKybB5m4VQuo2CT8ygPTnYEAi4wZgxxW4bhNAvKYAvObTH9sYIBDxhhv6t4kvJDqG0mVcPantjBAKeGFpif9uNyK7PKcyUgXazDwcbAgE3mK4VE64mJ6hhNFEEfFEAX9tsaz+7GyMQ8MTQErYKlBDaFr75tHByFaqUqdR0AF8AeAfAmwA+BVAHRbU79pFAwIXKm1fVIdwZk6LdG2ks/BVJxDphlDb6CXW5NgM950E/AXBsAeW0ANgGIALzYPZoAPUwc472zTt6GIA13J6iQGATLBqebURCvR1wmG5Qhg5CaQiSZDDJ7TFkdy1cHnchqbKo7F6vo0eg6/q5PwxzMakD5t5PLcytk1HWKxcOhRCoYBBgJOLTd7lIJGoQ1AKohW4AehSIRwGmxymhHQQkAlkmTHJVGi5PLWRX1j1UIknrgN49KAAYMIXYCkADUA0zPWENgKlFtuswpx+sQFAKjHjs4JxvJpLbSHZimma+omEQZnQTSjsJlRJMcslMdg1jrooaULO7pVR6D+gR6KcwPYrGwOwZ7XAsmF58EQKB82jRcHHbhoSAEamaAdUwDMCIAYkYEO40qOxuJ+6KLn3MXq8DqYlkFXUz7Hds3xcBX3/D6UGHFaRrGXoCQLfBDMK1JOWet7FrBPjlVtr7/spfBGBOMBg8NM17fpgHs5PRA5st28ut9+cgc7S/M5JnR9OETGkYioe6K69/6sjwlo2v2WmDyq4O46HrRgC9fQnf4tC+QhaiBjSWON+GOW/3BYNBAvNQ9iLrS5/KqmAwSKx7JsOMwpdLHKF5SBMS07K9GmaEhGS5SwAs8/v9fSM3HJq8J+WVFOczlo1DrTIOhRkydJnTz5c3Rix8ut02pIrKnbsqqQJ9m0P7judgo9yYB1OcZyTDVlpf/FXIErjaCs/ZiH4yaFtxdWuTPWIfZlq2l6SUu9wqN9dQnzOtexuSEQCt/y7PtYzBhB6L2j5Vo+6Kd5L/Tj0GxqMHnQlFdSHgszsOUjnhh/md7nWsr7+hqxX1byayR44HTJFkCr/ZnHLPznLyDDrmh9kD97WxCkPsMH7VTSvd4S0bD7TbDnW5/pv8d6pA3wbAgEJ2bXJmOICjAbxsdyPLjFzP3M7x+/2pO96NOUTVmwMg7T3BYDDo9/vPQM+Qdrl1OZ2g3+6TKiYZbrM2Q9nNyC1w9qDBiEcDTNcrbDbDqCS/lPyjR6ABXxsU9X0AB9lcgVMx9AS6E2s+lzo09KX0rr1i0FpR4J/JJFJLdG1WtL60JIfT1r2T0CPWM/r06oeKxEjZ0aMR24f0UoX369AtZ32T/LvvZuk/ObTzVA42yo2dvVAwGDzDWmjJpfdZArNXzRTceg5yzJcSDAaXWyE+JyNzyM10pO39/X7/pBwXsAYNWqjzGLttSBVVb6T+3Vegazm0cxIU9dDiixkwBGHudhQzX9tFoClz1IzpH/x+/2K/37+hV2XMXjOI3JP6BgHUpskfk0wRMSSobHjie4aWsD1CpeSpWJ36d1+BvgLTm8hufszBRllg7RU2w8y/MgnYuf2RzLKdbX66yLon3RB2Dsw5arZI8Y0AevV0ltBmIsdEvJbtVQAWJ/OZWv+dhyw/DoMNLdJ9EQczjErys6kXegs04OsAn+2WH0NRh1Ju0mTKhQ3WIpAKc+jYdzV1jt/vZ8mXdS3TIlG/ArHEdShMTSXLXAbTUaHvEPvtVNvWa5FVzhkwh9JvW2WsRo5OFIOBqptWSolQZ75pIvNGqqjclDr/BNKt2CrqTQB4JDuaiYCPx5x30GH1gsuCwaAICs4B76LHzol8s/kxu+14fLutiN110U9Tr6XrxV7g1O4h8etrB8FgcJUQJz+0UBeXubbk8T7V91r6PU8+frkJAHsg4NvOo/ECQSFU3fDUhNCWLz4HM2zN0kdlV7vx0HW7LCRmmge+yKHtLgDncbAjEBSMFglfZ7c4AUCuHPafdNczCfQvnNp/CRRV5A8VlCVVN62UEl3tXPKjShXeP6W7nkmg/4QZzsRuJgL4AY8HIBDkix4NzzcSMVvzrwAAkV0hWY8/ke699AIN+HQAKzk9h4Wc7AgEeZHoal/Aw46ratiarjsvSnuAJNte5B85PYcjoKhHcbIlEOSEt+GxOXo0PJGHLclbtSLTe9kE+hr4pIUAgJs42REIciLR1c7lO0ldnh0VOzY/n/H9jJ8M+BiARzg9j9lQ1GmcbAkEWfE2PH6qFuo6gIctV/Wwv7U9eH1G99r+3O1WwDwjyoOfc7IjEGQl0anexskUkyoqs9rKLtCA70sAL4EPs6GoQy5mkaC88C76w1wt3L03D1tyVc0H4VvP/jDbPbk4rOd03rBE3DnEnOgFZUTVTSulePuOW3nZc1XVPNDfPbmI4UUAWzjV+WAA53CyJRD0Qo+Eb9BjES7JpqnL1SHr2sP93tdvSQGfBuBeHpW2uBKKWsXRnkAA1+/fqYm1t1zDzd4w3zOZ9j5TyXU4uQxAyOY6h2BmRDsYwM022xIIekE+e3MZDXeEwDjEK6BSXHZX5PQdz02gAV8b7N1yScYBPcT678+gqPZnMBYIAFRdvfz4xBefnalHwmNoR2uIRkM77LTnrhnxUujWs7fmcm8+CzK/Rem3XJpgJg8+BEDqsFYG8AAU1c4QoAIBqm5aKcVavlrBLC0YhFYZsXCd1Nm6gySipR81EhhyVU3OI8TcBRrwNSNzDo98aQHwMcyMabtnuOcoAJeV/AEJBCnobdvu1Lq7+iwMEegMdSzUUSl179gKXddKZc9VPeL18C1nvZfr/fluafwSxfWiMZhR4nwA9svh/iVQ1CmlejgCQSpV1zx4RGzb5sydAJGIrrMxpKvVkCKd34AVPYBkrpoRi/L5QP5DSEX9I4AzC6jc+wAmwIwunw+vAvguAj4e0QYFQ4Saax50RbZ/vV7r7hif62cksE5WUWUYnsoRhdh01Yx4LXHv5XkdDCnEKSDfXnQTgI0ADkT+4gTMVBHXFfJABIJMJCLdy/IRJwDoIMOMaGiE1NnSQrR4NE+TefeeQKF5WBT1KfQf27YdwBcwhVksOoDpCPj+W3RJgiFP1c+W/TC8ad0zrLAOCgBAwAwqy9/o3prRoHK/5biGjfhXYunlM/K1U2gFbwAQz/CeDnOe6UVpxAkAEoCVUFQRyU5QFNXXrtgjsqV5RTHiBAAGQnVNH0O71BiNdmWPPkKo7qqp/VkhdgqrZMC3Eem9iz6GGZTZD8BTzANIwzgAj4qtF0Gh1F50C421bvmbEY8PK1WZBqjXiMVGSR3b22k80pXuHvdw31/Cv5n7biHlF/Mr8muYYgTMvcz1MFdmR5Wq8Wk4BeJYmqBAInLF44n2HbY4wOigI4xIV43U1foNMRI7R5dElsOuyuorCi23cIEGfO0wF4zegbmXyWs75H+hqCLQmCAvvAvuvza6bfNce61Q6AZGo6uNyuH2bTAM5hled3/fdA75lVgcvwPgtrfRaXkcimp7pmPB4KDq6gdnRbc038LLHgOVtYRWL7tczca4fa8vpqziBGqedLmUV8NTqALwVyjqOAdsCwYQ1dc8tF9kywaF6bpcfGn54R4x8vr4VUf1e2IlG8Ufjg74XoUZGoU3YwG8BEUtZG9VMASouebBMZGtm9YYsVgNb9vuutH/Ct95YdGusaWKXrAIgK0nADLwLQDPQ1ErHbAtKGOqrn9yWKTl69f0SGg33rapyxVx1+52dknKKkmNAr5WOBeA+hgAChTVibmwoAypWfhQZXxr86taV8cEJ+x7dht3e/ftF3xVirJKu6eoqM8C+L4DzwQw0yaebs2LBUOUmoUPVUZ3bH090a5yCZvZF9dw38eJR28q2VZOqQN0XYKevVHenALgCdGTDl1qrnnQFVO/ecUpcRLZFfXsNq6kW4ClFWjAtw1AwZuyJeBMmMPdUnsxCcqcmoUPVUbV7W/H21oPKb60wqgYM/7n3bedt76UZdrjNqeoTwP4EY+HkoGXAZyMgC/sYB0EnKhe9GhddOum17Wujr2cqoOrdvRbiRUNh5e6XLti0F4CoNneR5KVYwGsgaLa6XYoKAOqFz40Prpl43tOipN6Kjo8I0efZkvZttQ44OuA2YMWtUlbJEcAeB2KOtXBOghspGrhQ9+JfN38jtbduYdTdSCUGN6xk37Sfdv5tsSOti+Ke8D3FoAG28rPjUkAXoOi1jtcD0GJqfzZAz8Of9H0Tz0acfQIoqd+/LLQXRc9Z1f5dqdZ+C0A2yqfI09bi1eCQUS8detipiUqnKyDe8TI973xkK2LovYK1ExheA6AT221k5m/A7jKIdsCG6kYtfts6vbYHUw9I5K3coenbvTsbKkDS4H9iYoCvi4Ap8EMgcKTdQDORMCnc7Yr4ED3XfPWeXef9GNCCXfHFCLLsYqxE0/tuuPCgo+R5QqfTGIBXxOAuQB4ReZTYW6zdHCyJ3CA0F3zXqjYffKNnM2yyrETF4TuuPA1Hsb4pfoL+P4G4FoOlhIAfoCAbwO3tgkcI7L08iUV9Xs+wctexdgJy0P3XMYtJSffXJwB310Altps5VIEfP/m2i6Bo3i1yE9ctaPfstuOZ+SY1dHfXXkJz7Y5kSz3agB/tqnsOxHw9ZtzUTC4aHvwesMzcvTxcvWwzXbZcI+oe9c9rPYk3m3jL1Bz0eYcAKUew78I81yqYAjSfdv5XRVjJh5P3e7OUpctVw/b5BozcUYu+TxLjTPp5k0f2VMAfFSiEj8CMFes2A5tum87b713j8lnEkkqmZAkb9X2ijETjgrdclbJhZ8LzggUAAI+FcBxMLdDimE7zBXbriLLEQwCQnfOe8m7+6RrS3EMRKrwtnl3n3SkXW58ueCcQAEg4GsBcAKAQldc4zBXbL9wtB2CsiJ8z2X3VNTvWVTCaanC2+YdO2l69+0XOHnow6bjZvmiqONhZjHL1+n5XAR8jztdfUF54r5wyavxHdvyyiYGmKdTKneffFT3nRd+7HQbnO1Bk5g94JHIrye9VYhTkA3PiLpZcvWwTfl8xhrWzi4HcQLlIlAACPi+AjAduS0cPQszgZNAkJGuOy4MV9SPP556KnLyKJO8Vdu9YydND9150RtO1z1J+QgUAAK+rTAXjt7Jcte7AM62HPEFgqx0335Bs3fspB8QWYpnu0+urvnaO3bCtHLpOZOUl0CB5MLRcQD+mebdbQBORcDn2CkGwcAjdNdFL3t3n3w1MiSelmuGN3tH7+nvvuPCjU7XtS/lJ1AgGZHhRACpc8wIgO9bQ2GBIC/Cd1/6O++Y8cv6XnfXjnrTu9seB/A4mVII5SlQAAj44gB+AuA31pXzEfC96XS1BAOXyP1XXeoeWf9y8m/P6N1XVUk4suuOC0VwuaIQmcwEJaJm4UOVrp/88lPvFff+2um65ML/B0uPe20x0+ZGAAAAAElFTkSuQmCC" width="232" height="212"/>
+</svg>
diff --git a/skyquake/framework/style/img/viewport-vnf-temp.png b/skyquake/framework/style/img/viewport-vnf-temp.png
new file mode 100644 (file)
index 0000000..2debb1b
Binary files /dev/null and b/skyquake/framework/style/img/viewport-vnf-temp.png differ
diff --git a/skyquake/framework/style/img/vim-icon-corners.png b/skyquake/framework/style/img/vim-icon-corners.png
new file mode 100644 (file)
index 0000000..3fdea44
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-corners.png differ
diff --git a/skyquake/framework/style/img/vim-icon-diamond.png b/skyquake/framework/style/img/vim-icon-diamond.png
new file mode 100644 (file)
index 0000000..76c2cd3
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-diamond.png differ
diff --git a/skyquake/framework/style/img/vim-icon-halfcircle-bottom.png b/skyquake/framework/style/img/vim-icon-halfcircle-bottom.png
new file mode 100644 (file)
index 0000000..4440a9a
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-halfcircle-bottom.png differ
diff --git a/skyquake/framework/style/img/vim-icon-halfcircle-top.png b/skyquake/framework/style/img/vim-icon-halfcircle-top.png
new file mode 100644 (file)
index 0000000..25d8e1d
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-halfcircle-top.png differ
diff --git a/skyquake/framework/style/img/vim-icon-plus.png b/skyquake/framework/style/img/vim-icon-plus.png
new file mode 100644 (file)
index 0000000..88c7f83
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-plus.png differ
diff --git a/skyquake/framework/style/img/vim-icon-soliddiamond.png b/skyquake/framework/style/img/vim-icon-soliddiamond.png
new file mode 100644 (file)
index 0000000..7d6ca71
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-soliddiamond.png differ
diff --git a/skyquake/framework/style/img/vim-icon-solidsquare.png b/skyquake/framework/style/img/vim-icon-solidsquare.png
new file mode 100644 (file)
index 0000000..03466e4
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-solidsquare.png differ
diff --git a/skyquake/framework/style/img/vim-icon-solidstar.png b/skyquake/framework/style/img/vim-icon-solidstar.png
new file mode 100644 (file)
index 0000000..a756b55
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-solidstar.png differ
diff --git a/skyquake/framework/style/img/vim-icon-triangle.png b/skyquake/framework/style/img/vim-icon-triangle.png
new file mode 100644 (file)
index 0000000..fa53ce4
Binary files /dev/null and b/skyquake/framework/style/img/vim-icon-triangle.png differ
diff --git a/skyquake/framework/style/layout.scss b/skyquake/framework/style/layout.scss
new file mode 100644 (file)
index 0000000..358564c
--- /dev/null
@@ -0,0 +1,149 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+html, body {
+  height:100%;
+  width:100%;
+}
+.flex {
+  display:-ms-flexbox;
+  display:flex;
+  &-column {
+    display:-ms-flexbox;
+    display:flex;
+    -ms-flex-direction:column;
+        flex-direction:column;
+  }
+  &.space-between {
+    -ms-flex-pack:justify;
+        justify-content:space-between;
+  }
+}
+.layout-col {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-direction: column;
+        flex-direction: column;
+    box-sizing: border-box;
+    -ms-flex: 1 1 auto;
+        flex: 1 1 auto;
+    &_left {
+      -ms-flex: 1 1 70%;
+          flex: 1 1 70%;
+    }
+    &_right {
+      -ms-flex: 0 1 30%;
+          flex: 0 1 30%;
+    }
+  }
+
+.app-body {
+  width:100%;
+  /*height:100%;*/
+  display:-ms-flexbox;
+  display:flex;
+  -ms-flex-direction:column;
+      flex-direction:column;
+  -ms-flex-pack:start;
+      justify-content:flex-start;
+  -ms-flex-align:stretch;
+      align-items:stretch;
+  -ms-flex-line-pack: stretch;
+      align-content: stretch;
+  margin:0px;
+}
+
+.header-app h1 {
+  /* background: url('../../../../assets/img/header-logo.png') no-repeat left center !important;*/
+  height: 51px;
+  line-height: 51px;
+  margin-left: 80px;
+  padding-left: 118px;
+  position: absolute;
+  left: 0;
+  text-transform: uppercase;
+}
+
+
+html, body, .application{
+    margin:0px;
+   height:100%;
+}
+
+.wrap {
+  height: 100%;
+  display: -ms-flexbox;
+  display: flex;
+  .content-wrapper {
+    height:100%;
+    overflow-y:auto;
+  }
+}
+
+.application{
+  display:-ms-flexbox;
+  display:flex;
+  -ms-flex:1 1 auto;
+      flex:1 1 auto;
+  -ms-flex-direction:column;
+      flex-direction:column;
+  height:auto;
+  overflow:auto;
+}
+
+
+.content {
+  display:-ms-flexbox;
+  display:flex;
+  -ms-flex-direction:column;
+      flex-direction:column;
+}
+.panel {
+  display:-ms-flexbox;
+  display:flex;
+  margin:0.25rem;
+  border:1px solid black;
+  border-offset: -1px;
+  /*flex:1 1 auto;*/
+  &--container {
+    padding:0.25rem;
+  }
+  &--column {
+    -ms-flex-direction:column;
+        flex-direction:column;
+  }
+  &--grow {
+    -ms-flex:1;
+        flex:1;
+  }
+  &--wrap {
+    -ms-flex-wrap:wrap;
+        flex-wrap:wrap;
+  }
+}
+.card {
+
+}
+.size-2 {
+ -ms-flex: 1 1 20%;
+     flex: 1 1 20%;
+}
+.size-5 {
+ -ms-flex: 1 1 50%;
+     flex: 1 1 50%;
+}
diff --git a/skyquake/framework/style/variables.scss b/skyquake/framework/style/variables.scss
new file mode 100644 (file)
index 0000000..a1d6cbd
--- /dev/null
@@ -0,0 +1,13 @@
+/* TRANSITIONS
+############################################################################ */
+
+$transition: all 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
+
+
+
+/* SHADOW
+############################################################################ */
+
+$shadow: 0 8px 6px -6px hsla(0,0,0,.35);
+
+// $focus-shadow: 0 0 6px 0 $focus;
diff --git a/skyquake/framework/style/vendor/css-reset-2.0/css-reset.css b/skyquake/framework/style/vendor/css-reset-2.0/css-reset.css
new file mode 100644 (file)
index 0000000..ba39032
--- /dev/null
@@ -0,0 +1,5 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+   v2.0 | 20110126
+   License: none (public domain)
+*/
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kb,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
diff --git a/skyquake/framework/utils/guid.js b/skyquake/framework/utils/guid.js
new file mode 100644 (file)
index 0000000..b266c37
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * @return {string}
+ */
+function GUID() {
+  // http://byronsalau.com/blog/how-to-create-a-guid-uuid-in-javascript/
+  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+    var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
+    return v.toString(16);
+  });
+}
+
+module.exports = GUID;
diff --git a/skyquake/framework/utils/rw.js b/skyquake/framework/utils/rw.js
new file mode 100644 (file)
index 0000000..1cca8f2
--- /dev/null
@@ -0,0 +1,924 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+// rw.js will no longer be necessary when Angular dependency no longer exists
+/**
+ * reset values in an array, useful when an array instance is
+ * being observed for changes and simply setting array reference
+ * to a new array instance is not a great option.
+ *
+ * Example:
+ *   x = ['a', 'b']
+ *   setValues(x, ['c', 'd'])
+ *   x
+ *     ['c', 'd']
+ */
+
+var rw = rw || {
+  // Angular specific for now but can be modified in one location if need ever be
+  BaseController: function() {
+    var self = this;
+
+    // handles factories with detach/cancel methods and listeners with cancel method
+    if (this.$scope) {
+      this.$scope.$on('$stateChangeStart', function() {
+        var properties = Object.getOwnPropertyNames(self);
+
+        properties.forEach(function(key) {
+
+          var propertyValue = self[key];
+
+          if (propertyValue) {
+            if (Array.isArray(propertyValue)) {
+              propertyValue.forEach(function(item) {
+                if (item.off && typeof item.off == 'function') {
+                  item.off(null, null, self);
+                }
+              });
+              propertyValue.length = 0;
+            } else {
+              if (propertyValue.detached && typeof propertyValue.detached == 'function') {
+                propertyValue.detached();
+              } else if (propertyValue.cancel && typeof propertyValue.cancel == 'function') {
+                propertyValue.cancel();
+              } else if (propertyValue.off && typeof propertyValue.off == 'function') {
+                propertyValue.off(null, null, self);
+              }
+            }
+          }
+        });
+      });
+    };
+
+    // call in to do additional cleanup
+    if (self.doCleanup && typeof self.doCleanup == 'function') {
+      self.doCleanup();
+    };
+  },
+  getSearchParams: function (url) {
+    var a = document.createElement('a');
+    a.href = url;
+    var params = {};
+    var items = a.search.replace('?', '').split('&');
+    for (var i = 0; i < items.length; i++) {
+      if (items[i].length > 0) {
+        var key_value = items[i].split('=');
+        params[key_value[0]] = key_value[1];
+      }
+    }
+    return params;
+  },
+
+  inplaceUpdate : function(ary, values) {
+    var args = [0, ary.length];
+    Array.prototype.splice.apply(ary, args.concat(values));
+  }
+};
+
+// explore making this configurable somehow
+//   api_server = 'http://localhost:5050';
+rw.search_params = rw.getSearchParams(window.location.href);
+// MONKEY PATCHING
+if (Element.prototype == null) {
+  Element.prototype.uniqueId = 0;
+}
+
+Element.prototype.generateUniqueId = function() {
+  Element.prototype.uniqueId++;
+  return 'uid' + Element.prototype.uniqueId;
+};
+
+Element.prototype.empty = Element.prototype.empty || function() {
+  while(this.firstChild) {
+    this.removeChild(this.firstChild);
+  }
+};
+
+/**
+ * Merge one object into another.  No circular reference checking so if there
+ * is there might be infinite recursion.
+ */
+rw.merge = function(obj1, obj2) {
+  for (prop in obj2) {
+    if (typeof(obj2[prop]) == 'object') {
+      if (prop in obj1) {
+        this.merge(obj1[prop], obj2[prop]);
+      } else {
+        obj1[prop] = obj2[prop];
+      }
+    } else {
+      obj1[prop] = obj2[prop];
+    }
+  }
+}
+
+Element.prototype.getElementByTagName = function(tagName) {
+  for (var i = this.children.length - 1; i >= 0; i--) {
+    if (this.children[i].localName == tagName) {
+      return this.children[i];
+    }
+  }
+};
+
+rw.ui = {
+
+  computedWidth : function(elem, defaultValue) {
+    var s = window.getComputedStyle(elem);
+    var w = s['width'];
+    if (w && w != 'auto') {
+      // I've never seen this case, but here anyway
+      return w;
+    }
+    w = s['min-width'];
+    if (w) {
+      return w;
+    }
+    return defaultValue;
+  },
+
+  computedHeight : function(elem, defaultValue) {
+    var s = window.getComputedStyle(elem);
+    var w = s['height'];
+    if (w && w != 'auto') {
+      // I've never seen this case, but here anyway
+      return w;
+    }
+    w = s['min-height'];
+    if (w) {
+      return w;
+    }
+    return defaultValue;
+  },
+
+  computedStyle : function(elem, property, defaultValue) {
+    var s = window.getComputedStyle(elem);
+    if (s[property]) {
+      return s[property];
+    }
+    return defaultValue;
+  },
+
+  odd : function(n) {
+    return Math.abs(n) % 2 == 1 ? 'odd' : '';
+  },
+
+  status : function(s) {
+    return s == 'OK' ? 'yes' : 'no';
+  },
+
+  capitalize: function(s) {
+    return s ? s.charAt(0).toUpperCase() + s.slice(1) : '';
+  },
+
+  fmt: function(n, fmtStr) {
+    return numeral(n).format(fmtStr);
+  },
+
+  // assumes values are in megabytes!
+  bytes: function(n, capacity) {
+    if (n === undefined || isNaN(n)) {
+      return '';
+    }
+    var units = false;
+    if (capacity === undefined) {
+      capacity = n;
+      units = true;
+    }
+    var suffixes = [
+      ['KB' , 1000],
+      ['MB' , 1000000],
+      ['GB' , 1000000000],
+      ['TB' , 1000000000000],
+      ['PB' , 1000000000000000]
+    ];
+    for (var i = 0; i < suffixes.length; i++) {
+      if (capacity < suffixes[i][1]) {
+        return (numeral((n * 1000) / suffixes[i][1]).format('0,0') + (units ? suffixes[i][0] : ''));
+      }
+    }
+    return n + (units ? 'B' : '');
+  },
+
+  // assumes values are already in megabits!
+  bits: function(n, capacity) {
+    if (n === undefined || isNaN(n)) {
+      return '';
+    }
+    var units = false;
+    if (capacity === undefined) {
+      capacity = n;
+      units = true;
+    }
+    var suffixes = [
+      ['Mbps' , 1000],
+      ['Gbps' , 1000000],
+      ['Tbps' , 1000000000],
+      ['Pbps' , 1000000000000]
+    ];
+    for (var i = 0; i < suffixes.length; i++) {
+      if (capacity < suffixes[i][1]) {
+        return (numeral((n  * 1000) / suffixes[i][1]).format('0,0') + (units ? suffixes[i][0] : ''));
+      }
+    }
+    return n + (units ? 'Bps' : '');
+  },
+
+  ppsUtilization: function(pps) {
+    return pps ? numeral(pps / 1000000).format('0.0') : '';
+  },
+  ppsUtilizationMax: function(item) {
+    var rate = item.rate / 10000;
+    var max = item.max * 0.0015;
+    return rate/max;
+  },
+  bpsAsPps: function(speed) {
+    return parseInt(speed) * 0.0015;
+  },
+
+  upperCase: function(s) {
+    return s.toUpperCase()
+  },
+
+  mbpsAsPps: function(mbps) {
+    var n = parseInt(mbps);
+    return isNaN(n) ? 0 : rw.ui.fmt(rw.ui.bpsAsPps(n * 1000000), '0a').toUpperCase();
+  },
+
+  k: function(n) {
+    return rw.ui.fmt(rw.ui.noNaN(n), '0a');
+  },
+
+  noNaN: function(n) {
+    return isNaN(n) ? 0 : n;
+  },
+
+  // Labels used in system
+  l10n : {
+    vnf: {
+      'trafsimclient': 'Traf Sim Client',
+      'trafsimserver': 'Traf Sim Server',
+      'ltemmesim': 'MME',
+      'ltegwsim': 'SAE Gateway',
+      'trafgen': 'Traf Gen Client',
+      'trafsink': 'Traf Gen Server',
+      'loadbal': 'Load Balancer',
+      'slbalancer': 'Scriptable Load Balancer'
+    }
+  }
+};
+
+rw.math = {
+  editXml : function(xmlTemplate, domEditor) {
+    var str2dom = new DOMParser();
+    var dom = str2dom.parseFromString(xmlTemplate, 'text/xml');
+    if (domEditor) {
+      domEditor(dom);
+    }
+    var dom2str = new XMLSerializer();
+    return dom2str.serializeToString(dom);
+  },
+
+  num : function(el, tag) {
+    return parseInt(this.str(el, tag), 10);
+  },
+
+  str : function(el, tag) {
+    var tags = el.getElementsByTagName(tag);
+    return tags.length > 0 ? tags[0].textContent.trim() : '';
+  },
+
+  sum : function(total, i, key, value) {
+    if (_.isNumber(value)) {
+      total[key] = (i === 0 ? value : (total[key] + value));
+    }
+  },
+
+  sum2 : function(key) {
+    return function(prev, cur, i) {
+      var value = cur[key];
+      if (_.isNumber(value)) {
+        if (typeof(prev) === 'undefined') {
+          return value;
+        } else {
+          return prev + value;
+        }
+      }
+      return prev;
+    };
+  },
+
+  max : function(key) {
+    return function(prev, cur, i) {
+      var value = cur[key];
+      if (_.isNumber(value)) {
+        if (typeof(prev) === 'undefined') {
+          return value;
+        } else if (prev < value) {
+          return value;
+        }
+      }
+      return prev;
+    };
+  },
+
+  avg2 : function(key) {
+    var sum = rw.math.sum2(key);
+    return function(prev, cur, i, ary) {
+      var s = sum(prev, cur, i);
+      if (i === ary.length - 1) {
+        return s / ary.length;
+      }
+      return s;
+    };
+  },
+
+  avg : function(rows, key) {
+    var total = XmlMath.total(rows, key);
+    return total / rows.length;
+  },
+
+  total : function(rows, key) {
+    var total = 0;
+    for (var i = rows.length - 1; i >= 0; i--) {
+      var n =  parseInt(rows[i][key]);
+      if (!isNaN(n)) {
+        total += n;
+      }
+    }
+    return total;
+  },
+
+  run : function(total, rows, operation) {
+    var i;
+    var f = function(value, key) {
+      operation(total, i, key, value);
+    };
+    for (i = 0; i < rows.length; i++) {
+      _.each(rows[i], f);
+    }
+  }
+};
+
+
+rw.db = {
+  open: function (name, onInit, onOpen) {
+    var self = this;
+
+    var open = window.indexedDB.open(name, 2);
+
+    open.onerror = function (e) {
+      console.log('Could not open database', name, e.target.error.message);
+    };
+
+    open.onsuccess = function (e) {
+      var db = e.target.result;
+      onOpen(db);
+    };
+
+    open.onupgradeneeded = function (e) {
+      var db = e.target.result;
+      onInit(db);
+    };
+  }
+};
+
+rw.db.Offline = function(name) {
+  this.name = name;
+  this.datastore = 'offline';
+};
+
+rw.db.Offline.prototype = {
+
+  open : function(onOpen) {
+    rw.db.open(this.name, this.init.bind(this), onOpen);
+  },
+
+  getItem : function(url, onData) {
+    var self = this;
+    this.open(function(db) {
+      var query = db.transaction(self.datastore)
+          .objectStore(self.datastore)
+          .get(url);
+      query.onsuccess = function(e) {
+        if (e.target.result) {
+          onData(e.target.result.data);
+        } else {
+          console.log('No data found for ' + url + '.  You may need to rebuild your offline database');
+        }
+      }
+    });
+  },
+
+  init : function(db) {
+    var self = this;
+    if (!db.objectStoreNames.contains(this.datastore)) {
+      var create = db.createObjectStore(this.datastore, {keyPath: 'url'});
+      create.onerror = function(e) {
+        console.log('Could not create object store ' + this.datastore);
+      }
+    }
+  },
+
+  saveStore : function(store) {
+    var self = this;
+    this.open(function(db) {
+      for (var i = 0; i < store.length; i++) {
+        var save = db.transaction(self.datastore, "readwrite")
+            .objectStore(self.datastore)
+            .put(store[i]);
+      }
+    });
+  }
+};
+
+rw.api = {
+  nRequests : 0,
+  tRequestsMs: 0,
+  tRequestMaxMs: 0,
+  nRequestsByUrl: {},
+  statsId: null,
+
+  resetStats: function() {
+    rw.api.nRequests = 0;
+    rw.api.tRequestsMs = 0;
+    rw.api.tRequestMaxMs = 0;
+    rw.api.nRequestsByUrl = {};
+  },
+
+  handleAjaxError : function (req, status, err) {
+    console.log('failed', req, status, err);
+  },
+
+  json: function(url) {
+    return this.get(url, 'application/json')
+  },
+
+  get: function(url, accept) {
+    var deferred = jQuery.Deferred();
+    if (rw.api.offline) {
+      rw.api.offline.getItem(url, function (data) {
+        deferred.resolve(data);
+      });
+    } else {
+      var startTime = new Date().getTime();
+      jQuery.ajax(rw.api.server + url, {
+        type: 'GET',
+        dataType: 'json',
+        error: rw.api.handleAjaxError,
+        headers: rw.api.headers(accept),
+        success: function (data) {
+          rw.api.recordUrl(url, startTime);
+          deferred.resolve(data);
+        },
+        error: function(e) {
+          deferred.reject(e);
+        }
+      });
+    }
+    return deferred.promise();
+  },
+
+  headers: function(accept, contentType) {
+    var h = {
+      Accept: accept
+    };
+    if (rw.api.statsId != null) {
+      h['x-stats'] = rw.api.statsId;
+    }
+    if (contentType) {
+      h['Content-Type'] = contentType;
+    }
+    return h;
+  },
+
+  recordUrl:function(url, startTime) {
+    var elapsed = new Date().getTime() - startTime;
+    rw.api.tRequestsMs += elapsed;
+    rw.api.nRequests += 1;
+    rw.api.tRequestMaxMs = Math.max(rw.api.tRequestMaxMs, elapsed);
+    if (url in rw.api.nRequestsByUrl) {
+      var metric = rw.api.nRequestsByUrl[url];
+      metric.url = url;
+      metric.n += 1;
+      metric.max = Math.max(metric.max, elapsed);
+    } else {
+      rw.api.nRequestsByUrl[url] = {url: url, n: 1, max: elapsed};
+    }
+  },
+
+  put: function(url, data, contentType) {
+    return this.push('PUT', url, data, contentType);
+  },
+
+  post: function(url, data, contentType) {
+    return this.push('POST', url, data, contentType);
+  },
+
+  rpc: function(url, data, error) {
+    if(error === undefined){
+        error = function(a,b,c){
+      }
+    }
+    return this.push('POST', url, data, 'application/vnd.yang.data+json', error);
+  },
+
+  push: function(method, url, data, contentType, errorFn) {
+    var deferred = jQuery.Deferred();
+    if (rw.api.offline) {
+      // eating offline put request
+      if(contentType == 'application/vnd.yang.data+json'){
+        var payload = data;
+        rw.api.offline.getItem(url, function (data) {
+          deferred.resolve(data);
+        });
+      }
+      deferred.resolve({});
+    } else {
+      var startTime = new Date().getTime();
+      jQuery.ajax(rw.api.server + url, {
+        type: method,
+        error: rw.api.handleAjaxError,
+        dataType: 'json',
+        headers: rw.api.headers('application/json', contentType),
+        data: JSON.stringify(data),
+        success: function (response) {
+          rw.api.recordUrl(url, startTime);
+          deferred.resolve(response);
+        },
+        error: errorFn
+      });
+    }
+    return deferred.promise();
+  },
+
+  setOffline: function(name) {
+    if (name) {
+      rw.api.offline = new rw.db.Offline(name);
+    } else {
+      rw.api.offline = false;
+    }
+  },
+
+  // When passing things to ConfD ('/api/...') then '/' needs to be
+  // %252F(browser) --> %2F(Rest) --> / ConfD
+  encodeUrlParam: function(value) {
+    var once = rw.api.singleEncodeUrlParam(value);
+    return once.replace(/%/g, '%25');
+  },
+
+  // UrlParam cannot have '/' and encoding it using %2F gets double-encoded in flask
+  singleEncodeUrlParam: function(value) {
+    return value.replace(/\//g, '%2F');
+  }
+};
+
+rw.api.SocketSubscriber = function(url) {
+  this.url = url;
+
+  this.id = ++rw.api.SocketSubscriber.uniqueId;
+
+  this.subscribed = false;
+  this.offlineRateMs = 2000;
+},
+
+rw.api.SocketSubscriber.uniqueId = 0;
+
+rw.api.SocketSubscriber.prototype = {
+
+  // does not support PUT/PORT with payloads requests yet
+  websubscribe : function(webUrl, onload, offline) {
+    this.subscribeMeta(onload, {
+      url: webUrl
+    }, offline);
+  },
+
+  subscribeMeta : function(onload, meta, offline) {
+    var self = this;
+
+    if (this.subscribed) {
+      this.unsubscribe();
+    }
+
+    var m = meta || {};
+    if (rw.api.offline) {
+      this.subscribeOffline(onload, m, offline);
+    } else {
+      this.subscribeOnline(onload, m);
+    }
+  },
+
+  subscribeOffline: function(onload, meta, offline) {
+    var self = this;
+    rw.api.json(meta.url).done(function(data) {
+      var _update = function() {
+        if (offline) {
+          offline(data);
+        } else {
+          onload(data);
+        }
+      };
+
+      this.offlineTimer = setInterval(_update, self.offlineRateMs);
+    });
+  },
+
+  subscribeOnline: function(onload, meta) {
+    var self = this;
+    var _subscribe = function() {
+      meta.widgetId = self.id;
+      meta.accept = meta.accept || 'application/json';
+      document.websocket().emit(self.url, meta);
+      self.subscribed = true;
+    };
+
+    var _register = function() {
+      document.websocket().on(self.url + '/' + self.id, function(dataString) {
+        var data = dataString;
+
+        // auto convert to object to make backward compatible
+        if (meta.accept.match(/[+\/]json$/) && dataString != '') {
+          data = JSON.parse(dataString);
+        }
+        onload(data);
+      });
+      _subscribe();
+    };
+    document.websocket().on('error',function(d){
+      console.log('socket error', d)
+    });
+    document.websocket().on('close',function(d){
+      console.log('socket close', d)
+    })
+    document.websocket().on('connect', _register);
+
+    // it's possible this call is not nec. and will always be called
+    // as part of connect statement above
+    _register();
+  },
+
+  unsubscribe : function() {
+    if (rw.api.offline) {
+      if (this.offlineTimer) {
+        clearInterval(this.offlineTimer);
+        this.offlineTimer = null;
+      }
+    } else {
+      var unsubscribe = { widgetId: this.id, enable: false };
+      document.websocket().emit(this.url, unsubscribe);
+      this.subscribed = false;
+    }
+  }
+};
+
+rw.api.server = rw.search_params['api_server'] || '';
+
+document.websocket = function() {
+  if ( ! this.socket ) {
+    //io.reconnection = true;
+    var wsServer = rw.api.server || 'http://' + document.domain + ':' + location.port;
+    var wsUrl = wsServer + '/rwapp';
+    this.socket = io.connect(wsUrl, {reconnection:true});
+  }
+  return this.socket;
+};
+
+rw.api.setOffline(rw.search_params['offline']);
+
+rw.vnf = {
+  ports: function(service) {
+    return _.flatten(jsonPath.eval(service, '$.connector[*].interface[*].port'));
+  },
+  fabricPorts: function(service) {
+    return _.flatten(jsonPath.eval(service, '$.vm[*].fabric.port'));
+  }
+};
+
+rw.VcsVisitor = function(enter, leave) {
+  this.enter = enter;
+  this.leave = leave;
+}
+
+rw.VcsVisitor.prototype = {
+
+  visit: function(node, parent, i, listType) {
+    var hasChildren = this.enter(parent, node, i, listType);
+    if (hasChildren) {
+      switch (rw.vcs.nodeType(node)) {
+        case 'rwsector':
+          this.visitChildren(node, node.collection, 'collection');
+          break;
+        case 'rwcolony':
+          this.visitChildren(node, node.collection, 'collection');
+          this.visitChildren(node, node.vm, 'vm');
+          break;
+        case 'rwcluster':
+          this.visitChildren(node, node.vm, 'vm');
+          break;
+        case 'RWVM':
+          this.visitChildren(node, node.process, 'process');
+          break;
+        case 'RWPROC':
+          this.visitChildren(node, node.tasklet, 'tasklet');
+          break;
+      }
+    }
+    if (this.leave) {
+      this.leave(parent, node, obj, i, listType);
+    }
+  },
+
+  visitChildren : function(parent, children, listType) {
+    if (!children) {
+      return;
+    }
+    var i = 0;
+    var self = this;
+    _.each(children, function(child) {
+      self.visit.call(self, child, parent, i, listType);
+      i += 1;
+    });
+  }
+};
+
+rw.vcs = {
+
+  allVms : function() {
+    return _.flatten([this.jpath('$.collection[*].vm'), this.jpath('$.collection[*].collection[*].vm')], true);
+  },
+
+  vms: function(n) {
+    if (n == undefined || n === null || n === this) {
+      return this.allVms();
+    }
+    switch (rw.vcs.nodeType(n)) {
+      case 'rwcolony':
+        return this.jpath('$.collection[*].vm[*]', n);
+      case 'rwcluster':
+        return this.jpath('$.vm[*]', n);
+      case 'RWVM':
+        return [n];
+      default:
+        return null;
+    }
+  },
+
+  nodeType: function(node) {
+    if (node.component_type === 'RWCOLLECTION') {
+      return node.collection_info['collection-type'];
+    }
+    return node.component_type;
+  },
+
+  allClusters : function() {
+    return this.jpath('$.collection[*].collection');
+  },
+
+  allColonies: function() {
+    return this.jpath('$.collection');
+  },
+
+  allPorts:function(n) {
+    switch (rw.vcs.nodeType(n)) {
+      case 'rwsector':
+        return this.jpath('$.collection[*].collection[*].vm[*].port[*]', n);
+      case 'rwcolony':
+        return this.jpath('$.collection[*].vm[*].port[*]', n);
+      case 'rwcluster':
+        return this.jpath('$.vm[*].port[*]', n);
+      case 'RWVM':
+        return this.jpath('$.port[*]', n);
+      default:
+        return null;
+    }
+  },
+
+  allFabricPorts:function(n) {
+    switch (rw.vcs.nodeType(n)) {
+      case 'rwsector':
+        return this.jpath('$.collection[*].collection[*].vm[*].fabric.port[*]', n);
+      case 'rwcolony':
+        return this.jpath('$.collection[*].vm[*].fabric.port[*]', n);
+      case 'rwcluster':
+        return this.jpath('$.vm[*].fabric.port[*]', n);
+      case 'RWVM':
+        return this.jpath('$.fabric.port[*]', n);
+      default:
+        return null;
+    }
+  },
+
+  getChildren: function(n) {
+    switch (rw.vcs.nodeType(n)) {
+      case 'rwcolony':
+        return 'vm' in n ? _.union(n.collection, n.vm) : n.collection;
+      case 'rwcluster':
+        return n.vm;
+      case 'RWVM':
+        return n.process;
+      case 'RWPROC':
+        return n.tasklet;
+    }
+    return [];
+  },
+
+  jpath : function(jpath, n) {
+    return _.flatten(jsonPath.eval(n || this, jpath), true);
+  }
+};
+
+rw.trafgen = {
+  startedActual : null, // true or false once server-side state is loaded
+  startedPerceived : false,
+  ratePerceived : 25,
+  rateActual : null, // non-null once server-side state is loaded
+  packetSizePerceived : 1024,
+  packetSizeActual: null
+};
+
+rw.trafsim = {
+  startedActual : null, // true or false once server-side state is loaded
+  startedPerceived : false,
+  ratePerceived : 50000,
+  rateActual : null, // non-null once server-side state is loaded
+  maxRate: 200000
+};
+
+rw.aggregateControlPanel = null;
+
+rw.theme = {
+  // purple-2 and blue-2
+  txBps : 'hsla(212, 57%, 50%, 1)',
+  txBpsTranslucent : 'hsla(212, 57%, 50%, 0.7)',
+  rxBps : 'hsla(212, 57%, 50%, 1)',
+  rxBpsTranslucent : 'hsla(212, 57%, 50%, 0.7)',
+  txPps : 'hsla(260, 35%, 50%, 1)',
+  txPpsTranslucent : 'hsla(260, 35%, 50%, 0.7)',
+  rxPps : 'hsla(260, 35%, 50%, 1)',
+  rxPpsTranslucent : 'hsla(260, 35%, 50%, 0.7)',
+  memory : 'hsla(27, 98%, 57%, 1)',
+  memoryTranslucent : 'hsla(27, 98%, 57%, 0.7)',
+  cpu : 'hsla(123, 45%, 50%, 1)',
+  cpuTranslucent : 'hsla(123, 45%, 50%, 0.7)',
+  storage : 'hsla(180, 78%, 25%, 1)',
+  storageTranslucent : 'hsla(180, 78%, 25%, 0.7)'
+};
+
+rw.RateTimer = function(onChange, onStop) {
+  this.rate = 0;
+  this.onChange = onChange;
+  this.onStop = onStop;
+  this.testFrequency = 500;
+  this.testWaveLength = 5000;
+  this.timer = null;
+  return this;
+};
+
+rw.RateTimer.prototype = {
+  start: function() {
+    this.rate = 0;
+    if (!this.timer) {
+      this.n = 0;
+      var strategy = this.smoothRateStrategy.bind(this);
+      this.testingStartTime = new Date().getTime();
+      this.timer = setInterval(strategy, this.testFrequency);
+    }
+  },
+
+  stop: function() {
+    if (this.timer) {
+      clearInterval(this.timer);
+      this.timer = null;
+      this.onStop();
+    }
+  },
+
+  smoothRateStrategy: function() {
+    var x = (new Date().getTime() - this.testingStartTime) / this.testWaveLength;
+    this.rate = Math.round(100 * 0.5 * (1 - Math.cos(x)));
+    // in theory you could use wavelength and frequency to determine stop but this
+    // is guaranteed to stop at zero.
+    this.onChange(this.rate);
+    this.n += 1;
+    if (this.n >= 10 && this.rate < 1) {
+      this.stop();
+    }
+  }
+};
+
+module.exports = rw;
diff --git a/skyquake/framework/utils/utils.js b/skyquake/framework/utils/utils.js
new file mode 100644 (file)
index 0000000..d08fe5f
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+//Login needs to be refactored. Too many cross dependencies
+var AuthActions = require('../widgets/login/loginAuthActions.js');
+var $ = require('jquery');
+var rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var NODE_PORT = 3000;
+var SockJS = require('sockjs-client');
+
+var Utils = {};
+
+Utils.DescriptorModelMeta = null;
+
+var INACTIVITY_TIMEOUT = 600000;
+
+Utils.getInactivityTimeout = function() {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            url: '/inactivity-timeout',
+            type: 'GET',
+            success: function(data) {
+                resolve(data);
+            },
+            error: function(error) {
+                console.log("There was an error getting the inactivity-timeout: ", error);
+                reject(error);
+            }
+        }).fail(function(xhr) {
+            console.log('There was an xhr error getting the inactivity-timeout', xhr);
+            reject(xhr);
+        });
+    });
+};
+
+Utils.isMultiplexerLoaded = function() {
+    if (window.multiplexer) {
+        return true;
+    }
+    return false;
+};
+
+Utils.setupMultiplexClient = function() {
+    var sockjs_url = '/multiplex';
+
+    var sockjs = new SockJS(sockjs_url);
+
+    var loadChecker = function() {
+        try {
+            window.multiplexer = new WebSocketMultiplex(sockjs);
+            console.log('WebSocketMultiplex loaded');
+        } catch (e) {
+            // caught an error, retry in someTime
+            console.log('WebSocketMultiplex not loaded yet. will try again in 1 second:', e);
+            setTimeout(function() {
+                loadChecker();
+            }, 1000);
+        }
+    }
+    loadChecker();
+};
+
+Utils.checkAndResolveSocketRequest = function(data, resolve, reject) {
+    const checker = () => {
+        if (!Utils.isMultiplexerLoaded()) {
+            setTimeout(() => {
+                checker();
+            }, 500);
+        } else {
+            resolve(data.id);
+        }
+    };
+
+    checker();
+};
+
+Utils.bootstrapApplication = function() {
+    var self = this;
+    return new Promise(function(resolve, reject) {
+        Promise.all([self.getInactivityTimeout()]).then(function(results) {
+            INACTIVITY_TIMEOUT = results[0]['inactivity-timeout'];
+            resolve();
+        }, function(error) {
+            console.log("Error bootstrapping application ", error);
+            reject();
+        });
+    });
+};
+
+Utils.getDescriptorModelMeta = function() {
+    return new Promise(function(resolve, reject) {
+        if (!Utils.DescriptorModelMeta) {
+            $.ajax({
+                url: '/descriptor-model-meta?api_server=' + API_SERVER,
+                type: 'GET',
+                beforeSend: Utils.addAuthorizationStub,
+                success: function(data) {
+                    Utils.DescriptorModelMeta = data;
+                    Utils.DescriptorModelMetaLoaded = true;
+                    resolve(data);
+                },
+                error: function(error) {
+                    console.log("There was an error getting the schema: ", error);
+                    reject(error);
+                }
+            }).fail(function(xhr) {
+                console.log("There was an error getting the schema: ", xhr);
+                Utils.checkAuthentication(xhr.status);
+            });
+        } else {
+            resolve(Utils.DescriptorModelMeta);
+        }
+    })
+}
+
+Utils.addAuthorizationStub = function(xhr) {
+    var Auth = window.sessionStorage.getItem("auth");
+    xhr.setRequestHeader('Authorization', 'Basic ' + Auth);
+};
+
+Utils.getByteDataWithUnitPrefix = function(number, precision) {
+    var toPrecision = precision || 3;
+    if (number < Math.pow(10, 3)) {
+        return [number, 'B'];
+    } else if (number < Math.pow(10, 6)) {
+        return [(number / Math.pow(10, 3)).toPrecision(toPrecision), 'KB'];
+    } else if (number < Math.pow(10, 9)) {
+        return [(number / Math.pow(10, 6)).toPrecision(toPrecision), 'MB'];
+    } else if (number < Math.pow(10, 12)) {
+        return [(number / Math.pow(10, 9)).toPrecision(toPrecision), 'GB'];
+    } else if (number < Math.pow(10, 15)) {
+        return [(number / Math.pow(10, 12)).toPrecision(toPrecision), 'TB'];
+    } else if (number < Math.pow(10, 18)) {
+        return [(number / Math.pow(10, 15)).toPrecision(toPrecision), 'PB'];
+    } else if (number < Math.pow(10, 21)) {
+        return [(number / Math.pow(10, 18)).toPrecision(toPrecision), 'EB'];
+    } else if (number < Math.pow(10, 24)) {
+        return [(number / Math.pow(10, 21)).toPrecision(toPrecision), 'ZB'];
+    } else if (number < Math.pow(10, 27)) {
+        return [(number / Math.pow(10, 24)).toPrecision(toPrecision), 'ZB'];
+    } else {
+        return [(number / Math.pow(10, 27)).toPrecision(toPrecision), 'YB'];
+    }
+}
+
+Utils.getPacketDataWithUnitPrefix = function(number, precision) {
+    var toPrecision = precision || 3;
+    if (number < Math.pow(10, 3)) {
+        return [number, 'P'];
+    } else if (number < Math.pow(10, 6)) {
+        return [(number / Math.pow(10, 3)).toPrecision(toPrecision), 'KP'];
+    } else if (number < Math.pow(10, 9)) {
+        return [(number / Math.pow(10, 6)).toPrecision(toPrecision), 'MP'];
+    } else if (number < Math.pow(10, 12)) {
+        return [(number / Math.pow(10, 9)).toPrecision(toPrecision), 'GP'];
+    } else if (number < Math.pow(10, 15)) {
+        return [(number / Math.pow(10, 12)).toPrecision(toPrecision), 'TP'];
+    } else if (number < Math.pow(10, 18)) {
+        return [(number / Math.pow(10, 15)).toPrecision(toPrecision), 'PP'];
+    } else if (number < Math.pow(10, 21)) {
+        return [(number / Math.pow(10, 18)).toPrecision(toPrecision), 'EP'];
+    } else if (number < Math.pow(10, 24)) {
+        return [(number / Math.pow(10, 21)).toPrecision(toPrecision), 'ZP'];
+    } else if (number < Math.pow(10, 27)) {
+        return [(number / Math.pow(10, 24)).toPrecision(toPrecision), 'ZP'];
+    } else {
+        return [(number / Math.pow(10, 27)).toPrecision(toPrecision), 'YP'];
+    }
+}
+Utils.loginHash = "#/login";
+Utils.setAuthentication = function(username, password, cb) {
+    var self = this;
+    var AuthBase64 = btoa(username + ":" + password);
+    window.sessionStorage.setItem("auth", AuthBase64);
+    self.detectInactivity();
+    if (cb) {
+        cb();
+    }
+}
+Utils.clearAuthentication = function(callback) {
+    var self = this;
+    window.sessionStorage.removeItem("auth");
+    AuthActions.notAuthenticated();
+    window.sessionStorage.setItem("locationRefHash", window.location.hash);
+    if (callback) {
+        callback();
+    } else {
+        window.location.hash = Utils.loginHash;
+    }
+}
+Utils.isNotAuthenticated = function(windowLocation, callback) {
+    var self = this;
+    self.detectInactivity();
+    if (!window.sessionStorage.getItem("auth")) {
+        Utils.clearAuthentication();
+    }
+}
+Utils.isDetecting = false;
+Utils.detectInactivity = function(callback, duration) {
+    var self = this;
+    if (!self.isDetecting) {
+        var cb = function() {
+            self.clearAuthentication();
+            if (callback) {
+                callback();
+            }
+        };
+        var isInactive;
+        var timeout = duration || INACTIVITY_TIMEOUT;
+        var setInactive = function() {
+            isInactive = setTimeout(cb, timeout);
+        };
+        var reset = function() {
+            clearTimeout(isInactive);
+            setInactive();
+        }
+        setInactive();
+        window.addEventListener('mousemove', reset);
+        window.addEventListener("keypress", reset);
+        self.isDetecting = true;
+    }
+}
+Utils.checkAuthentication = function(statusCode, cb) {
+    var self = this;
+    if (statusCode == 401) {
+        if (cb) {
+            cb();
+        }
+        window.sessionStorage.removeItem("auth")
+        self.isNotAuthenticated(window.location)
+        return true;
+    }
+    return false;
+}
+
+Utils.isAuthenticationCached = function() {
+    var self = this;
+    if (window.sessionStorage.getItem("auth")) {
+        return true;
+    }
+    return false;
+}
+
+Utils.getHostNameFromURL = function(url) {
+    var match = url.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([^?#]*)(\?[^#]*|)(#.*|)$/);
+    return match && match[3];
+}
+
+Utils.webSocketProtocol = function() {
+    if (this.wsProto) {
+        return this.wsProto;
+    } else {
+        if (window.location.protocol == 'http:') {
+            this.wsProto = 'ws:'
+        } else {
+            this.wsProto = 'wss:'
+        }
+    }
+    return this.wsProto;
+}
+
+Utils.arrayIntersperse = (arr, sep) => {
+    if (arr.length === 0) {
+        return [];
+    }
+
+    return arr.slice(1).reduce((xs, x, i) => {
+        return xs.concat([sep, x]);
+    }, [arr[0]]);
+}
+
+module.exports = Utils;
diff --git a/skyquake/framework/widgets/JSONViewer/JSONViewer.js b/skyquake/framework/widgets/JSONViewer/JSONViewer.js
new file mode 100644 (file)
index 0000000..2f8c0a8
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * Created by onvelocity on 2/2/16.
+ */
+
+import React from 'react'
+import Prism from 'prismjs'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+
+import './JSONViewer.scss'
+
+const YAML = require('json2yaml');
+
+const cssString = `
+                               html, body {
+                                       padding:0;
+                                       margin:0;
+                               }
+                                       /*
+                                        copied from node_modules/prismjs/themes/prismjs.css
+                                        */
+                                       :not(pre) > code[class*="language-"],
+                                       pre[class*="language-"] {
+                                       font-size: 12px;
+                                       padding:1rem;
+                                       /*
+                                       border: 1px solid rgba(220, 220, 220, 0.5);
+                                       border-radius: 4px;
+                                       */
+                                       background-color: rgba(255, 255, 255, .25);
+                               }
+
+                                       /* Inline code */
+                                       :not(pre) > code[class*="language-"] {
+                                       padding: .1em;
+                               }
+
+                                       .token.comment,
+                                       .token.prolog,
+                                       .token.doctype,
+                                       .token.cdata {
+                                       color: slategray;
+                               }
+
+                                       .token.punctuation {
+                                       color: #333;
+                               }
+
+                                       .namespace {
+                                       opacity: .7;
+                               }
+
+                                       .token.property,
+                                       .token.tag,
+                                       .token.boolean,
+                                       .token.number,
+                                       .token.constant,
+                                       .token.symbol,
+                                       .token.deleted {
+                                       color: #905;
+                               }
+
+                                       .token.selector,
+                                       .token.attr-name,
+                                       .token.string,
+                                       .token.char,
+                                       .token.builtin,
+                                       .token.inserted {
+                                       color: #df5000;
+                               }
+
+                                       .token.operator,
+                                       .token.entity,
+                                       .token.url,
+                                       .language-css .token.string,
+                                       .style .token.string {
+                                       color: #a67f59;
+                               }
+
+                                       .token.atrule,
+                                       .token.attr-value,
+                                       .token.keyword {
+                                       color: #07a;
+                               }
+
+                                       .token.function {
+                                       color: #DD4A68;
+                               }
+
+                                       .token.regex,
+                                       .token.important,
+                                       .token.variable {
+                                       color: #e90;
+                               }
+
+                                       .token.important,
+                                       .token.bold {
+                                       font-weight: bold;
+                               }
+                                       .token.italic {
+                                       font-style: italic;
+                               }
+
+                                       .token.entity {
+                                       cursor: help;
+                               }
+`;
+
+const JSONViewer = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState: function () {
+               return {};
+       },
+       getDefaultProps: function () {
+               return {};
+       },
+       componentWillMount: function () {
+       },
+       componentDidMount: function () {
+       },
+       componentDidUpdate: function () {
+       },
+       componentWillUnmount: function () {
+       },
+       render() {
+               const text = YAML.stringify(this.props.json, undefined, 12).replace(/    /g, '     ');
+               const result = Prism.highlight(text, Prism.languages.javascript, 'javascript');
+               return (
+                       <div className="JSONViewer">
+                               <style dangerouslySetInnerHTML={{__html: cssString}}></style>
+                               <label className="descriptor">
+                                       <pre className="language-js">
+                                               <code dangerouslySetInnerHTML={{__html: result}} />
+                                       </pre>
+                               </label>
+                       </div>
+               );
+       }
+});
+
+export default JSONViewer;
diff --git a/skyquake/framework/widgets/JSONViewer/JSONViewer.scss b/skyquake/framework/widgets/JSONViewer/JSONViewer.scss
new file mode 100644 (file)
index 0000000..08fcefd
--- /dev/null
@@ -0,0 +1,104 @@
+.JSONViewer {
+       /*
+       copied from node_modules/prismjs/themes/prismjs.css
+*/
+       :not(pre) > code[class*="language-"],
+       pre[class*="language-"] {
+               font-size: 12px;
+               /* border: 1px solid rgba(220, 220, 220, 0.5);*/
+               border-radius: 4px;
+               background-color: rgba(255, 255, 255, .25);
+               overflow:auto;
+       }
+
+       /* Inline code */
+       :not(pre) > code[class*="language-"] {
+               padding: .1em;
+       }
+
+       .token.comment,
+       .token.prolog,
+       .token.doctype,
+       .token.cdata {
+               color: slategray;
+       }
+
+       .token.punctuation {
+               color: #333;
+       }
+
+       .namespace {
+               opacity: .7;
+       }
+
+       .token.property,
+       .token.tag,
+       .token.boolean,
+       .token.number,
+       .token.constant,
+       .token.symbol,
+       .token.deleted {
+               color: #905;
+       }
+
+       .token.selector,
+       .token.attr-name,
+       .token.string,
+       .token.char,
+       .token.builtin,
+       .token.inserted {
+               color: #df5000;
+       }
+
+       .token.operator,
+       .token.entity,
+       .token.url,
+       .language-css .token.string,
+       .style .token.string {
+               color: #a67f59;
+               background: none !important;
+       }
+
+       .token.atrule,
+       .token.attr-value,
+       .token.keyword {
+               color: #07a;
+       }
+
+       .token.function {
+               color: #DD4A68;
+       }
+
+       .token.regex,
+       .token.important,
+       .token.variable {
+               color: #e90;
+       }
+
+       .token.important,
+       .token.bold {
+               font-weight: bold;
+       }
+       .token.italic {
+               font-style: italic;
+       }
+
+       .token.entity {
+               cursor: help;
+       }
+}
+
+.composerPopout {
+       background-color: #f1f1f1;
+       h1 {
+                       height: 51px;
+                       line-height: 51px;
+                       margin-left: 80px;
+                       padding-left: 118px;
+                       position: absolute;
+                       left: 0;
+                       text-transform: uppercase;
+                       font-size: 1.625rem;
+                       font-weight: normal;
+       }
+}
diff --git a/skyquake/framework/widgets/bullet/bullet.js b/skyquake/framework/widgets/bullet/bullet.js
new file mode 100644 (file)
index 0000000..1411f0f
--- /dev/null
@@ -0,0 +1,230 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+var mixin = require('../mixins/ButtonEventListener.js')
+//TODO: Many values are hard coded, need to make bullet "smarter"
+/**
+ *  A bullet graph component.
+ *  It's props values and a brief description below
+ *
+ *  vertical: If true, the bar rises and falls vertically
+ *  value:    The value displayed
+ *  min:      The minimum value expected
+ *  max:      The maximum value expected
+ *  bulletColor: The fill color of the value section of the graph
+ *  radius:   Radius of graph corners.
+ *  containerMarginX: Container's margin along x-axis
+ *  containerMarginY: Container's margin along y-axis
+ *  width:    Width of bullet graph in pixels
+ *  height:   Height of bullet graph in pixels
+ *  fontSize:  Font size of text in pixels
+ *  textMarginX: margin for text on x-axis
+ *  textMarginY: Margin for text on y-axis
+ *  units:    units displayed. Also changes whether a max value is displayed.
+ **/
+module.exports = React.createClass({
+  displayName: 'Bullet',
+  mixins:mixin.MIXINS,
+  propTypes: {
+    vertical: React.PropTypes.bool,
+    value: React.PropTypes.number,
+    min: React.PropTypes.number,
+    max: React.PropTypes.number,
+    bulletColor: React.PropTypes.string,
+    radius: React.PropTypes.number,
+    containerMarginX: React.PropTypes.number,
+    containerMarginY: React.PropTypes.number,
+    bulletMargin: React.PropTypes.number,
+    width: React.PropTypes.number,
+    height: React.PropTypes.number,
+    markerX: React.PropTypes.number,
+    fontSize: React.PropTypes.number,
+    textMarginX: React.PropTypes.number,
+    textMarginY: React.PropTypes.number,
+    units: React.PropTypes.string
+  },
+
+  getDefaultProps: function() {
+    return {
+        vertical: false,
+        value: 0,
+        min: 0,
+        max: 100,
+        bulletColor: "blue",
+        radius: 4,
+        containerMarginX: 0,
+        containerMarginY: 0,
+        bulletMargin: 0,
+        width: 512,
+        height: 64,
+        markerX: -100,
+        fontSize: 16,
+        textMarginX: 5,
+        textMarginY: 42,
+        units:''
+    }
+  },
+
+  /**
+   * Defines default state.
+   * value: The value displayed
+   */
+  getInitialState: function() {
+    return {
+        value: this.props.value
+    }
+  },
+
+  /**
+   * Called when the props are updated.
+   * Syncs the state value with the prop value.
+   * @params nextProps
+   */
+  componentWillReceiveProps: function(nextProps) {
+    this.setState({value:nextProps.value || this.state.value})
+  },
+
+  /**
+   * Before the component will mount, the width value is recalculed based on browser.
+   */
+  componentWillMount: function() {
+        var isIE = false || !!document.documentMode;
+        var range = this.props.max - this.props.min;
+        var normalizedValue = (this.state.value - this.props.min) / range;
+        this.isPercent = (!this.props.units || this.props.units == '')? true:false
+        if (isIE) {
+            this.bulletWidth = String(Math.round(100 * normalizedValue)) + "%";
+        } else {
+            this.bulletWidth = this.props.width - (2 * this.props.containerMarginX);
+        }
+        this.displayValue = (this.isPercent)? String(Math.round(normalizedValue * 100)) + "%" : this.props.value
+
+  },
+
+  /**
+   * When the component mounts, this function sets the animation for smooth transition on value change.  This only
+   * happens if the user's browser is not IE.
+   */
+  componentDidMount: function() {
+        var isIE = false || !!document.documentMode;
+        var range = this.props.max - this.props.min;
+        var normalizedValue = (this.state.value - this.props.min) / range;
+        if (!isIE) {
+            var transform = "scaleX(" + normalizedValue + ")";
+            var bullet = React.findDOMNode(this.refs.bulletRef);
+            bullet.style.transform = transform;
+            bullet.style["-webkit-transform"] = transform;
+        }
+  },
+
+  /**
+   * On update, reaplies transformation and width changes made in componentWillMount and componentDidMount
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+
+    if (String(this.state.value) == String(nextState.value)) {
+      return false;
+    } else {
+        var isIE = false || !!document.documentMode;
+        var range = this.props.max - this.props.min;
+        var normalizedValue = (nextState.value - this.props.min) / range;
+
+        if (isIE) {
+            this.bulletWidth = String(Math.round(100 * normalizedValue)) + "%";
+        } else {
+            this.bulletWidth = this.props.width - (2 * this.props.containerMarginX);
+            var transform = "scaleX(" + normalizedValue + ")";
+            var bullet = React.findDOMNode(this.refs.bulletRef);
+            bullet.style.transform = transform;
+            bullet.style["-webkit-transform"] = transform;
+        }
+        this.displayValue = (this.isPercent)? String(Math.round(normalizedValue * 100)) + "%" : nextState.value
+
+        return true;
+    }
+  },
+
+
+
+  /**
+   * Renders the Bullet Component
+   * @returns {*}
+   */
+  render: function() {
+
+    // The text element that displays the difference between the max value and the current value.
+    var maxDOMEl = (!this.isPercent)? null : React.createElement("text", {
+                //X needs better logic
+                // x: this.props.width - this.props.height * 1.25,
+                x: this.props.width - (130 - this.props.textMarginX),
+                y: this.props.textMarginY,
+                fontFamily: "Verdana",
+                fontSize: this.props.fontSize,
+                fill: "#ffffff"}, String(this.props.max - this.state.value) + "%");
+
+
+        // The main bullet element.  Made up of a static black rect in the background,
+        // a moving colored rect overlayed on top and a text element for the current value.
+        var bulletDOM = React.createElement("svg", {
+            width: "100%",
+            height: "100%",
+            viewBox: "0 0 512 " + this.props.height,
+            preserveAspectRatio: "none"},
+          React.createElement("rect", {className: "bullet-container",
+                width: this.props.width - (2 * this.props.containerMarginX),
+                height: this.props.height - (2 * this.props.containerMarginY),
+                x: this.props.containerMarginX,
+                y: this.props.containerMarginY,
+                rx: this.props.radius,
+                ry: this.props.radius}, null),
+          React.createElement("svg", {
+              x: this.props.containerMarginX,
+              y: this.props.bulletMargin},
+            React.createElement("rect", {
+                className: "bullet",
+                ref:"bulletRef",
+                fill: this.props.bulletColor,
+                width: this.bulletWidth,
+                height: this.props.height - (2 * this.props.bulletMargin),
+                rx: this.props.radius,
+                ry: this.props.radius
+            })
+          ),
+          React.createElement("line", {className: "bullet-marker",
+                x1: this.props.markerX,
+                x2: this.props.markerX,
+                y1: this.props.markerY1,
+                y2: this.props.markerY2}),
+            React.createElement("text", {
+                x: this.props.textMarginX,
+                y: this.props.textMarginY,
+                "fontFamily": "Verdana",
+              "fontSize": this.props.fontSize,
+              fill: "#ffffff"}, this.displayValue
+              ),
+            maxDOMEl
+        );
+
+
+    return bulletDOM;
+  }
+});
diff --git a/skyquake/framework/widgets/button/button.scss b/skyquake/framework/widgets/button/button.scss
new file mode 100644 (file)
index 0000000..c972e14
--- /dev/null
@@ -0,0 +1,270 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import '../../style/_colors.scss';
+@import '../../style/variables.scss';
+
+button{
+    color: #000000;
+    display: inline-block;
+    font-size: 0.75rem;
+    padding: 0.75rem 3rem;
+    text-decoration: none;
+    text-transform: uppercase;
+    box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+    cursor: pointer;
+    margin:0 1rem;
+  &.light {
+    background-color: #ffffff;
+    border: 1px solid #cccccc;
+    border-top: 0;
+    &.small {
+      padding:0.25rem 1rem;
+    }
+  }
+
+  &.dark {
+    background-color: #333333;
+    border: 1px solid #000000;
+    border-top: 0;
+    color: #ffffff;
+    &:hover,&:active {
+      background: #00acee;
+      color: #ffffff;
+    }
+  }
+
+
+}
+
+/* IMPORTS
+############################################################################ */
+
+
+
+
+/* BUTTON
+############################################################################ */
+
+.SqButton {
+  align-items: center;
+  border-style: solid;
+  border-radius: 3px;
+  border-width: 0px;
+  cursor: pointer;
+  display: inline-flex;
+  font-size: 1rem;
+  height: 50px;
+  justify-content: center;
+  margin: 0 10px;
+  outline: none;
+  padding: 0 15px;
+  text-transform: uppercase;
+  transition: $transition;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  user-select: none;
+
+  /* Button Content */
+  &-content {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    transition: $transition;
+    white-space: nowrap;
+  }
+
+  /* Button Icon */
+  &-icon {
+    transition: $transition;
+  }
+
+  /* Spacing between content and icon when icon is on the right */
+  &-icon + &-content {
+    margin-left: 10px;
+  }
+
+  /* Spacing between content and icon when icon is on the left */
+  &-content + &-icon {
+    margin-left: 10px;
+  }
+
+  /* Focus */
+  &:focus {
+    // box-shadow: $focus-shadow;
+    border: 1px solid red;
+  }
+
+  /* SIZES
+  ############################################################################ */
+
+  &--large {
+    width: 250px;
+  }
+
+  &--medium {
+    width: 175px;
+  }
+
+  &--small {
+    width: 85px;
+  }
+
+  /* NORMAL
+  ############################################################################ */
+
+  /* Base */
+  &--normal {
+    background: $normalBackground;
+    border-color: darken($normalBackground, 10%);
+
+    .SqButton-content {
+      color: $normalForeground;
+    }
+
+    .SqButton-icon {
+      fill: $normalForeground;
+    }
+  }
+
+  /* Hover */
+  &--normal:hover {
+    background: $normalHoverBackground;
+    border-color: darken($normalHoverBackground, 10%);
+
+    .SqButton-content {
+      color: $normalHoverForeground;
+    }
+
+    .SqButton-icon {
+      fill: $normalHoverForeground;
+    }
+  }
+
+  /* Active */
+  &--normal:active {
+    background: $normalActiveBackground;
+    border-color: darken($normalActiveBackground, 10%);
+
+    .SqButton-content {
+      color: $normalActiveForeground;
+    }
+
+    .SqButton-icon {
+      fill: $normalActiveForeground;
+    }
+  }
+
+  /* Disabled */
+  &--normal.is-disabled {
+    cursor: default;
+    opacity: .55;
+  }
+
+  &--normal:hover.is-disabled,
+  &--normal:active.is-disabled {
+    background: $normalBackground;
+    border-color: darken($normalBackground, 10%);
+
+    .SqButton-content {
+      color: $normalForeground;
+    }
+
+    .SqButton-icon {
+      fill: $normalForeground;
+    }
+  }
+
+
+  /* PRIMARY
+  ############################################################################ */
+
+  /* Base */
+  &--primary {
+    background: $primaryBackground;
+    border-color: darken($primaryBackground, 10%);
+
+    .SqButton-content {
+      color: $primaryForeground;
+    }
+
+    .SqButton-icon {
+      fill: $primaryForeground;
+    }
+  }
+
+  /* Hover */
+  &--primary:hover {
+    background: $primaryHoverBackground;
+    border-color: darken($primaryHoverBackground, 10%);
+
+    .SqButton-content {
+      color: $primaryHoverForeground;
+    }
+
+    .SqButton-icon {
+      fill: $primaryHoverForeground;
+    }
+  }
+
+  /* Active */
+  &--primary:active {
+    background: $primaryActiveBackground;
+    border-color: darken($primaryActiveBackground, 10%);
+
+    .SqButton-content {
+      color: $primaryActiveForeground;
+    }
+
+    .SqButton-icon {
+      fill: $primaryActiveForeground;
+    }
+  }
+
+  /* Disabled */
+  &--primary.is-disabled {
+    cursor: default;
+    opacity: .55;
+  }
+
+  &--primary:hover.is-disabled,
+  &--primary:active.is-disabled {
+    background: $primaryBackground;
+    border-color: darken($primaryBackground, 10%);
+
+    .SqButton-content {
+      color: $primaryForeground;
+    }
+
+    .SqButton-icon {
+      fill: $primaryForeground;
+    }
+  }
+
+
+}
+
+
+
+
+
+
+
+
+
diff --git a/skyquake/framework/widgets/button/rw.button.js b/skyquake/framework/widgets/button/rw.button.js
new file mode 100644 (file)
index 0000000..41730eb
--- /dev/null
@@ -0,0 +1,261 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import './button.scss';
+import Loader from '../loading-indicator/loadingIndicator.jsx';
+var React = require('react');
+var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
+
+
+/**
+ *  A generic button component.
+ *  It's props values and a brief description below
+ *
+ *  Label: The label of the button. What it displays at any given time.
+ *  Icon: A url for an icon that will be displayed on the button.  Leave blank if no icon required.
+ *  Class: Css Classes applied to the element.
+ *  sizeOfButton: The preset sizes for the button (small, default, large, xlarge, expand).
+ *  minWidth: Minimum Width of the button.
+ *  maxWidth: Maximum Width of the button.
+ **/
+module.exports = React.createClass({
+  displayName: "Button",
+  mixins:[ButtonEventListenerMixin],
+  propTypes: {
+    label:           React.PropTypes.string,
+    icon:            React.PropTypes.array,
+    className:       React.PropTypes.string,
+    //sizeOfButton:    React.PropTypes.string,
+    minWidth:        React.PropTypes.string,
+    maxWidth:        React.PropTypes.string,
+    //isActive:        React.PropTypes.bool,
+    //isFocused:       React.PropTypes.bool,
+    //isHovered:       React.PropTypes.bool,
+    isDisabled:      React.PropTypes.bool
+  },
+
+
+  /**
+   * Defines default state.
+   * sizeOfButton: See Prop type definitions.
+   * class: See Prop type definitions.
+   * label: See Prop type definitions.
+   * isActive: Boolean to indicate if button is active.
+   * isHovered: Boolean to indicate if the button is being hovered over.
+   * isFocused: Boolean to indicate if the button has been focused.
+   * isDisabled: Boolean to indicate if button has been disabled.
+   * @returns {{sizeOfButton: (*|string), class: *, isActive: boolean, isHovered: boolean,
+   *            isFocused: boolean, isDisabled: (*|boolean), label: *}}
+   */
+  getInitialState: function() {
+    return {
+      //sizeOfButton:   this.props.size || '',  //There is no Medium value in CSS, default size is the absence of a value
+      className:      this.props.className || 'rw-button-primary', //Default value is 'rw-button-primary' which is the primary one
+      label:          this.props.label,
+      isActive:       false,
+      isHovered:      false,
+      isFocused:      false,
+      isLoading:      this.props.isLoading || false,
+      isDisabled:     this.props.isDisabled || false
+    }
+  },
+
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
+   * "this.props" and "this.state" hold the state and property variables as they were before the update.
+   * returns true if the state have changed. Otherwise returns false.
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = this.state.label + this.state.isDisabled + this.state.isActive + this.state.isFocused +
+      this.state.isHovered + this.props.isLoading;
+    var nextStateString = nextState.label + nextState.isDisabled + nextState.isActive + nextState.isFocused +
+      nextState.isHovered + nextProps.isLoading;
+
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    return true;
+  },
+
+
+  /**
+   * Returns a string reflecting the current state of the button.
+   * If the button state "isDisabled" is true, returns a string "disabled".
+   * Otherwise returns a string containing a word for each state that has been set to true.
+   * (ie "active focused" if the states active and focused are true, but hovered is false).
+   * @returns {string}
+   */
+  setButtonState: function() {
+    var ret = "";
+    if (this.state.isDisabled) {
+      return "disabled";
+    }
+    if (this.state.isActive) {
+      ret += "active ";
+    }
+    if (this.state.isHovered) {
+      ret += "hovered ";
+    }
+    if (this.state.isFocused) {
+      ret += "focused ";
+    }
+    return ret;
+  },
+
+
+
+  /**
+   * Track the width if set and write into markup using Style attribute
+   * Returns the minWidth and maxWidth prop in a string
+   * @returns {{}}
+   */
+  setButtonWidth:function(){

+    var width = {};


+
+    if (this.props.minWidth) {

+      width.minWidth = String(this.props.minWidth);

+    }

+    if (this.props.maxWidth) {

+      width.maxWidth = String(this.props.maxWidth);

+    }

+
+    return width;

+  },
+
+
+
+  /**
+   * Apply the size of the button to the icon directly
+   * Returns a string indicating the icon size.
+   * @returns {string}
+   */
+  /*
+  setIconSize:function(){
+
+    var iconClass = "rw-icon";
+
+    if(this.props.size){
+      iconClass += "-" + this.props.size;
+    }
+    return iconClass;
+  },
+  */
+
+
+
+  /**
+   * Builds the list of classes.
+   * Returns a string holding each class seperated by a space.
+   * @returns {string}
+   */
+  /*
+  setButtonClass:function() {
+    var buttonClass = "";
+    var buttonClassType = "rw-button-primary";
+    // If the size is declared, add it in
+    if (this.state.sizeOfButton) {
+      buttonClass += this.state.sizeOfButton;
+    }
+    //
+    if (typeof(this.props.className) != "undefined") {
+      this.props.className.push("rw-button-secondary");
+
+      // Run through the array and check all the values
+      for (var i = 0; i < this.props.className.length; i++) {
+
+        if (this.props.className[i].indexOf("secondary") > -1) {
+          buttonClassType = "rw-button-secondary";  // If the value of the array is equal to the string "secondary", add a predefined string
+        } else {
+          buttonClass += " " + this.props.className[i];  // Else just write the value of the array
+        }
+      }
+    }
+    buttonClass += " " + buttonClassType;  //Add the button style type either primary or secondary
+    return buttonClass;
+  },
+  */
+
+  /**
+   * Builds an array of html elements for the icons and returns them.
+   * @returns {Array}
+   */
+  setIconElement: function() {
+    var button_icon = [];
+
+    if (typeof(this.props.icon) != "undefined") {
+      for (var i = 0; i < this.props.icon.length; i++) {
+        button_icon.push(React.createElement('svg', {
+          className: "rw-button__icon",
+          key: i,
+          dangerouslySetInnerHTML: {__html: '<use xlink:href="#' + this.props.icon[i] + '" />'}  //Using a React method to drop in a hack since React does not support xlink:href yet
+        }));
+      }
+    }
+    return button_icon;
+  },
+
+  /**
+   * Renders the Button Component
+   * Returns a react component that constructs the html that houses the button component.
+   * @returns {*}
+   */
+  render: function() {
+    var button = null;
+    var button_style = this.setButtonWidth();
+    var button_state = this.setButtonState();
+    var button_class = this.state.className;
+    var button_icon = this.setIconElement();
+    var display = this.state.label;
+    if (this.props.isLoading) {
+      display = React.createElement(Loader, {show: true, size: '1rem', color: this.props.loadingColor});
+    }
+
+    button = React.createElement("button", {
+        className:         button_class,
+        "data-state":      button_state,
+        style:             button_style,
+
+        // onClick:           this.onClick,
+        onClick:           this.props.onClick,
+        onMouseUp:         this.onMouseUp,
+        onMouseDown:       this.onMouseDown,
+        onMouseOver:       this.onMouseOver,
+        onMouseEnter:      this.onMouseEnter,
+        onMouseLeave:      this.onMouseLeave,
+        onMouseOut:        this.onMouseOut,
+        onTouchCancel:     this.onTouchCancel,
+        onTouchEnd:        this.onTouchEnd,
+        onTouchMove:       this.onTouchMove,
+        onTouchStart:      this.onTouchStart,
+        onKeyDown:         this.onKeyDown,
+        onKeyPress:        this.onKeyPress,
+        onKeyUp:           this.onKeyUp,
+        onFocus:           this.onFocus,
+        onBlur:            this.onBlur
+      },
+      button_icon,
+      React.createElement("span", {className: "rw-button__label"}, display)
+    );
+    return button;
+  }
+});
diff --git a/skyquake/framework/widgets/button/sq-button.jsx b/skyquake/framework/widgets/button/sq-button.jsx
new file mode 100644 (file)
index 0000000..ae93128
--- /dev/null
@@ -0,0 +1,55 @@
+import React from 'react';
+
+import 'style/base.scss';
+import './button.scss';
+
+const icons = {
+    check: require("style/icons/svg-sprite-navigation-symbol.svg")  + "#ic_check_24px"
+}
+
+export default class SqButton extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let {icon, primary, size, disabled, label, ...props} = this.props;
+        let svgHTML = null;
+        let Class = "SqButton";
+        if(icon) {
+            svgHTML = <svg className="svg-24px SqButton-icon">
+            <use xlinkHref={icons[icon]}></use></svg>;
+        }
+        if(primary) {
+            Class += " SqButton--primary";
+        } else {
+            Class += " SqButton--normal";
+        }
+        if(size && (
+                size == 'small'
+                || size == 'medium'
+                || size == 'large'
+                )
+            ) {
+            Class += " SqButton--" + size;
+        }
+        if(disabled) {
+            Class += " is-disabled";
+        }
+        return (
+                <div style={{display: 'flex'}}>
+            <div className={Class} tabIndex="0">
+            {svgHTML}
+              <div className="SqButton-content">{label}</div>
+            </div>
+            </div>
+        )
+    }
+}
+
+SqButton.defaultProps = {
+    icon: false,
+    primary: false,
+    disabled: false,
+    size: false, // 'small', 'medium', 'large'
+    label: 'Submit'
+}
diff --git a/skyquake/framework/widgets/components.js b/skyquake/framework/widgets/components.js
new file mode 100644 (file)
index 0000000..1fe49bc
--- /dev/null
@@ -0,0 +1,380 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+//var Histogram = require('react-d3-histogram')
+export default {
+  //test: require('./test/test.js'),
+  button: require('./button/rw.button.js'),
+  React: React,
+//  Histogram: Histogram,
+  Multicomponent: require('./multicomponent/multicomponent.js'),
+  Mixins: require('./mixins/ButtonEventListener.js'),
+  Gauge: require('./gauge/gauge.js'),
+  Bullet: require('./bullet/bullet.js')
+};
+
+// require('../../assets/js/n3-line-chart.js');
+// var Gauge = require('../../assets/js/gauge-modified.js');
+// var bulletController = function($scope, $element) {
+//     this.$element = $element;
+//     this.vertical = false;
+//     this.value = 0;
+//     this.min = 0;
+//     this.max = 100;
+//     //this.range = this.max - this.min;
+//     //this.percent = (this.value - this.min) / this.range;
+//     this.displayValue = this.value;
+//     this.isPercent = (this.units == '')? true:false;
+//     this.bulletColor = "#6BB814";
+//     this.fontsize = 28;
+//     this.radius = 4;
+//     this.containerMarginX = 0;
+//     this.containerMarginY = 0;
+//     this.textMarginX = 5;
+//     this.textMarginY = 42;
+//     this.bulletMargin = 0;
+//     this.width = 512;
+//     this.height = 64;
+//     this.markerX = -100; // puts it off screen unless set
+//     var self = this;
+//     if (this.isPercent) {
+//         this.displayValue + "%";
+//     }
+//     $scope.$watch(
+//       function() {
+//         return self.value;
+//       },
+//       function() {
+//         self.valueChanged();
+//       }
+//     );
+
+//   }
+
+//   bulletController.prototype = {
+
+//     valueChanged: function() {
+//       var range = this.max - this.min;
+//       var normalizedValue = (this.value - this.min) / range;
+//       if (this.isPercent) {
+//         this.displayValue = String(Math.round(normalizedValue * 100)) + "%";
+//       } else {
+//         this.displayValue = this.value;
+//       }
+//       // All versions of IE as of Jan 2015 does not support inline CSS transforms on SVG
+//       if (platform.name == 'IE') {
+//         this.bulletWidth = Math.round(100 * normalizedValue) + '%';
+//       } else {
+//         this.bulletWidth = this.width - (2 * this.containerMarginX);
+//         var transform = 'scaleX(' + normalizedValue + ')';
+//         var bullet = $(this.$element).find('.bullet2');
+//         bullet.css('transform', transform);
+//         bullet.css('-webkit-transform', transform);
+//       }
+//     },
+
+//     markerChanged: function() {
+//       var range = this.max - this.min;
+//       var w = this.width - (2 * this.containerMarginX);
+//       this.markerX = this.containerMarginX + ((this.marker - this.min) / range ) * w;
+//       this.markerY1 = 7;
+//       this.markerY2 = this.width - 7;
+//     }
+//   }
+
+// angular.module('components', ['n3-line-chart'])
+//     .directive('rwBullet', function() {
+//       return {
+//         restrict : 'E',
+//         templateUrl: 'modules/views/rw.bullet.tmpl.html',
+//         bindToController: true,
+//         controllerAs: 'bullet',
+//         controller: bulletController,
+//         replace: true,
+//         scope: {
+//           min : '@?',
+//           max : '@?',
+//           value : '@',
+//           marker: '@?',
+//           units: '@?',
+//           bulletColor: '@?',
+//           label: '@?'
+//         }
+//       };
+//     })
+//     .directive('rwSlider', function() {
+//       var controller = function($scope, $element, $timeout) {
+//         // Q: is there a way to force attributes to be ints?
+//         $scope.min = $scope.min || "0";
+//         $scope.max = $scope.max || "100";
+//         $scope.step = $scope.step || "1";
+//         $scope.height = $scope.height || "30";
+//         $scope.orientation = $scope.orientation || 'horizontal';
+//         $scope.tooltipInvert = $scope.tooltipInvert || false;
+//         $scope.percent = $scope.percent || false;
+//         $scope.kvalue = $scope.kvalue || false;
+//         $scope.direction = $scope.direction || "ltr";
+//         $($element).noUiSlider({
+//           start: parseInt($scope.value),
+//           step: parseInt($scope.step),
+//           orientation: $scope.orientation,
+//           range: {
+//             min: parseInt($scope.min),
+//             max: parseInt($scope.max)
+//           },
+//           direction: $scope.direction
+//         });
+//         //$(".no-Ui-target").Link('upper').to('-inline-<div class="tooltip"></div>')
+//         var onSlide = function(e, value) {
+//           $timeout(function(){
+//             $scope.value = value;
+//           })
+
+//         };
+//         $($element).on({
+//           change: onSlide,
+//           slide: onSlide,
+//           set: $scope.onSet({value: $scope.value})
+//         });
+//         var val = String(Math.round($scope.value));
+//         if ($scope.percent) {
+//             val += "%"
+//         } else if ($scope.kvalue) {
+//             val += "k"
+//         }
+//         $($element).height($scope.height);
+//         if ($scope.tooltipInvert) {
+//             $($element).find('.noUi-handle').append("<div class='tooltip' style='position:relative;right:20px'>" + val + "</div>");
+//         } else {
+//             $($element).find('.noUi-handle').append("<div class='tooltip' style='position:relative;left:-20px'>" + val + "</div>");
+//         }
+//         $scope.$watch('value', function(value) {
+//         var val = String(Math.round($scope.value));
+//         if ($scope.percent) {
+//             val += "%"
+//         } else if($scope.kvalue) {
+//             val += "k"
+//         }
+//           $($element).val(value);
+//           $($element).find('.tooltip').html(val);
+//         if ($scope.tooltipInvert) {
+//             $($element).find('.tooltip').css('right', $($element).find('.tooltip').innerWidth() * -1);
+//         } else {
+//             $($element).find('.tooltip').css('left', $($element).find('.tooltip').innerWidth() * -1);
+//         }
+//         });
+//       };
+
+//       return {
+//         restrict : 'E',
+//         template: '<div></div>',
+//         controller : controller,
+//         replace: true,
+//         scope: {
+//           min : '@',
+//           max : '@',
+//           width: '@',
+//           height: '@',
+//           step : '@',
+//           orientation : '@',
+//           tooltipInvert: '@',
+//           percent: '@',
+//           kvalue: '@?',
+//           onSet:'&?',
+//           direction: '@?',
+//           value:'=?'
+//         }
+//       };
+//     })
+// .directive('rwGauge', function() {
+//     return {
+//         restrict: 'AE',
+//         template: '<canvas class="rwgauge" style="width:100%;height:100%;max-width:{{width}}px;max-height:240px;"></canvas>',
+//         replace: true,
+//         scope: {
+//             min: '@?',
+//             max: '@?',
+//             size: '@?',
+//             color: '@?',
+//             value: '@?',
+//             resize: '@?',
+//             isAggregate: '@?',
+//             units: '@?',
+//             valueFormat: '=?',
+//             width: '@?'
+//         },
+//         bindToController: true,
+//         controllerAs: 'gauge',
+//         controller: function($scope, $element) {
+//             var self = this;
+//             this.gauge = null;
+//             this.min = this.min || 0;
+//             this.max = this.max || 100;
+//             this.nSteps = 14;
+//             this.size = this.size || 300;
+//             this.units = this.units || '';
+//             $scope.width = this.width || 240;
+//             this.color = this.color || 'hsla(212, 57%, 50%, 1)';
+//             if (!this.valueFormat) {
+//                 if (this.max > 1000 || this.value) {
+//                     self.valueFormat = {
+//                         "int": 1,
+//                         "dec": 0
+//                     };
+//                 } else {
+//                     self.valueFormat = {
+//                         "int": 1,
+//                         "dec": 2
+//                     };
+//                 }
+//             }
+//             this.isAggregate = this.isAggregate || false;
+//             this.resize = this.resize || false;
+//             if (this.format == 'percent') {
+//                 self.valueFormat = {
+//                     "int": 3,
+//                     "dec": 0
+//                 };
+//             }
+//             $scope.$watch(function() {
+//                 return self.max;
+//             }, function(n, o) {
+//                 if(n !== o) {
+//                     renderGauge();
+//                 }
+//             });
+//             $scope.$watch(function() {
+//                 return self.valueFormat;
+//             }, function(n, o) {
+//                 if(n != 0) {
+//                     renderGauge();
+//                 }
+//             });
+//             $scope.$watch(function() {
+//                 return self.value;
+//             }, function() {
+//                 if (self.gauge) {
+//                     // w/o rounding gauge will unexplainably thrash round.
+//                     self.valueFormat = determineValueFormat(self.value);
+//                     self.gauge.setValue(Math.ceil(self.value * 100) / 100);
+//                     //self.gauge.setValue(Math.round(self.value));
+//                 }
+//             });
+//             angular.element($element).ready(function() {
+//                 console.log('rendering')
+//                 renderGauge();
+//             })
+//             window.testme = renderGauge;
+//             function determineValueFormat(value) {
+
+//                     if (value > 999 || self.units == "%") {
+//                         return {
+//                             "int": 1,
+//                             "dec": 0
+//                         }
+//                     }
+
+//                     return {
+//                         "int": 1,
+//                         "dec": 2
+//                     }
+//                 }
+//             function renderGauge(calcWidth) {
+//                 if (self.max == self.min) {
+//                     self.max = 14;
+//                 }
+//                 var range = self.max - self.min;
+//                 var step = Math.round(range / self.nSteps);
+//                 var majorTicks = [];
+//                 for (var i = 0; i <= self.nSteps; i++) {
+//                     majorTicks.push(self.min + (i * step));
+//                 };
+//                 var redLine = self.min + (range * 0.9);
+//                 var config = {
+//                     isAggregate: self.isAggregate,
+//                     renderTo: angular.element($element)[0],
+//                     width: calcWidth || self.size,
+//                     height: calcWidth || self.size,
+//                     glow: false,
+//                     units: self.units,
+//                     title: false,
+//                     minValue: self.min,
+//                     maxValue: self.max,
+//                     majorTicks: majorTicks,
+//                     valueFormat: determineValueFormat(self.value),
+//                     minorTicks: 0,
+//                     strokeTicks: false,
+//                     highlights: [],
+//                     colors: {
+//                         plate: 'rgba(0,0,0,0)',
+//                         majorTicks: 'rgba(15, 123, 182, .84)',
+//                         minorTicks: '#ccc',
+//                         title: 'rgba(50,50,50,100)',
+//                         units: 'rgba(50,50,50,100)',
+//                         numbers: '#fff',
+//                         needle: {
+//                             start: 'rgba(255, 255, 255, 1)',
+//                             end: 'rgba(255, 255, 255, 1)'
+//                         }
+//                     }
+//                 };
+//                 var min = config.minValue;
+//                 var max = config.maxValue;
+//                 var N = 1000;
+//                 var increment = (max - min) / N;
+//                 for (i = 0; i < N; i++) {
+//                     var temp_color = 'rgb(0, 172, 238)';
+//                     if (i > 0.5714 * N && i <= 0.6428 * N) {
+//                         temp_color = 'rgb(0,157,217)';
+//                     } else if (i >= 0.6428 * N && i < 0.7142 * N) {
+//                         temp_color = 'rgb(0,142,196)';
+//                     } else if (i >= 0.7142 * N && i < 0.7857 * N) {
+//                         temp_color = 'rgb(0,126,175)';
+//                     } else if (i >= 0.7857 * N && i < 0.8571 * N) {
+//                         temp_color = 'rgb(0,122,154)';
+//                     } else if (i >= 0.8571 * N && i < 0.9285 * N) {
+//                         temp_color = 'rgb(0,96,133)';
+//                     } else if (i >= 0.9285 * N) {
+//                         temp_color = 'rgb(0,80,112)';
+//                     }
+//                     config.highlights.push({
+//                         from: i * increment,
+//                         to: increment * (i + 2),
+//                         color: temp_color
+//                     })
+//                 }
+//                 var updateSize = _.debounce(function() {
+//                     config.maxValue = self.max;
+//                     var clientWidth = self.parentNode.parentNode.clientWidth / 2;
+//                     var calcWidth = (300 > clientWidth) ? clientWidth : 300;
+//                     self.gauge.config.width = self.gauge.config.height = calcWidth;
+//                     self.renderGauge(calcWidth);
+//                 }, 500);
+//                 if (self.resize) $(window).resize(updateSize)
+//                 if (self.gauge) {
+//                     self.gauge.updateConfig(config);
+//                 } else {
+//                     self.gauge = new Gauge(config);
+//                     self.gauge.draw();
+//                 }
+//             };
+//         },
+//     }
+// });
diff --git a/skyquake/framework/widgets/dashboard_card/dashboardCardHeader.jsx b/skyquake/framework/widgets/dashboard_card/dashboardCardHeader.jsx
new file mode 100644 (file)
index 0000000..e44c4cc
--- /dev/null
@@ -0,0 +1,26 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+class DashboardCardHeader extends React.Component {
+  constructor(props) {
+    super(props);
+
+  }
+}
diff --git a/skyquake/framework/widgets/dashboard_card/dashboard_card.jsx b/skyquake/framework/widgets/dashboard_card/dashboard_card.jsx
new file mode 100644 (file)
index 0000000..4904dd2
--- /dev/null
@@ -0,0 +1,105 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './dashboard_card.scss';
+
+var cardClass = 'dashboardCard'//classSet(this.props.class);
+
+var CardHeader = React.createClass({
+  render() {
+    var cardClassHeader = cardClass + '_header';
+    if(this.props.className) {
+        cardClassHeader += ' ' + this.props.className + '_header';
+    }
+   return (
+    <header className={cardClassHeader}>
+      <h3>
+        {this.props.title}
+      </h3>
+    </header>
+    )
+  }
+});
+ CardHeader.defaultProps = {
+  title: ' Loading...'
+ }
+
+
+
+var dashboardCard = React.createClass({
+    componentDidMount: function() {
+
+    },
+    getDefaultProps: function() {
+      return {
+        isHidden: false
+      }
+    },
+    render() {
+      var cardClassWrapper = cardClass;
+      var cardClassContent = cardClass + '_content';
+      var cardClassContentBody = cardClassContent + '-body';
+      var hasHeader;
+      var cardClasses = [];
+      if(this.props.className) {
+        cardClasses = this.props.className.split(' ');
+        cardClasses.map(function(c, i) {
+          cardClassWrapper += ' ' + c;
+          cardClassContent += ' ' + c + '_content';
+          cardClassContentBody += ' ' + c + '-body';
+        })
+
+      }
+      let closeCard = null;
+    if (this.props.showHeader) {
+      hasHeader = <CardHeader className={this.props.className} title={this.props.title}/>;
+    };
+    if (this.props.closeCard) {
+      closeCard = this.props.closeCard;
+    }
+    return (
+        <div className={cardClassWrapper} style={{display: this.props.isHidden ? 'none':'inherit'}}>
+          {closeCard}
+          <i className="corner-accent top left"></i>
+          <i className="corner-accent top right"></i>
+            {hasHeader}
+            <div className={cardClassContent}>
+              <div className={cardClassContentBody}>
+                {this.props.children}
+              </div>
+            </div>
+          <i className="corner-accent bottom left"></i>
+          <i className="corner-accent bottom right"></i>
+        </div>
+      )
+  }
+})
+
+
+// class DashboardCard extends React.Component {
+//   constructor(props) {
+//     super(props)
+//   }
+//   render() {
+
+//   }
+// }
+
+
+export default dashboardCard;
diff --git a/skyquake/framework/widgets/dashboard_card/dashboard_card.scss b/skyquake/framework/widgets/dashboard_card/dashboard_card.scss
new file mode 100644 (file)
index 0000000..9a33dc5
--- /dev/null
@@ -0,0 +1,57 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import '../../style/_colors.scss';
+//Needs to be refactored
+.dashboardCard {
+  &_wrapper {
+    display: flex;
+    flex-wrap: wrap;
+    padding: 0.5rem;
+  }
+
+  background-color: $body-color;
+  position: relative;
+  // height: 750px;
+  width: 693px;
+  margin: 0.5rem 1rem;
+  align-content: flex-start;
+  flex-direction: column;
+  &_header {
+    display: flex;
+    align-items: center;
+    padding-left: 1rem;
+    background-color: $secondary-header;
+    text-transform: uppercase;
+
+    h3 {
+      padding: 1.5rem;
+    }
+  }
+  &_content {
+    display: flex;
+    flex-direction: row;
+    flex: 1;
+    overflow:hidden;
+    &-body{
+      display:flex;
+      flex-direction:column;
+      flex:1;
+    }
+  }
+}
diff --git a/skyquake/framework/widgets/filter/filter.jsx b/skyquake/framework/widgets/filter/filter.jsx
new file mode 100644 (file)
index 0000000..0ee7af5
--- /dev/null
@@ -0,0 +1,84 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+var Slider = require('react-slick');
+// require('../../components/gauge/gauge.js');
+// require('../../components/text-area/rw.text-area.js');
+// require('../../components/test/multicomponent.js');
+import button from '../../components/components.js'
+
+require('./carousel.css');
+var SimpleSlider = React.createClass({
+  propTypes: {
+    component_list:           React.PropTypes.array.isRequired,
+    slideno:                  React.PropTypes.number
+  },
+  handleClick: function() {
+    this.setState({});
+  },
+  getInitialState: function() {
+    return {
+      }
+    
+  },
+  shouldComponentUpdate: function(nextProps) {
+
+    if (nextProps.slideno != this.props.slideno) {
+      return true;
+    }
+    return false;
+  },
+  render: function () {
+    // var settings = {
+    //   dots: true,
+    //   infinite: false,
+    //   speed: 500,
+    //   slidesToShow: 1,
+    //   slidesToScroll: 1,
+    //   centerMode: true,
+    //   initialSlide: this.props.slideno || 2
+    // };
+    var settings = {
+        dots: false,
+        infinite: false,
+        speed: 500,
+        slidesToShow: 1,
+        slidesToScroll: 1,
+        centerMode: true,
+        initialSlide: this.props.slideno || 0
+    }
+    setTimeout(function() {
+      window.dispatchEvent(new Event('resize'));
+    }, 1000)
+    var list = [];
+    if (this.props.component_list !== undefined) {
+      for (var i = 0; i < this.props.component_list.length; i++) {
+        list.push(<div key={i}  className={"component"}>{this.props.component_list[i]}</div>);
+      }
+    }
+    return (
+      <div>
+      <Slider {...settings}>
+        {list}
+      </Slider>
+      </div>o
+    );
+  }
+});
+module.exports = SimpleSlider;
diff --git a/skyquake/framework/widgets/form_controls/formControls.scss b/skyquake/framework/widgets/form_controls/formControls.scss
new file mode 100644 (file)
index 0000000..4a88435
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'style/_colors.scss';
+
+.sqTextInput {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-direction: column;
+        flex-direction: column;
+    width: 100%;
+    margin-bottom:1rem;
+    -ms-flex-align: start;
+        align-items: flex-start;
+    -ms-flex-pack:start;
+        justify-content:flex-start;
+    span {
+        color:$darker-gray;
+        text-transform:uppercase;
+    }
+    input, .readonly, textarea {
+        height: 35px;
+        box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+        font-size: 1rem;
+        display: block;
+        background: white !important;
+        margin: 0;
+        margin-top: 0.25rem;
+        padding-left:0.25rem;
+        min-width:100%;
+        &[disabled] {
+            background:#ccc;
+        }
+    }
+    .readonly {
+        line-height: 35px;
+        box-shadow:none;
+    }
+    textarea {
+        -ms-flex-align: stretch;
+        -ms-grid-row-align: stretch;
+        align-items: stretch;
+        border:0px;
+        height: 100%;
+    }
+}
diff --git a/skyquake/framework/widgets/form_controls/selectOption.jsx b/skyquake/framework/widgets/form_controls/selectOption.jsx
new file mode 100644 (file)
index 0000000..41a8b13
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+export default class SelectOption extends React.Component {
+  constructor(props){
+    super(props);
+    this.state = {};
+  }
+  handleOnChange = (e) => {
+    this.props.onChange(e);
+  }
+  render() {
+    let html;
+    let defaultValue = this.props.defaultValue;
+    let options =  this.props.options.map(function(op, i) {
+      let value = JSON.stringify(op.value);
+      return <option key={i} value={JSON.stringify(op.value)}>{op.label}</option>
+    });
+    if (this.props.initial) {
+      options.unshift(<option key='blank' value={JSON.stringify(this.props.defaultValue)}></option>);
+    }
+    html = (
+        <label>
+            {this.props.label}
+            <select className={this.props.className} onChange={this.handleOnChange} defaultValue={JSON.stringify(defaultValue)} >
+                {
+                 options
+                }
+            </select>
+        </label>
+    );
+    return html;
+  }
+}
+SelectOption.defaultProps = {
+  options: [],
+  onChange: function(e) {
+    console.dir(e)
+  },
+  defaultValue: false,
+  initial: false,
+  label: null
+}
diff --git a/skyquake/framework/widgets/form_controls/textInput.jsx b/skyquake/framework/widgets/form_controls/textInput.jsx
new file mode 100644 (file)
index 0000000..03dfa9c
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import './formControls.scss';
+
+import React, {Component} from 'react';
+
+export default class TextInput extends Component {
+    render() {
+        let {label, onChange, value, defaultValue, ...props} = this.props;
+        let inputProperties = {
+            value: value,
+            onChange: onChange
+        }
+        let isRequired;
+        let inputType;
+        if(this.props.required) {
+           isRequired = <span className="required">*</span>
+        }
+        if (defaultValue) {
+            inputProperties.defaultValue = defaultValue;
+        }
+        if (props.pattern) {
+            inputProperties.pattern = props.pattern;
+        }
+        if (value == undefined) {
+            value = defaultValue;
+        }
+        switch(props.type) {
+            case 'textarea':
+                inputType = <textarea {...inputProperties} value={value}/>
+
+                break;
+            default:
+                inputType = <input type={props.type} {...inputProperties} placeholder={props.placeholder}/>;
+        }
+        let html = (
+            <label className={"sqTextInput " + props.className} style={props.style}>
+              <span> { label } {isRequired}</span>
+              {
+                !props.readonly ? inputType : <div className="readonly">{value}</div>
+              }
+
+            </label>
+        );
+        return html;
+    }
+}
+
+TextInput.defaultProps = {
+    onChange: function(e) {
+        console.log(e.target.value);
+    },
+    label: '',
+    defaultValue: undefined,
+    type: 'text',
+    readonly: false,
+    style:{}
+
+}
+
diff --git a/skyquake/framework/widgets/gauge/gauge.js b/skyquake/framework/widgets/gauge/gauge.js
new file mode 100644 (file)
index 0000000..dc1a083
--- /dev/null
@@ -0,0 +1,275 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require("react");
+var ReactDOM = require('react-dom');
+var MIXINS = require("../mixins/ButtonEventListener.js");
+var Gauge = require("../../js/gauge-modified.js");
+var GUID = require("utils/guid");
+import _ from 'underscore'
+
+
+
+
+/**
+ *  Gauge Component
+ *  It's props values and a brief description below
+ *
+ *  min:         minimum value expected
+ *  max:         maximum value expected
+ *  width:       width of gauge in px
+ *  height:      height of gauge in px
+ *  value:       the number displayed on the gauge
+ *  resize:      should the gauge resize with container
+ *  unit:        the units displayed on the gauge
+ *  valueFormat: An object with an 'int' and 'dec' property. The 'int' is the min number of integer digits displayed
+ *                 and the 'dec' object is the min number of fractional digits displayed.
+ *
+ *
+ **/
+module.exports = React.createClass({
+  displayName: 'Gauge',
+  mixins:MIXINS,
+  propTypes: {
+    min:           React.PropTypes.number,
+    max:           React.PropTypes.number,
+    width:         React.PropTypes.number,
+    height:        React.PropTypes.string,
+    value:         React.PropTypes.number,
+    resize:        React.PropTypes.bool,
+    isAggregate:   React.PropTypes.bool,
+    units:         React.PropTypes.string,
+    valueFormat:   React.PropTypes.shape({
+      'int':         React.PropTypes.number,
+      'dec':         React.PropTypes.number
+    })
+  },
+  clone: function(obj) {
+      if (null == obj || "object" != typeof obj) return obj;
+      var copy = obj.constructor();
+      for (var attr in obj) {
+          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
+      }
+      return copy;
+  },
+
+  /**
+   * Defines default state.
+   *
+   *  min:         minimum value expected
+   *  max:         maximum value expected
+   *  nSteps:      fixed number for now. The number of ticks in the gauge.
+   *  width:       width of gauge in px
+   *  height:      height of gauge in px
+   *  value:       the number displayed on the gauge
+   *  resize:      should the gauge resize with container
+   *  unit:        the units displayed on the gauge
+   *  valueFormat: An object with an 'int' and 'dec' property. The 'int' is the min number of integer digits displayed
+   *                 and the 'dec' object is the min number of fractional digits displayed.
+   */
+  getInitialState: function() {
+    var valueFormatState = null
+    this.gauge = null;
+    this.gaugeID = GUID();
+    if (!this.props.valueFormat) {
+        if ((this.props.max && this.props.max > 1000) || this.props.value) {
+            valueFormatState = {
+                "int": 1,
+                "dec": 0
+            };
+        } else {
+            valueFormatState = {
+                "int": 1,
+                "dec": 2
+            };
+        }
+    } else {
+      valueFormatState = this.props.valueFormat;
+    }
+    return {
+      //sizeOfButton:   this.props.size || '',  //There is no Medium value in CSS, default size is the absence of a value
+      min: this.props.min || 0,
+      max: this.props.max || 0,
+      nSteps: 14,
+      height: this.props.height || 200,
+      width: this.props.width || 200,
+      color: this.props.color || 'hsla(212, 57%, 50%, 1)',
+      value: this.props.value || 0,
+      valueFormat: valueFormatState,
+      isAggregate: this.props.isAggregate || false,
+      units: this.props.units || '',
+      resize:this.props.resize || false
+
+    }
+  },
+
+
+  /**
+   *  Called when props are changed.  Syncs props with state.
+   */
+  componentWillReceiveProps: function(nextProps) {
+    this.setState({
+      max:nextProps.max || this.state.max,
+      value:nextProps.value || 0,
+      valueFormat:nextProps.valueFormat || this.state.valueFormat
+    });
+  },
+
+  /**
+   * Calls the render on the gauge object once the component first mounts
+   */
+  componentDidMount: function() {
+    this.canvasRender(this.state);
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * Note, this is where the render step occures for the gauge object.
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = String(this.state.max) + String(this.state.valueFormat.int) + String(this.state.valueFormat.dec) + String(this.state.value);
+    var nextStateString = String(nextState.max) + String(nextState.valueFormat.int) + String(nextState.valueFormat.dec) + String(nextState.value);
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    this.state.valueFormat = this.determineValueFormat(nextState.value);
+    this.canvasRender(nextState);
+    return true;
+  },
+
+  /**
+   * Default value format based on units.
+   */
+  determineValueFormat: function(value) {
+          if (value > 999 || this.state.units == "%") {
+              return {
+                  "int": 1,
+                  "dec": 0
+              }
+          }
+
+          return {
+              "int": 1,
+              "dec": 2
+          }
+      },
+
+
+  /**
+   * Render step for the gauge object. Sets some defaults, passes some of the component's state down.
+   */
+  canvasRender: function(state) {
+    if (state.max == state.min) {
+        state.max = 14;
+    }
+    var range = state.max - state.min;
+    var step = Math.round(range / state.nSteps);
+    var majorTicks = [];
+    for (var i = 0; i <= state.nSteps; i++) {
+        majorTicks.push(state.min + (i * step));
+    }
+    var redLine = state.min + (range * 0.9);
+    var config = {
+        isAggregate: state.isAggregate,
+        renderTo: ReactDOM.findDOMNode(document.getElementById(this.gaugeID)),
+        width: state.width,
+        height: state.height,
+        glow: false,
+        units: state.units,
+        title: false,
+        minValue: state.min,
+        maxValue: state.max,
+        majorTicks: majorTicks,
+        valueFormat: this.determineValueFormat(self.value),
+        minorTicks: 0,
+        strokeTicks: false,
+        highlights: [],
+        colors: {
+            plate: 'rgba(0,0,0,0)',
+            majorTicks: 'rgba(15, 123, 182, .84)',
+            minorTicks: '#ccc',
+            title: 'rgba(50,50,50,100)',
+            units: 'rgba(50,50,50,100)',
+            numbers: '#fff',
+            needle: {
+                start: 'rgba(255, 255, 255, 1)',
+                end: 'rgba(255, 255, 255, 1)'
+            }
+        }
+    };
+
+    var min = config.minValue;
+    var max = config.maxValue;
+    var N = 1000;
+    var increment = (max - min) / N;
+    for (i = 0; i < N; i++) {
+        var temp_color = 'rgb(0, 172, 238)';
+        if (i > 0.5714 * N && i <= 0.6428 * N) {
+            temp_color = 'rgb(0,157,217)';
+        } else if (i >= 0.6428 * N && i < 0.7142 * N) {
+            temp_color = 'rgb(0,142,196)';
+        } else if (i >= 0.7142 * N && i < 0.7857 * N) {
+            temp_color = 'rgb(0,126,175)';
+        } else if (i >= 0.7857 * N && i < 0.8571 * N) {
+            temp_color = 'rgb(0,122,154)';
+        } else if (i >= 0.8571 * N && i < 0.9285 * N) {
+            temp_color = 'rgb(0,96,133)';
+        } else if (i >= 0.9285 * N) {
+            temp_color = 'rgb(0,80,112)';
+        }
+        config.highlights.push({
+            from: i * increment,
+            to: increment * (i + 2),
+            color: temp_color
+        })
+    }
+    var updateSize = _.debounce(function() {
+        config.maxValue = state.max;
+    }, 500);
+    if (state.resize) $(window).resize(updateSize)
+
+    if (this.gauge) {
+        this.gauge.setValue(Math.ceil(state.value* 100) / 100)
+        this.gauge.updateConfig(config);
+    } else {
+        this.gauge = new Gauge(config);
+        this.gauge.setValue(Math.ceil(state.value* 100) / 100)
+        this.gauge.draw();
+    }
+  },
+
+  /**
+   * Renders the Gauge Component
+   * Returns the canvas element the gauge will be housed in.
+   * @returns {*}
+   */
+  render: function() {
+    var gaugeDOM = React.createElement("div", null,
+      React.createElement("canvas",
+        {className: "rwgauge", style:
+          {width:'100%','maxWidth':this.state.width + 'px','maxHeight':this.state.width},
+          id:this.gaugeID
+        }
+      )
+    )
+
+
+
+    return gaugeDOM;
+  }
+});
diff --git a/skyquake/framework/widgets/header/header.jsx b/skyquake/framework/widgets/header/header.jsx
new file mode 100644 (file)
index 0000000..21f4c10
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import './header.scss';
+import Crouton from 'react-crouton';
+import HeaderStore from './headerStore.js';
+import ScreenLoader from '../screen-loader/screenLoader.jsx';
+export default class AppHeader extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.validateErrorEvent = 0;
+        this.state.validateErrorMsg = '';
+    }
+    componentDidMount() {
+        HeaderStore.listen(this.storeListener);
+    }
+    componentWillUnmount(){
+        HeaderStore.unlisten(this.storeListener);
+    }
+    closeError() {
+        LaunchpadFleetActions.validateReset()
+    }
+    storeListener = (state) => {
+        this.setState(state);
+    }
+    render() {
+        let html;
+        let navItems = this.props.nav.map(function(nav, i) {
+            if (nav.href || nav.onClick) {
+                return <li key={i}><a {...nav}>{nav.name}</a></li>
+            } else {
+                return <li key={i}><span className="current"> {nav.name} </span></li>
+            }
+        });
+        let errorMessage = <Crouton
+                id={Date.now()}
+                message={this.state.validateErrorMsg}
+                type={"error"}
+                hidden={!(this.state.validateErrorEvent && this.state.validateErrorMsg)}
+                onDismiss={HeaderStore.validateReset}
+            />
+
+        // html = (
+        //     <header className="header-app-component">
+        //     {errorMessage}
+        //     <ScreenLoader show={this.props.isLoading}/>
+        //     <div className="header-app-main">
+        //         <h1>{this.props.title}</h1>
+        //         <CommonLinks></CommonLinks>
+        //     </div>
+        //     <div className="header-app-nav">
+        //         <ul>
+        //             {navItems}
+        //         </ul>
+        //     </div>
+        //     </header>
+        // );
+
+        html = (
+            <header className="header-app-component">
+            {errorMessage}
+            <ScreenLoader show={this.props.isLoading}/>
+            <div className="header-app-nav">
+                <ul>
+                    {navItems}
+                </ul>
+            </div>
+            </header>
+        );
+
+        return html;
+    }
+}
+export class CommonLinks extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    openAbout() {
+        generateRefPage();
+        navigateTo('about')
+    }
+    openDebug() {
+        generateRefPage();
+        navigateTo('debug');
+    }
+    render() {
+        let links = [];
+        setContext();
+        links.push(<li key={'about'} onClick={this.openAbout}><a>About</a></li>);
+        links.push(<li  key={'debug'} onClick={this.openDebug}><a>Debug</a></li>);
+        let html;
+        html = (
+            <nav>
+                <ul>
+                    {links}
+                </ul>
+            </nav>
+        );
+        return html;
+    }
+}
+AppHeader.defaultProps = {
+    nav: [],
+    isLoading: false
+}
+function generateRefPage() {
+    let applicationContext = window.sessionStorage.getItem('applicationContext') || 'launchpad';
+    let hash = window.location.hash.split('/');
+    let pageTitle = 'Dashboard';
+    if (applicationContext === 'launchpad') {
+        hash = '#/launchpad/' + hash[2];
+    } else {
+        hash = "#/"
+    }
+    let refPage = {
+        'hash': hash,
+        'title': pageTitle
+    };
+    window.sessionStorage.setItem('refPage', JSON.stringify(refPage));
+    return refPage;
+}
+function navigateTo(loc) {
+    window.location.hash = '#/' + loc;
+}
+function setContext() {
+     let applicationContext;
+     let hashOne = window.location.hash.split('/')[1];
+    if(hashOne == "launchpad") {
+      applicationContext = "launchpad";
+    } else {
+      applicationContext = "missioncontrol";
+    }
+    if(hashOne != 'about' && hashOne != 'debug'){
+        window.sessionStorage.setItem('applicationContext', applicationContext);}
+}
diff --git a/skyquake/framework/widgets/header/header.scss b/skyquake/framework/widgets/header/header.scss
new file mode 100644 (file)
index 0000000..9238c22
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+header.header-app-component {
+    padding: 20px 0px;
+    display:flex;
+    flex-direction:column;
+    .header-app-main {
+        display:flex;
+        flex-direction:row;
+        justify-content:space-between;
+        align-items:center;
+    }
+    h1 {
+        background: url('../../style/img/header-logo.png') no-repeat;
+        background-size:contain;
+        height: 51px;
+        line-height: 51px;
+        margin-left: 20px;
+        padding-left: 100px;
+        left: 0;
+        text-transform: uppercase;
+        font-size: 1.625rem;
+        font-weight: 400;
+        position:relative;
+        flex: 1 0 auto;
+
+    }
+    ul {
+            display:flex;
+        }
+        li {
+            display:flex;
+             flex:1 1 auto;
+             border-right:1px solid #e5e5e5;
+             padding: 0 1rem;
+            &:last-child {
+                border:none;
+            }
+            a {
+                cursor:pointer;
+                // padding: 0.125rem;
+                // border-bottom:1px solid black;
+                text-decoration:underline;
+            }
+        }
+    .header-app-nav {
+        display:flex;
+        margin-left: 0.25rem;
+        a,span {
+            text-transform:uppercase;
+        }
+        a {
+            cursor: pointer;
+            margin-left: 0.5rem;
+            font-weight: normal;
+            color: black;
+        }
+
+        .spacer {
+
+        }
+        .current {
+            font-weight: bold;
+        }
+    }
+    nav {
+        display:flex;
+        flex:0 1 auto;
+        align-items:center;
+    }
+}
diff --git a/skyquake/framework/widgets/header/headerActions.js b/skyquake/framework/widgets/header/headerActions.js
new file mode 100644 (file)
index 0000000..e71e79f
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import Alt from '../skyquake_container/skyquakeAltInstance';
+export default Alt.generateActions('showError', 'resetError');
diff --git a/skyquake/framework/widgets/header/headerStore.js b/skyquake/framework/widgets/header/headerStore.js
new file mode 100644 (file)
index 0000000..4ee86ff
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import HeaderActions from './headerActions.js';
+import Alt from '../skyquake_container/skyquakeAltInstance';
+
+class HeaderStoreConstructor {
+    constructor() {
+        var self = this;
+        this.validateErrorEvent = 0;
+        this.validateErrorMsg = '';
+        this.bindActions(HeaderActions);
+        this.exportPublicMethods({
+            validateReset: self.validateReset
+        })
+    }
+    showError = (msg) => {
+        console.log('message received');
+        this.setState({
+            validateErrorEvent: true,
+            validateErrorMsg: msg
+        });
+    }
+    validateReset = () => {
+        this.setState({
+            validateErrorEvent: false
+        });
+    }
+}
+
+export default Alt.createStore(HeaderStoreConstructor)
diff --git a/skyquake/framework/widgets/input-range-slider/input-range-slider.jsx b/skyquake/framework/widgets/input-range-slider/input-range-slider.jsx
new file mode 100644 (file)
index 0000000..d9e0544
--- /dev/null
@@ -0,0 +1,72 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+// import Slider from 'react-rangeslider';
+// import Slider from './react-rangeslider.jsx';
+import './input-range-slider.scss';
+
+
+class RWslider extends React.Component {
+  constructor(props, context) {
+    super(props, context);
+    this.state = {...props}
+  }
+
+  handleChange = (value) => {
+    this.props.handleInputUpdate(value);
+    this.setState({
+      value: value
+    });
+  };
+
+  render() {
+    let state = this.state;
+      var className = "input-range-slider_" + this.props.orientation;
+    return (
+      <div className={className}>
+      <div className={className + '-info'}>
+      {state["min-value"]}
+      </div>
+      <Slider
+        displayValue={true}
+        value={state.value}
+        max={state["max-value"]}
+        min={state["min-value"]}
+        step={state["step-value"]}
+        onChange={this.handleChange}
+        className={className + '-info'} />
+      <div className={className + '-info'}>
+      {state["max-value"]}
+      </div>
+      </div>
+    );
+  }
+}
+
+RWslider.defaultProps = {
+    value: 10,
+    "min-value": 0,
+    "max-value":100,
+    "step-value":1,
+    "units": "%",
+    orientation: "horizontal"
+}
+
+export default RWslider
+
diff --git a/skyquake/framework/widgets/input-range-slider/input-range-slider.scss b/skyquake/framework/widgets/input-range-slider/input-range-slider.scss
new file mode 100644 (file)
index 0000000..803bd8b
--- /dev/null
@@ -0,0 +1,104 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import '../../style/_colors.scss';
+
+  .input-range-slider_horizontal{
+    display:flex;
+    align-items:baseline;
+    &-info {
+      margin:0 0.5rem;
+    }
+  }
+
+
+.rangeslider {
+  margin: 20px 0;
+  position: relative;
+  background: #e6e6e6;
+  display:flex;
+  flex:1;
+  .rangeslider__fill, .rangeslider__handle {
+    position: absolute;
+  }
+  &, .rangeslider__fill {
+    display: block;
+    box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);
+  }
+  .rangeslider__handle {
+    background: #fff;
+    border: 1px solid #ccc;
+    cursor: pointer;
+    display: inline-block;
+    position: absolute;
+    &:active {
+      background: #999;
+    }
+  }
+}
+
+/**
+ * Rangeslider - Horizontal slider
+ */
+.rangeslider-horizontal {
+  height: 1rem;
+  margin-bottom: 2.5rem;
+  .rangeslider__fill {
+    height: 100%;
+    background: $light-blue;
+    top: 0;
+  }
+  .rangeslider__handle {
+    width: 0.5rem;
+    height: 2rem;
+    top: -0.5rem;
+    left:-10px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    >div{
+          width: 5rem;
+          margin-top: 2rem;
+          text-align: center;
+    }
+  }
+}
+
+/**
+ * Rangeslider - Vertical slider
+ */
+.rangeslider-vertical {
+  margin: 20px auto;
+  height: 150px;
+  max-width: 10px;
+  background: none;
+  .rangeslider__fill {
+    width: 100%;
+    background: $light-blue;
+    box-shadow: none;
+    bottom: 0;
+  }
+  .rangeslider__handle {
+    width: 30px;
+    height: 10px;
+    left: -10px;
+    &:active {
+      box-shadow: none;
+    }
+  }
+}
diff --git a/skyquake/framework/widgets/input-range-slider/react-rangeslider.jsx b/skyquake/framework/widgets/input-range-slider/react-rangeslider.jsx
new file mode 100644 (file)
index 0000000..feff1eb
--- /dev/null
@@ -0,0 +1,251 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * https://github.com/larsmaultsby/react-rangeslider
+ *
+ *
+ * Forked from: https://github.com/whoisandie/react-rangeslider
+ *
+ *
+    The MIT License (MIT)
+
+    Copyright (c) 2015 Bhargav Anand
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in all
+    copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+    SOFTWARE.
+ *
+ */
+
+import React, { PropTypes, Component, findDOMNode } from 'react';
+import joinClasses from 'react/lib/joinClasses';
+
+function capitalize(str) {
+  return str.charAt(0).toUpperCase() + str.substr(1);
+}
+
+function maxmin(pos, min, max) {
+  if (pos < min) { return min; }
+  if (pos > max) { return max; }
+  return pos;
+}
+
+const constants = {
+  orientation: {
+    horizontal: {
+      dimension: 'width',
+      direction: 'left',
+      coordinate: 'x',
+    },
+    vertical: {
+      dimension: 'height',
+      direction: 'top',
+      coordinate: 'y',
+    }
+  }
+};
+
+class Slider extends Component {
+  static propTypes = {
+    min: PropTypes.number,
+    max: PropTypes.number,
+    step: PropTypes.number,
+    value: PropTypes.number,
+    orientation: PropTypes.string,
+    onChange: PropTypes.func,
+    className: PropTypes.string,
+  }
+
+  static defaultProps = {
+    min: 0,
+    max: 100,
+    step: 1,
+    value: 0,
+    orientation: 'horizontal',
+  }
+
+  state = {
+    limit: 0,
+    grab: 0
+  }
+
+  // Add window resize event listener here
+  componentDidMount() {
+    this.calculateDimensions();
+    window.addEventListener('resize', this.calculateDimensions);
+  }
+
+  componentWillUnmount() {
+    window.removeEventListener('resize', this.calculateDimensions);
+  }
+
+  handleSliderMouseDown = (e) => {
+    let value, { onChange } = this.props;
+    if (!onChange) return;
+    value = this.position(e);
+    onChange && onChange(value);
+  }
+
+  handleKnobMouseDown = () => {
+    document.addEventListener('mousemove', this.handleDrag);
+    document.addEventListener('mouseup', this.handleDragEnd);
+  }
+
+  handleDrag = (e) => {
+    let value, { onChange } = this.props;
+    if (!onChange) return;
+    value = this.position(e);
+    onChange && onChange(value);
+  }
+
+  handleDragEnd = () => {
+    document.removeEventListener('mousemove', this.handleDrag);
+    document.removeEventListener('mouseup', this.handleDragEnd);
+  }
+
+  handleNoop = (e) => {
+    e.stopPropagation();
+    e.preventDefault();
+  }
+
+  calculateDimensions = () => {
+    let { orientation } = this.props;
+    let dimension = capitalize(constants.orientation[orientation].dimension);
+    const sliderPos = findDOMNode(this.refs.slider)['offset' + dimension];
+    const handlePos = findDOMNode(this.refs.handle)['offset' + dimension]
+    this.setState({
+      limit: sliderPos - handlePos,
+      grab: handlePos / 2,
+    });
+  }
+  getPositionFromValue = (value) => {
+    let percentage, pos;
+    let { limit } = this.state;
+    let { min, max } = this.props;
+    percentage = (value - min) / (max - min);
+    pos = Math.round(percentage * limit);
+
+    return pos;
+  }
+
+  getValueFromPosition = (pos) => {
+    let percentage, value;
+    let { limit } = this.state;
+    let { orientation, min, max, step } = this.props;
+    percentage = (maxmin(pos, 0, limit) / (limit || 1));
+
+    if (orientation === 'horizontal') {
+      value = step * Math.round(percentage * (max - min) / step) + min;
+    } else {
+      value = max - (step * Math.round(percentage * (max - min) / step) + min);
+    }
+
+    return value;
+  }
+
+  position = (e) => {
+    let pos, value, { grab } = this.state;
+    let { orientation } = this.props;
+    const node = findDOMNode(this.refs.slider);
+    const coordinateStyle = constants.orientation[orientation].coordinate;
+    const directionStyle = constants.orientation[orientation].direction;
+    const coordinate = e['client' + capitalize(coordinateStyle)];
+    const direction = node.getBoundingClientRect()[directionStyle];
+
+    pos = coordinate - direction - grab;
+    value = this.getValueFromPosition(pos);
+
+    return value;
+  }
+
+  coordinates = (pos) => {
+    let value, fillPos, handlePos;
+    let { limit, grab } = this.state;
+    let { orientation } = this.props;
+    value = this.getValueFromPosition(pos);
+    handlePos = this.getPositionFromValue(value);
+
+    if (orientation === 'horizontal') {
+      fillPos = handlePos + grab;
+    } else {
+      fillPos = limit - handlePos + grab;
+    }
+
+    return {
+      fill: fillPos,
+      handle: handlePos,
+    };
+  }
+
+  render() {
+    let dimension, direction, position, coords, fillStyle, handleStyle, displayValue;
+    let { value, orientation, className } = this.props;
+
+    dimension = constants.orientation[orientation].dimension;
+    direction = constants.orientation[orientation].direction;
+
+    position = this.getPositionFromValue(value);
+    coords = this.coordinates(position);
+
+    fillStyle = {[dimension]: `${coords.fill}px`};
+    handleStyle = {[direction]: `${coords.handle}px`};
+
+    if(this.props.displayValue) {
+      displayValue = <div>{this.props.value}</div>;
+    }
+
+    return (
+      <div
+        ref="slider"
+        className={joinClasses('rangeslider ', 'rangeslider-' + orientation, className)}
+        onMouseDown={this.handleSliderMouseDown}
+        onClick={this.handleNoop}
+        style={{display:'flex'}}>
+        <div
+          ref="fill"
+          className="rangeslider__fill"
+          style={fillStyle} />
+        <div
+          ref="handle"
+          className="rangeslider__handle"
+          onMouseDown={this.handleKnobMouseDown}
+          onClick={this.handleNoop}
+          style={handleStyle}>
+            {displayValue}
+          </div>
+      </div>
+    );
+  }
+}
+
+export default Slider;
diff --git a/skyquake/framework/widgets/listy/listy.js b/skyquake/framework/widgets/listy/listy.js
new file mode 100644 (file)
index 0000000..ac0e58a
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import _ from 'lodash';
+
+/**
+ *
+ *
+ */
+export default class Listy extends React.Component {
+       constructor(props) {
+               super(props);
+       }
+
+       /**
+
+        */
+       createList(data, iter=0) {
+               var groupTag = this.props.groupTag.tag;
+               var groupClass = this.props.groupTag.className;
+               var itemTag = this.props.itemTag.tag;
+               var itemClass = this.props.itemTag.className;
+               var listHeaderTag = this.props.listHeaderTag.tag;
+               var listHeaderClass = this.props.listHeaderTag.className;
+
+               var listNode = null;
+               var self = this;
+               if (_.isArrayLike(data) && _.isObjectLike(data)) {
+                       var children = [];
+                       data.forEach(function(element, index, array) {
+                               if ( _.isArrayLike(element) || _.isObjectLike(element)) {
+                                       children.push(self.createList(element, iter+1));
+                               } else {
+                                       children.push(React.createElement(itemTag, {
+                                               key: index,
+                                               className: itemClass
+                                       }, element));
+                               }
+                       });
+
+                       listNode = React.createElement(groupTag, {
+                               key: iter,
+                               className: groupClass }, children);
+               }
+               else if (_.isObjectLike(data)) {
+                       var children = [];
+                       for (var key in data) {
+                               if ( _.isArrayLike(data[key]) || _.isObjectLike(data[key])) {
+                                       children.push(
+                                               React.createElement(listHeaderTag, {
+                                                       key: key + '_header',
+                                                       className: listHeaderClass }, key + ":")
+                                       );
+                                       children.push(
+                                               React.createElement(groupTag, {
+                                                       key: key + '_list',
+                                                       className: groupClass },
+                                                       [this.createList(data[key], iter + 1)])
+                                       );
+
+                               } else {
+                                       // TODO: Add span to line-wrap the data part (hanging)
+                                       children.push(React.createElement(itemTag, {
+                                               key: key,
+                                               className: itemClass},
+                                               key + ": " + data[key]));
+                               }
+                       }
+                       listNode = React.createElement(groupTag, {
+                               key: iter,
+                               className: groupClass }, children);
+               } else {
+                       listNode = React.createElement(itemTag, {
+                               className: itemClass}, data);
+               }
+
+               return listNode;
+       }
+
+       noDataMessage() {
+               return React.createElement("div", {
+                       className: this.props.noDataMessageClass},
+                       this.props.noDataMessage);
+       }
+
+       render () {
+               var data = this.props.data;
+
+               return React.createElement("div", {
+                       className: "listy" },
+                       _.isEmpty(data) ? 
+                       this.noDataMessage() : 
+                       this.createList(data)
+               )
+       }
+}
+
+Listy.validateTagDefinition = function(props, propName, componentName) {
+       let obj = props[propName];
+       let fullAttr = componentName + "." + propName;
+
+       if (!obj)
+               return new Error('Validation failed. "%" is undefined', fullAttr);
+       if (!obj.hasOwnProperty("tag") || _.isEmpty(obj.tag))
+               return new Error('Validation failed. "%s" missing attribute "tag"', fullAttr);
+       if (!obj.hasOwnProperty("className") || obj.className == undefined)
+               return new Error('Validation failed. "%s" missing attribute "className"', fullAttr);
+}
+
+Listy.propTypes = {
+       data: React.PropTypes.object,
+       groupTag: Listy.validateTagDefinition,
+       itemTag: Listy.validateTagDefinition,
+       listHeaderTag: Listy.validateTagDefinition,     
+       debugMode: React.PropTypes.bool
+}
+
+Listy.defaultProps = {
+       data: {},
+
+       // Visual Rules
+       groupTag: {
+               tag: "ul",
+               className: "listyGroup"
+       },
+       itemTag: {
+               tag: "li",
+               className: "listyItem"
+       },
+       listHeaderTag: {
+               tag: "h2",
+               className: "listyGroupHeader"
+       },
+       noDataMessage: "No data",
+       noDataMessageClass: "listyNoDataMessage",
+       debugMode: false
+}
diff --git a/skyquake/framework/widgets/loading-indicator/loading-indicator-animations.scss b/skyquake/framework/widgets/loading-indicator/loading-indicator-animations.scss
new file mode 100644 (file)
index 0000000..44222de
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.line-scale-pulse-out-rapid > div {
+  background-color: #fff;
+  width: 4px;
+  height: 2rem;
+  border-radius: 2px;
+  margin: 2px;
+  animation-fill-mode: both;
+  display: inline-block;
+  animation: line-scale-pulse-out-rapid 0.9s -0.5s infinite cubic-bezier(0.11, 0.49, 0.38, 0.78); }
+  .line-scale-pulse-out-rapid > div:nth-child(2), .line-scale-pulse-out-rapid > div:nth-child(4) {
+    animation-delay: -0.25s !important; }
+  .line-scale-pulse-out-rapid > div:nth-child(1), .line-scale-pulse-out-rapid > div:nth-child(5) {
+    animation-delay: 0s !important; }
+
+
+.loader-animation-enter, .loader-animation-appear {
+  opacity: 0.01;
+}
+
+.loader-animation-enter.loader-animation-enter-active, .loader-animation-appear.loader-animation-appear-active {
+  opacity: 1.0;
+  transition: opacity 300ms ease-in;
+}
+
+.loader-animation-leave {
+  visibility:hidden;
+  height:0px;
+  width:0px;
+  opacity:1.0;
+}
+
+.loader-animation-leave.loader-animation-leave-active {
+  opacity:0;
+  transition: opacity 300ms ease-in;
+}
diff --git a/skyquake/framework/widgets/loading-indicator/loadingIndicator.jsx b/skyquake/framework/widgets/loading-indicator/loadingIndicator.jsx
new file mode 100644 (file)
index 0000000..9e77fdd
--- /dev/null
@@ -0,0 +1,60 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import '../../../node_modules/loaders.css/src/animations/line-scale-pulse-out-rapid.scss';
+import './loading-indicator-animations.scss';
+let ReactCSSTransitionGroup = require('react-addons-css-transition-group');
+export default class Loader extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  render() {
+    let loader = '';
+    var style = {
+      height: this.props.size + 'rem',
+      width: this.props.size * 0.15 + 'rem',
+      backgroundColor: this.props.color || 'white'
+    }
+    if (this.props.show) {
+      loader = (
+                <div
+                  transitionName="loader-animation"
+                  transitionAppear={true}
+                  component="div"
+                  className={"line-scale-pulse-out-rapid"}>
+                  <div style={style}></div>
+                  <div style={style}></div>
+                  <div style={style}></div>
+                  <div style={style}></div>
+                  <div style={style}></div>
+                </div>
+      );
+    }else {
+      loader = <span></span>
+    }
+    return loader;
+
+  }
+}
+
+Loader.defaultProps = {
+  show: true,
+  size: '5'
+}
+
diff --git a/skyquake/framework/widgets/login/login.js b/skyquake/framework/widgets/login/login.js
new file mode 100644 (file)
index 0000000..f6ce188
--- /dev/null
@@ -0,0 +1,51 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+var LoginScreen = require('./login.jsx');
+angular.module('login', ['ui.router'])
+    .config(function($stateProvider) {
+
+     $rw.nav.push({
+        module: 'login',
+        name: "Login"
+      });
+
+      $stateProvider.state('login', {
+        url: '/login',
+        replace: true,
+        template: '<login-screen></login-screen>'
+      });
+
+})
+.directive('loginScreen', function() {
+  return {
+      restrict: 'AE',
+      controller: function($element) {
+        function reactRender() {
+          React.render(
+            React.createElement(LoginScreen, null)
+            ,
+            $element[0]
+          );
+        }
+        reactRender();
+      }
+    };
+})
+    ;
diff --git a/skyquake/framework/widgets/login/login.jsx b/skyquake/framework/widgets/login/login.jsx
new file mode 100644 (file)
index 0000000..1506809
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import Utils from 'utils/utils.js';
+import Button from 'widgets/button/rw.button.js';
+import './login.scss'
+let rw = require('utils/rw.js');
+class LoginScreen extends React.Component{
+  constructor(props) {
+    super(props);
+    var API_SERVER =  rw.getSearchParams(window.location).api_server;
+    if (!API_SERVER) {
+      window.location.href = "//" + window.location.host + '/index.html?api_server=' + window.location.protocol + '//localhost';
+    }
+    this.state = {
+      username: '',
+      password: ''
+    };
+
+  }
+  updateValue = (e) => {
+    let state = {};
+    state[e.target.name] = e.target.value;
+    this.setState(state);
+  }
+  validate = (e) => {
+    let self = this;
+    let state = this.state;
+    e.preventDefault();
+    if (state.username == '' || state.password == '') {
+      console.log('false');
+      return false;
+    } else {
+      Utils.setAuthentication(state.username, state.password, function() {
+        //Returning to previous location disabled post port
+        //  let hash = window.sessionStorage.getItem("locationRefHash") || '#/';
+        //   if (hash == '#/login') {
+        //     hash = '#/'
+        //   }
+        // window.location.hash = hash;
+        self.context.router.push('/');
+      });
+
+    }
+  }
+  submitForm = (e) => {
+      if(e.keyCode == 13){
+        this.validate(e);
+      }
+  }
+  render() {
+    let html;
+    html = (
+      <form className="login-cntnr" autoComplete="on" onKeyUp={this.submitForm}>
+        <div className="logo"> </div>
+        <h1 className="riftio">Launchpad Login</h1>
+        <p>
+            <input type="text" placeholder="Username" name="username" value={this.state.username} onChange={this.updateValue} autoComplete="username"></input>
+        </p>
+        <p>
+            <input type="password" placeholder="Password" name="password" onChange={this.updateValue} value={this.state.password} autoComplete="password"></input>
+        </p>
+        <p>
+           <Button className="sign-in" onClick={this.validate}  style={{cursor: 'pointer'}} type="submit" label="Sign In"/>
+        </p>
+      </form>
+    )
+    return html;
+  }
+}
+LoginScreen.contextTypes = {
+    router: React.PropTypes.object
+  };
+
+
+export default LoginScreen;
diff --git a/skyquake/framework/widgets/login/login.scss b/skyquake/framework/widgets/login/login.scss
new file mode 100644 (file)
index 0000000..cb14e9b
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.login-cntnr .logo {
+    background-image: url(../../style/img/header-logo.png);
+
+}
diff --git a/skyquake/framework/widgets/login/loginAuthActions.js b/skyquake/framework/widgets/login/loginAuthActions.js
new file mode 100644 (file)
index 0000000..c2c805f
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+module.exports = Alt.generateActions(
+                                       'notAuthenticated'
+                                     );
diff --git a/skyquake/framework/widgets/login/main.js b/skyquake/framework/widgets/login/main.js
new file mode 100644 (file)
index 0000000..f69a91e
--- /dev/null
@@ -0,0 +1,11 @@
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#content');
+
+render(router, element);
+
+
diff --git a/skyquake/framework/widgets/metric-bars/metricBarGroup.jsx b/skyquake/framework/widgets/metric-bars/metricBarGroup.jsx
new file mode 100644 (file)
index 0000000..d4f92d6
--- /dev/null
@@ -0,0 +1,141 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import ReactDOM from 'react-dom';
+import d3 from 'd3';
+import './metricBarGroup.scss';
+
+class MetricBarGroup extends React.Component {
+  constructor(props) {
+    super(props);
+
+  }
+  componentWillMount() {
+    const {...props} = this.props;
+    this.margin = {top: 20, right: 50, bottom: 700, left: 100};
+    this.width = 1220 - this.margin.left - this.margin.right;
+    this.height = 1220 - this.margin.top - this.margin.bottom;
+    // this.width = 800;
+    // this.height = 600;
+    this.x = d3.scale.ordinal()
+      .rangeRoundBands([0, this.width], .1);
+
+    this.y = d3.scale.linear()
+      .range([this.height, 0]);
+
+    this.xAxis = d3.svg.axis()
+      .scale(this.x)
+      .orient("bottom");
+
+    this.yAxis = d3.svg.axis()
+        .scale(this.y)
+        .orient("left")
+        .ticks(props.ticks.number, props.ticks.type);
+  }
+  componentDidMount() {
+    let el = document.querySelector('#' + this.props.title + this.props.lp_id);
+    this.svg = d3.select(el)
+      .append('svg');
+    let self = this;
+
+    let totalWidth = this.width + this.margin.left + this.margin.right;
+    let totalHeight = this.height + this.margin.top + this.margin.bottom;
+    this.svg = this.svg
+      .attr("viewBox", "-10 0 " + totalWidth + " " + totalHeight + "")
+      .attr("preserveAspectRatio", "xMidYMid meet")
+      .style("overflow","visible")
+      .append("g")
+      .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
+
+    this.svg.append("g")
+        .attr("class", "y axis")
+        .call(this.yAxis);
+    this.svg.append("g")
+        .attr("class", "x axis")
+        .attr("transform", "translate(-1," + this.height + ")")
+        .call(this.xAxis)
+    this.drawBars(this.props);
+
+
+  }
+  componentWillReceiveProps(props) {
+    this.drawBars(props);
+  }
+  drawBars = (props) => {
+    let DATA = props.data.sort(function(a,b){
+      return (a.id > b.id) ? -1 : 1;
+    });
+    this.x.domain(DATA.map(function(d, i) { return d.id }));
+    let self = this;
+    let barGroup = this.svg.selectAll(".barGroup").data(DATA, function(d, i) { return d.id});;
+    let barGroupExit = barGroup.exit().remove();
+    let barGroupEnter =  barGroup.enter().append('g')
+      .attr('class', 'barGroup');
+    barGroupEnter
+      .append("rect")
+      .attr("class", "bar")
+      .attr("x", function(d) { return self.x(d.id); })
+      .attr("width", self.x.rangeBand())
+      .attr("y", function(d) { return self.y(d[props.valueName]); })
+      .attr("height", function(d) {return self.height - self.y(d[props.valueName]); });
+    barGroupEnter.append("g")
+      .attr("transform", function(d){
+        return "translate("+ (parseInt(self.x(d.id)) + (self.x.rangeBand() / 2) + 10) +"," + (parseInt(self.height) + 10) + ")"
+       })
+      .append('text')
+      .classed('metriclabel', true)
+      .style("text-anchor", "end")
+      .attr('transform', 'rotate(-75)')
+      .text(function(d) { return d.name;} )
+
+    let barGroupUpdate = barGroup.transition();
+    barGroupUpdate.select('rect')
+      .attr("class", "bar")
+      .attr("x", function(d) { return self.x(d.id) })
+      .attr("width", self.x.rangeBand())
+      .attr("y", function(d) { return self.y(d[props.valueName]); })
+      .attr("height", function(d) {return self.height - self.y(d[props.valueName]); });
+    barGroupUpdate
+      .select('g')
+      .attr("transform", function(d){
+        return "translate("+ (parseInt(self.x(d.id)) + (self.x.rangeBand() / 2) + 10) +"," + (parseInt(self.height) + 10) + ")"
+       })
+      .select('text')
+      .style("text-anchor", "end")
+      .attr('transform', 'rotate(-75)')
+      .text(function(d) { return d.name;} )
+  }
+  render() {
+    let html = <div></div>;
+    let self = this;
+    return <div className="metricBarGroup"><h3>{this.props.title}</h3><div id={this.props.title + this.props.lp_id}></div></div>;
+  }
+}
+MetricBarGroup.defaultProps = {
+  ticks: {
+    number: 2,
+    type: '%'
+  },
+  valueName: 'utilization',
+  title: '',
+  data: []
+}
+
+
+export default MetricBarGroup;
diff --git a/skyquake/framework/widgets/metric-bars/metricBarGroup.scss b/skyquake/framework/widgets/metric-bars/metricBarGroup.scss
new file mode 100644 (file)
index 0000000..6517612
--- /dev/null
@@ -0,0 +1,49 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "../../../framework/style/_colors.scss";
+    .metricBarGroup {
+      display:flex;
+      flex-direction:column;
+      padding: 1rem;
+      justify-content: center;
+      h3 {
+        text-align:center;
+        font-weight:bold;
+      }
+      .bar {
+        fill: $brand-blue-light;
+        stroke: black;
+      }
+      .y.axis {
+        .domain {
+          transform:scaleX(0.25);
+        }
+      }
+      .x.axis {
+        .domain {
+          transform:scaleY(0.25);
+        }
+     }
+     .metriclabel, .y.axis .tick text{
+      font-size:3rem;
+     }
+     &>div {
+      flex: 1 1 %33;
+     }
+   }
diff --git a/skyquake/framework/widgets/mixins/ButtonEventListener.js b/skyquake/framework/widgets/mixins/ButtonEventListener.js
new file mode 100644 (file)
index 0000000..7a8e0cc
--- /dev/null
@@ -0,0 +1,207 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+
+
+/**
+ * Event listener Mixins. A vast majority of components are going to expose these events to the user so we're making
+ * a central location to house all of them.
+ */
+module.exports = {
+  propTypes: {
+    onClick:       React.PropTypes.func,
+    onMouseUp:     React.PropTypes.func,
+    onMouseDown:   React.PropTypes.func,
+    onMouseOver:   React.PropTypes.func,
+    onMouseEnter:  React.PropTypes.func,
+    onMouseLeave:  React.PropTypes.func,
+    onMouseOut:    React.PropTypes.func,
+
+    onTouchCancel: React.PropTypes.func,
+    onTouchEnd:    React.PropTypes.func,
+    onTouchMove:   React.PropTypes.func,
+    onTouchStart:  React.PropTypes.func,
+
+    onKeyDown:     React.PropTypes.func,
+    onKeyPress:    React.PropTypes.func,
+    onKeyUp:       React.PropTypes.func,
+
+    onFocus:       React.PropTypes.func,
+    onBlur:        React.PropTypes.func
+  },
+
+  /**
+   * A vast majority of these functions just check to see if the event function is defined and then passes the function
+   * both the event and the local props.
+   * @param e
+   */
+  onClick: function(e) {
+    if (Boolean(this.props.onClick) && !this.state.isDisabled && !this.state.isReadOnly) {
+      //this.props.isActive = true;
+      this.props.onClick(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseUp: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive:false});
+      if (Boolean(this.props.onMouseUp)) {
+        this.props.onMouseUp(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseDown: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive:true});
+      if (Boolean(this.props.onMouseDown)) {
+        this.props.onMouseDown(e, this);
+      }
+    }
+  },
+  onMouseOver: function(e) {
+    if (Boolean(this.props.onMouseOver) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onMouseOver(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseEnter: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isHovered:true});
+      if (this.props.onMouseEnter) {
+        this.props.onMouseEnter(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseLeave: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isHovered:false, isActive:false});
+      if (Boolean(this.props.onMouseLeave)) {
+        this.props.onMouseLeave(e, this);
+      }
+    }
+  },
+  onMouseOut: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      if (Boolean(this.props.onMouseOut)) {
+        this.props.onMouseOut(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchCancel: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive: false});
+      if (Boolean(this.props.onTouchCancel)) {
+        this.props.onTouchCancel(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchEnd: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive: false});
+      if (Boolean(this.props.onTouchEnd)) {
+        this.props.onTouchEnd(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchMove: function(e) {
+    if (Boolean(this.props.onTouchMove) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onTouchMove(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchStart: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive: true});
+      if (Boolean(this.props.onTouchStart)) {
+        this.props.onTouchStart(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onKeyDown: function(e) {
+    if (Boolean(this.props.onKeyDown) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onKeyDown(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onKeyPress: function(e) {
+    if (Boolean(this.props.onKeyPress) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onKeyPress(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onKeyUp: function(e) {
+    if (Boolean(this.props.onKeyUp) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onKeyUp(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onFocus: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isFocused: true});
+      if (Boolean(this.props.onFocus)) {
+        this.props.onFocus(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onBlur: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isFocused: false});
+      if (Boolean(this.props.onBlur)) {
+        this.props.onBlur(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+
+  /**
+   * Generic clone function that takes an object and returns an independent clone of it.
+   * Needed to give the user a clone of the props instead of the props themselves to prevent direct access to the props.
+   * @param obj
+   * @returns {*}
+   **/
+  clone: function(obj) {
+    if (null == obj || "object" != typeof obj) return obj;
+    var copy = obj.constructor();
+    for (var attr in obj) {
+      if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
+    }
+    return copy;
+  }
+};
diff --git a/skyquake/framework/widgets/multicomponent/multicomponent.js b/skyquake/framework/widgets/multicomponent/multicomponent.js
new file mode 100644 (file)
index 0000000..4c2f9a5
--- /dev/null
@@ -0,0 +1,57 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+var mixin = require('../mixins/ButtonEventListener.js')
+/**
+ *  Contains a set of components.  Takes a list of components and renders them in lists.
+ *  It's props values and a brief description below
+ *  component_list: Takes a list of React components.
+ */
+module.exports = React.createClass({
+  displayName: 'Multicomponent',
+  mixins:mixin.MIXINS,
+  propTypes: {
+    component_list:           React.PropTypes.array.isRequired
+  },
+
+  /**
+   * Defines default state.
+   *  component_list: Takes a list of React components.
+   */
+  getInitialState: function() {
+    return {
+      component_list: this.props.component_list
+
+    }
+  },
+
+
+  /**
+   * Renders the multicomponent Component
+   * Returns a list React components
+   * @returns {*}
+   */
+  render: function() {
+
+    var componentDOM = React.createElement("div", {className:this.props.className}, 
+      this.props.component_list
+    )
+    return componentDOM;
+  }
+});
\ No newline at end of file
diff --git a/skyquake/framework/widgets/nfvi-metric-bars/nfviMetricBars.jsx b/skyquake/framework/widgets/nfvi-metric-bars/nfviMetricBars.jsx
new file mode 100644 (file)
index 0000000..019c4d7
--- /dev/null
@@ -0,0 +1,80 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './nfviMetricBars.scss';
+class MetricChart extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+  render() {
+    let html;
+    let byteSize = 1e+9;
+    let utilization = this.props.utilization;
+    // let utilization = (1 > this.props.utilization) ? Math.round(this.props.utilization * 100) : this.props.utilization;
+    let isVCPU = (this.props.label == "VCPU");
+    let label;
+    if (isVCPU) {
+      label = this.props.total;
+    } else {
+      var num = this.props.used / byteSize;
+      label = Math.round(num * 100) / 100 + ' / ' +  Math.round(this.props.total / byteSize) + 'GB';
+    }
+    html = (
+            <div className="nvfi-metric-container">
+              <div className="nfvi-metric-chart">
+                <div className="nfvi-metric-chart-value">{utilization}%</div>
+                <div className="nfvi-metric-chart-bar" style={{height: utilization + '%'}}></div>
+              </div>
+              <div className="nfvi-metric-value">{label}</div>
+              <div className="nfvi-metric-label">{this.props.label}</div>
+            </div>
+            );
+    return html;
+  }
+}
+
+class nfviMetrics extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  render() {
+    let html;
+    let nfviMetrics = this.props.metrics.map(function(metric, k) {
+      //Do not display network metrics
+      if("outgoing" in metric || "incoming" in metric){
+        return
+      } else {
+        return (<MetricChart key={k} utilization={metric.utilization} label={metric.label} total={metric.total} used={metric.used}/>)
+      }
+    });
+    html = (
+      <div className="nfvi-metrics-tray">
+        {nfviMetrics}
+      </div>
+    )
+    return html;
+  }
+}
+nfviMetrics.defaultProps = {
+  metrics: []
+}
+
+
+
+export default nfviMetrics;
diff --git a/skyquake/framework/widgets/nfvi-metric-bars/nfviMetricBars.scss b/skyquake/framework/widgets/nfvi-metric-bars/nfviMetricBars.scss
new file mode 100644 (file)
index 0000000..fcd77bb
--- /dev/null
@@ -0,0 +1,102 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "../../../framework/style/_colors.scss";
+.nfvi-metrics-tray {
+      flex: 1 0;
+      display: flex;
+      flex-direction: row;
+      justify-content: space-around;
+      margin: 10px 0;
+      padding: 0 15px 0 10px;
+      height: 165px;
+     .nvfi-metric-container {
+        flex: 1 0;
+        display: flex;
+        flex-direction: column;
+        align-items: stretch;
+        margin: 0 10px 0 0;
+      }
+
+        .nfvi-metric-chart {
+          position: relative;
+          flex: 1 0;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          background: #fff;
+        }
+
+          .nfvi-metric-chart-value {
+            font-size: 2rem;
+            font-weight: 700;
+            z-index: 2;
+          }
+
+          .nfvi-metric-chart-bar {
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            right: 0;
+            height: 0%;
+            background: #00ACEE;
+            transition: all 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
+          }
+
+        .nfvi-metric-value {
+          padding: 5px 10px;
+          text-align: center;
+          font-size: 16px;
+        }
+
+        .nfvi-metric-label {
+          text-align: center;
+          font-size: 12px;
+          text-transform: uppercase;
+        }
+
+ }
+    .metricBars {
+      display:flex;
+      flex-direction:row;
+      flex-wrap:wrap;
+      padding: 1rem;
+      justify-content: space-around;
+      h3 {
+        text-align:center;
+        font-weight:bold;
+      }
+      .bar {
+        fill: $brand-blue-light;
+        stroke: black;
+      }
+      .y.axis {
+        .domain {
+          transform:scaleX(0.25);
+        }
+      }
+      .x.axis {
+        .domain {
+          transform:scaleY(0.25);
+        }
+     }
+     &>div {
+      flex: 1 1;
+      max-width:400px;
+     }
+   }
diff --git a/skyquake/framework/widgets/operational-status/launchpadOperationalStatus.jsx b/skyquake/framework/widgets/operational-status/launchpadOperationalStatus.jsx
new file mode 100644 (file)
index 0000000..ba77a79
--- /dev/null
@@ -0,0 +1,201 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import Loader from 'widgets/loading-indicator/loadingIndicator.jsx';
+
+//Currently displays all buffer state messages. Should consider showing only the n most recent.
+//TODO remove loader when current state is running
+//TODO need to look at refactoring this
+class ThrottledMessage extends React.Component {
+
+  constructor(props) {
+    super(props);
+    let self = this;
+    this.displayBuffer = [];
+    this.bufferInterval;
+    this.last_id = null;
+    this.state = {};
+    this.state.loading = props.loading;
+    this.state.buffer = {};
+    this.state.displayMessage = 'Loading...'
+  }
+
+  componentWillReceiveProps(nextProps) {
+    let buffer = nextProps.buffer;
+    if(buffer.length) {
+      this.buildBufferObject(nextProps);
+      this.bufferIt(this.props);
+    }
+  }
+
+  componentDidMount() {
+    if(this.props.buffer.length) {
+      let buffer = this.props.buffer;
+      this.buildBufferObject(this.props);
+      this.bufferIt(this.props);
+    }
+  }
+  componentWillUnmount() {
+    clearInterval(this.bufferInterval);
+  }
+  buildBufferObject(props) {
+    let self = this;
+    let buffer = self.state.buffer;
+    this.last_id = props.buffer[props.buffer.length -1].id;
+    props.buffer.map(function(item) {
+      if(!buffer[item.id]) {
+        buffer[item.id] = {
+          displayed: false,
+          data: item
+        }
+        self.displayBuffer.push(buffer[item.id]);
+      }
+    });
+  }
+
+  bufferIt(props) {
+    let self = this
+    clearInterval(self.bufferInterval);
+    self.bufferInterval = setInterval(function() {
+      let currentStatus = self.props.currentStatus;
+      let failed = currentStatus == 'failed';
+      for (let i = 0; i < self.displayBuffer.length; i++) {
+        if(!self.displayBuffer[i].displayed) {
+          self.displayBuffer[i].displayed = true;
+          let displaymsg;
+          if(failed) {
+            displaymsg = self.displayBuffer[self.displayBuffer.length-1].data.description;
+            clearInterval(self.bufferInterval);
+                self.props.onEnd(failed);
+          } else {
+            displaymsg = self.displayBuffer[i].data.description;
+          }
+          self.setState({
+              displayMessage: displaymsg
+          });
+          break;
+        }
+      }
+
+      if((currentStatus == 'running' || currentStatus == 'started' || currentStatus == 'stopped' || failed) && self.displayBuffer[self.displayBuffer.length - 1].displayed ) {
+                clearInterval(self.bufferInterval);
+                self.props.onEnd(failed);
+        }
+    }, 600)
+  }
+  render() {
+    if(!this.props.hasFailed) {
+      return (<span className='throttledMessageText'>{this.state.displayMessage}</span>)
+    } else {
+      return (<span> </span>)
+    }
+  }
+}
+
+ThrottledMessage.defaultProps = {
+  buffer: []
+}
+
+export default class operationalStatus extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {};
+    this.state.message = 'Loading...';
+    this.state.messageHistory = {};
+  }
+  componentWillReceiveProps(nextProps) {
+
+  }
+  finishedMessages(){
+    this.setState({
+      loading: false
+    })
+  }
+  statusMessage(currentStatus, currentStatusDetails) {
+    var message = currentStatus;
+    if (currentStatusDetails) {
+       message += ' - ' + currentStatusDetails;
+    }
+    return message;
+  }
+  render() {
+    let html;
+    let isDisplayed = this.props.display;
+    let isFailed = (this.props.currentStatus == 'failed') || false;
+    let title = (!this.props.loading || isFailed) ? <h2>History</h2> : '';
+    let status = this.props.status.map(function(status, index) {
+      return (
+        <li key={index}>
+          {status.description}
+          {status.details ? (
+            <ul>
+              <li>{status.details}
+              </li>
+            </ul>) : null}
+        </li>
+      )
+    }).reverse();
+    if(this.props.loading) {
+      if (!isFailed) {
+        isDisplayed = true;
+        //If there is no collection of status event message, just display currentStatus
+        if(status.length) {
+              html = (
+                      <div className={this.props.className + '_loading'}>
+                        <Loader show={!isFailed}/>
+                        <ThrottledMessage currentStatus={this.props.currentStatus} buffer={this.props.status} onEnd={this.props.doneLoading}/>
+                      </div>
+              )
+        } else {
+          html = (
+                      <div className={this.props.className + '_loading'}>
+                        <Loader show={!isFailed}/>
+                        {this.statusMessage(this.props.currentStatus,this.props.currentStatusDetails)}
+                      </div>
+              )
+        }
+      } else {
+          isDisplayed = true;
+              html = (
+
+                        <ul>
+                        <ThrottledMessage currentStatus={this.props.currentStatus} buffer={this.props.status} onEnd={this.props.doneLoading} hasFailed={isFailed}/>
+                          {status}
+                        </ul>
+              )
+      }
+    } else {
+      html = (
+          <ul>
+            {status}
+          </ul>
+      )
+    }
+    return (<div className={this.props.className + (isDisplayed ? '_open':'_close')}>{title} {html}</div>);
+  }
+}
+
+operationalStatus.defaultProps = {
+  status: [],
+  loading: true,
+  display: false
+}
+
+
+
diff --git a/skyquake/framework/widgets/panel/panel.jsx b/skyquake/framework/widgets/panel/panel.jsx
new file mode 100644 (file)
index 0000000..e8a3118
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React, {Component} from 'react';
+import 'style/core.css';
+import './panel.scss';
+export class Panel extends Component {
+    constructor(props) {
+        super(props)
+    }
+    render() {
+        let self = this;
+        let {children, className, title, ...props} = self.props;
+        let classRoot = className ? ' ' + className : ' '
+        let titleTag = title ? <header className="skyquakePanel-title">{title}</header> : '';
+        return (
+            <section className={'skyquakePanel' + classRoot} style={props.style}>
+                <i className="corner-accent top left"></i>
+                <i className="corner-accent top right"></i>
+                {titleTag}
+                <div className="skyquakePanel-wrapper">
+                    <div className={(classRoot ? 'skyquakePanel-body ' + decorateClassNames(classRoot, '-body') : 'skyquakePanel-body')}>
+                            {children}
+                    </div>
+                </div>
+                <i className="corner-accent bottom left"></i>
+                <i className="corner-accent bottom right"></i>
+            </section>
+        )
+    }
+}
+
+Panel.defaultProps = {
+
+}
+
+export class PanelWrapper extends Component {
+    render() {
+        return (<div className={'skyquakePanelWrapper'}>
+            {this.props.children}
+        </div>)
+    }
+}
+
+export default Panel;
+
+
+function decorateClassNames(className, addendum) {
+    return className.split(' ').map(function(c) {
+        return c + addendum
+    }).join(' ');
+}
diff --git a/skyquake/framework/widgets/panel/panel.scss b/skyquake/framework/widgets/panel/panel.scss
new file mode 100644 (file)
index 0000000..ff36bbf
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import '../../style/_colors.scss';
+.skyquakePanel {
+    position:relative;
+    display:-ms-flexbox;
+    display:flex;
+    -ms-flex-direction:column;
+    flex-direction:column;
+    -ms-flex:1 1;
+    flex:1 1;
+    background-color: $body-color;
+    margin:0.5rem;
+        &-title{
+            display: -ms-flexbox;
+            display: flex;
+            -ms-flex-align: center;
+            -ms-grid-row-align: center;
+            align-items: center;
+            padding: 1rem;
+            background-color: white;
+            text-transform: uppercase;
+        }
+        &-wrapper {
+            overflow:auto;
+            height:100vh;
+        }
+        &-body {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-direction:column;
+            flex-direction:column;
+            padding:1rem;
+        }
+        &Wrapper {
+            display:-ms-flexbox;
+            display:flex;
+            width:100%;
+            height:100%;
+        }
+}
+
+/* Style for storybook */
+body{
+    height:100%;
+>#root{
+    height:100vh;
+    width:100vw;
+    display:-ms-flexbox;
+    display:flex;
+}
+}
diff --git a/skyquake/framework/widgets/radio-button/rw.radio-button.js b/skyquake/framework/widgets/radio-button/rw.radio-button.js
new file mode 100644 (file)
index 0000000..706d39e
--- /dev/null
@@ -0,0 +1,267 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
+
+
+/**
+ *  A radio-button component.
+ *  It's props values and a brief description below
+ *
+ *  label:        The label for the radio button group.
+ *  radiobuttons: The object that creates each radio button.  Each object has a property "label" and "checked".
+ *    label:        The label for the individual radio button.
+ *    checked:      If set to true, the individual radio button is initialized with a check.
+ *  requiredText: The text content of the "if required" message.
+ *  errorText:    The text content of the error message.
+ *  ClassName:    Css Classes applied to the element.
+ *  size:         The size of the element.
+ *  isRequired:   A boolean indicating whether or not the input is required.
+ *  isDisabled:   A boolean indicating the disabled state of the element.
+ *  isReadOnly:   A boolean indicating whether or not the input is read only.
+ *  instructions: The text content of the instructions
+ **/
+module.exports = React.createClass({
+  displayName: "RadioButton",
+  mixins:[ButtonEventListenerMixin],
+  propTypes: {
+    name:            React.PropTypes.string,
+    label:           React.PropTypes.string,
+    radiobuttons:    React.PropTypes.arrayOf(
+      React.PropTypes.shape(
+        {
+          label:   React.PropTypes.string,
+          checked: React.PropTypes.bool
+        }
+      )),
+    requiredText:    React.PropTypes.string,
+    errorText:       React.PropTypes.string,
+    placeholder:     React.PropTypes.string,
+    className:       React.PropTypes.string,
+    size:            React.PropTypes.string,
+    isRequired:      React.PropTypes.bool,
+    isDisabled:      React.PropTypes.bool,
+    isReadOnly:      React.PropTypes.bool,
+    instructions:    React.PropTypes.string
+  },
+
+
+  /**
+   * Sets the default input state.
+   * If there is no description for the variable, assume it's the same as it's props counterpart.
+   *
+   * isActive: Boolean to indicate if input is active.
+   * isHovered: Boolean to indicate if the input is being hovered over.
+   * isFocused: Boolean to indicate if the input has been focused.
+   * isDisabled: Boolean to indicate if input has been disabled.
+   *
+   * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
+   * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
+   * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
+   * isValid: null, isSuccess: null}}
+   */
+  getInitialState: function() {
+    return {
+      label:            this.props.label || "",
+      requiredText:     this.props.requiredText || "Required",
+      instructionsText: this.props.instructions || "",
+      errorText:        this.props.errorText || "",
+      size:             this.props.size || '',
+      isActive:         false,
+      isHovered:        false,
+      isFocused:        false,
+      isDisabled:       this.props.disabled || false,
+      isReadOnly:       this.props.isReadOnly || false,
+      isRequired:       this.props.isRequired || null,
+      isValid:          null,      // Three way bool. Valid: true.   Invalid: false. Not acted on: null.
+      isSuccess:        null       // Three way bool. Success: true. Error: false.   Not acted on: null.
+    }
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
+   * "this.props" and "this.state" hold the state and property variables as they were before the update.
+   * returns true if the state have changed. Otherwise returns false.
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
+      this.state.isHovered + this.state.isValid + this.state.isSuccess;
+    var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
+      nextState.isHovered + nextState.isValid + nextState.isSuccess;
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    return true;
+  },
+
+
+
+  /**
+   * Returns a string reflecting the current state of the input.
+   * If the component state "isDisabled" is true, returns a string "disabled".
+   * If the component state "isReadOnly" is true, returns a string "readonly".
+   * Otherwise returns a string containing a word for each state that has been set to true.
+   * (ie "active focused" if the states active and focused are true, but hovered is false).
+   * @returns {string}
+   */
+  setComponentState: function() {
+    var ret = "";
+    if (this.state.isDisabled) {
+      return "disabled";
+    }
+    if (this.state.isReadOnly) {
+      return "readonly";
+    }
+    if (this.state.isActive) {
+      ret += "active ";
+    }
+    if (this.state.isHovered) {
+      ret += "hovered ";
+    }
+    if (this.state.isFocused) {
+      ret += "focused ";
+    }
+    return ret;
+  },
+
+  /**
+   * Renders the Text Input component.
+   *
+   **/
+  render: function() {
+    var input = [];
+    var label = [];
+    var input_style = {};
+    var input_state = this.setComponentState();
+
+    // The following if statements translates the min/max width from a number into a string.
+    if (this.props.minWidth) {
+      input_style['min-width'] = String(this.props.minWidth) + 'px';
+    }
+    if (this.props.maxWidth) {
+      input_style['max-width'] = String(this.props.maxWidth) + 'px';
+    }
+
+    //// The input element.
+    //input = React.createElement("input", {
+    //    ref:               "inputRef",
+    //    "data-state":      input_state,
+    //    "type":            "checkbox",
+    //    placeholder:       this.props.placeholder,
+    //    pattern:           this.props.pattern,
+    //    maxLength:         this.props.maxLength,
+    //    required:          this.state.isRequired,
+    //    disabled:          this.state.isDisabled,
+    //    readOnly:          this.state.isReadOnly,
+    //    onChange:          this.handleChange,
+    //    onClick:           this.onClick,
+    //    onMouseUp:         this.onMouseUp,
+    //    onMouseDown:       this.onMouseDown,
+    //    onMouseOver:       this.onMouseOver,
+    //    onMouseEnter:      this.onMouseEnter,
+    //    onMouseLeave:      this.onMouseLeave,
+    //    onMouseOut:        this.onMouseOut,
+    //    onTouchCancel:     this.onTouchCancel,
+    //    onTouchEnd:        this.onTouchEnd,
+    //    onTouchMove:       this.onTouchMove,
+    //    onTouchStart:      this.onTouchStart,
+    //    onKeyDown:         this.onKeyDown,
+    //    onKeyPress:        this.onKeyPress,
+    //    onKeyUp:           this.onKeyUp,
+    //    onFocus:           this.onFocus,
+    //    onBlur:            this.onBlur,
+    //    className:         (this.props.className || "rw-textinput"),
+    //    tabIndex:          0
+    //  },
+    //  null
+    //);
+
+    label = React.createElement("label", null, this.props.label);
+
+    for (var i = 0; i < this.props.radiobuttons.length; i++) {
+
+      // Label for the whole radio button group
+      input[i] = React.createElement("label",
+        {
+          key:i*2 + 1,
+          readOnly:this.props.readonly,
+          disabled:this.props.disabled
+        },
+
+        // Creates each radio button input element.
+        React.createElement("input", {
+            key: i*2,
+            defaultChecked: this.props.radiobuttons[i].checked,
+            type: "radio",
+            name: this.props.name,
+            readOnly: this.props.readonly,
+            disabled: this.props.disabled,
+            onClick:           this.onClick,
+            onMouseUp:         this.onMouseUp,
+            onMouseDown:       this.onMouseDown,
+            onMouseOver:       this.onMouseOver,
+            onMouseEnter:      this.onMouseEnter,
+            onMouseLeave:      this.onMouseLeave,
+            onMouseOut:        this.onMouseOut,
+            onTouchCancel:     this.onTouchCancel,
+            onTouchEnd:        this.onTouchEnd,
+            onTouchMove:       this.onTouchMove,
+            onTouchStart:      this.onTouchStart,
+            onKeyDown:         this.onKeyDown,
+            onKeyPress:        this.onKeyPress,
+            onKeyUp:           this.onKeyUp,
+            onFocus:           this.onFocus,
+            onBlur:            this.onBlur
+          },
+          null
+        ),
+        this.props.radiobuttons[i].label);
+    }
+
+    // The "if required" element. It displays a label if the element is required.
+    if(this.props.isRequired == true){
+      var requiredEle = React.createElement("small", {className: "rw-form-requiredLabel"}, this.state.requiredText);
+    }
+
+    // The "error" element.  It pops up as a message if there is an error with the input.
+    if(this.state.errorText != "") {
+      var error = React.createElement("p", {className: "rw-form-errorMsg"}, this.state.errorText);
+    }
+
+    // The "instruction" element.
+    if(this.state.instructionsText != ""){
+      var instructions = React.createElement("p", {className: "rw-form-instructions"}, this.state.instructionsText)
+    }
+
+    // The parent element for all.
+    var ret = React.createElement("div", {
+      "data-state":      input_state,
+      required:          this.state.isRequired,
+      disabled:          this.state.isDisabled,
+      readOnly:          this.state.isReadOnly
+    }, requiredEle, label, input, error, instructions);
+
+    return ret;
+  }
+});
diff --git a/skyquake/framework/widgets/screen-loader/screenLoader.jsx b/skyquake/framework/widgets/screen-loader/screenLoader.jsx
new file mode 100644 (file)
index 0000000..eac33a9
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Loader from '../loading-indicator/loadingIndicator.jsx';
+import React from 'react';
+
+export default class ScreenLoader extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+  render() {
+    let overlayStyle = {
+      position: 'fixed',
+      zIndex: 999,
+      width: '100%',
+      height: '100%',
+      top: 0,
+      // right: 0,
+      // bottom: 0,
+      left: 0,
+      display: this.props.show ? 'flex' : 'none',
+      justifyContent: 'center',
+      alignItems: 'center',
+      scroll: 'none',
+      backgroundColor: 'rgba(0,0,0,0.5)'
+    };
+    return (
+      <div style={overlayStyle}><Loader size="10"/></div>
+    );
+  }
+}
diff --git a/skyquake/framework/widgets/skyquake_container/eventCenter.jsx b/skyquake/framework/widgets/skyquake_container/eventCenter.jsx
new file mode 100644 (file)
index 0000000..75d2d52
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+ /**
+  * EventCenter module to display a list of events from the system
+  * @module framework/widgets/skyquake_container/EventCenter
+  * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+  *
+  */
+
+import React from 'react';
+import { Link } from 'react-router';
+import Utils from 'utils/utils.js';
+import Crouton from 'react-crouton';
+import TreeView from 'react-treeview';
+import _ from 'lodash';
+import '../../../node_modules/react-treeview/react-treeview.css';
+import './eventCenter.scss';
+
+export default class EventCenter extends React.Component {
+       constructor(props) {
+               super(props);
+               this.state = {};
+               this.state.isOpen = false;
+       }
+
+       componentWillReceiveProps(props) {
+               let stateObject = {};
+
+               let notificationList = sessionStorage.getItem('notificationList');
+               let latestNotification = sessionStorage.getItem('latestNotification');
+
+               if (props.newNotificationEvent && props.newNotificationMsg) {
+                       if (latestNotification) {
+                               latestNotification = JSON.parse(latestNotification);
+                               if (!_.isEqual(props.newNotificationMsg, latestNotification)) {
+                                       stateObject.newNotificationEvent = props.newNotificationEvent;
+                                       stateObject.newNotificationMsg = props.newNotificationMsg;
+                                       sessionStorage.setItem('latestNotification', JSON.stringify(stateObject.newNotificationMsg));
+                               } else {
+                                       stateObject.newNotificationEvent = false;
+                                       stateObject.newNotificationMsg = null;
+                               }
+                       } else {
+                               stateObject.newNotificationEvent = true;
+                               stateObject.newNotificationMsg = props.newNotificationMsg;
+                               sessionStorage.setItem('latestNotification', JSON.stringify(stateObject.newNotificationMsg));
+                       }
+               } else {
+                       stateObject.newNotificationEvent = false;
+                       stateObject.newNotificationMsg = null;
+               }
+
+               if (notificationList) {
+                       stateObject.notifications = _.merge(notificationList, props.notifications);
+               } else {
+                       stateObject.notifications = props.notifications;
+               }
+               sessionStorage.setItem('notifications', JSON.stringify(stateObject.notifications));
+               this.setState(stateObject);
+       }
+
+       newNotificationReset = () => {
+        this.setState({
+            newNotificationEvent: false
+        });
+    }
+
+       onClickToggleOpenClose(event) {
+               this.props.onToggle();
+               this.setState({
+                       isOpen: !this.state.isOpen
+               });
+       }
+       constructTree(details) {
+               let markup = [];
+               for (let key in details) {
+                       if (typeof(details[key]) == "object") {
+                           let html = (
+                               <TreeView key={key} nodeLabel={key}>
+                                 {this.constructTree(details[key])}
+                               </TreeView>
+                           );
+                           markup.push(html);
+                       } else {
+                               markup.push((<div key={key} className="info">{key} = {details[key].toString()}</div>));
+                       }
+               }
+               return markup;
+       }
+
+       getNotificationFields(notification) {
+               let notificationFields = {};
+               if (notification) {
+
+                       notificationFields.source = notification.source;
+                       notificationFields.eventTime = notification.eventTime;
+
+                       Object.keys(notification).map((notificationKey) => {
+                               if (_.indexOf(['source', 'eventTime'], notificationKey) == -1) {
+                                       notificationFields.eventKey = notificationKey;
+                                       notificationFields.details = notification[notificationFields.eventKey];
+                               }
+                       });
+
+               }
+               return notificationFields;
+       }
+
+       render() {
+               let html;
+               let displayNotifications = [];
+               let displayNotificationsTableHead = null;
+
+               if (this.state.notifications && this.state.notifications.length > 0) {
+                       displayNotificationsTableHead = (
+                               <thead>
+                                       <tr key='header' className='header'>
+                                               <th className='source column'> Source Event Stream </th>
+                                               <th className='timestamp column'> Timestamp </th>
+                                               <th className='event column'> Event </th>
+                                               <th className='details column'> Details </th>
+                                       </tr>
+                               </thead>
+                       );
+               }
+
+               this.state.notifications && this.state.notifications.map((notification, notifIndex) => {
+                       let notificationFields = {};
+
+                       notificationFields = this.getNotificationFields(notification);
+
+                       displayNotifications.push(
+                               <tr key={notifIndex} className='notificationItem'>
+                                       <td className='source column'> {notificationFields.source} </td>
+                                       <td className='timestamp column'> {notificationFields.eventTime} </td>
+                                       <td className='event column'> {notificationFields.eventKey} </td>
+                                       <td className='details column'>
+                                               <TreeView key={notifIndex + '-detail'} nodeLabel='Event Details'>
+                                                       {this.constructTree(notificationFields.details)}
+                                               </TreeView>
+                                       </td>
+                               </tr>
+                       );
+               });
+
+               let openedClassName = this.state.isOpen ? 'open' : 'closed';
+               html = (
+                       <div className={'eventCenter ' + openedClassName}>
+
+                        <div className='notification'>
+                            <Crouton
+                                id={Date.now()}
+                                message={this.getNotificationFields(this.state.newNotificationMsg).eventKey +
+                                       ' notification received. Check Event Center for more details.'}
+                                type={'info'}
+                                hidden={!(this.state.newNotificationEvent && this.state.newNotificationMsg)}
+                                onDismiss={this.newNotificationReset}
+                                timeout={this.props.dismissTimeout}
+                            />
+                        </div>
+                               <h1 className='title' data-open-close-icon={this.state.isOpen ? 'open' : 'closed'}
+                                       onClick={this.onClickToggleOpenClose.bind(this)}>
+                                       EVENT CENTER
+                               </h1>
+                               <div className='notificationListBody'>
+                                       <table className='notificationList'>
+                                               {displayNotificationsTableHead}
+                                               <tbody>
+                                                       {displayNotifications}
+                                               </tbody>
+                                       </table>
+                               </div>
+                       </div>
+               );
+
+               return html;
+       }
+}
+
+EventCenter.defaultProps = {
+       dismissTimeout: 3000
+}
diff --git a/skyquake/framework/widgets/skyquake_container/eventCenter.scss b/skyquake/framework/widgets/skyquake_container/eventCenter.scss
new file mode 100644 (file)
index 0000000..103d416
--- /dev/null
@@ -0,0 +1,152 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@import '../../style/colors.scss';
+
+.eventCenter {
+       background-color: $white;
+       z-index: 9999;
+       position: relative;
+
+       [data-open-close-icon] {
+           &:after {
+               content: " ";
+               display: block;
+               float: right;
+               margin-right: 8px;
+               height: 51px;
+               width: 51px;
+               opacity: 0.25;
+               background-size: 20px 20px;
+               background-repeat: no-repeat;
+               background-position: center center;
+               /* background-image required in order for background-size to work*/
+               background-image: url(../../../node_modules/open-iconic/svg/caret-bottom.svg);
+               vertical-align: middle;
+           }
+           &:hover:after {
+               opacity: 1;
+           }
+       }
+       [data-open-close-icon="closed"]:after {
+           transform: rotate(180deg);
+           transition: all 300ms cubic-bezier(0.77, 0, 0.175, 1);
+       }
+       [data-open-close-icon="open"]:after {
+           transform: rotate(0deg);
+           transition: all 300ms cubic-bezier(0.77, 0, 0.175, 1);
+       }
+
+
+       .notification {
+        .crouton {
+            right: 4px;
+            top: 34px;
+            width: 30%;
+            left: auto;
+            .info {
+                border-radius: 25px;
+            }
+        }
+    }
+       &.-with-transitions {
+               transition: height 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
+       }
+       &.open {
+               .notificationListBody {
+                       height: 300px;
+               }
+       }
+       &.closed {
+               .notificationListBody {
+                       height: 0px;
+               }
+       }
+       .title {
+               border-top: 1px solid $gray-dark;
+               border-bottom: 1px solid $gray-dark;
+               cursor: pointer;
+               color: $gray-darker;
+               font-style: normal;
+               font-size: 1.625rem;
+       font-weight: 400;
+               height: 51px;
+               line-height: 51px;
+               margin: 0;
+               padding-left: 0;
+               padding-right: 0;
+               text-align: center;
+               text-transform: uppercase;
+               background-color: $gray-lighter;
+       }
+       .notificationListBody {
+               overflow: auto;
+               .notificationList {
+                       width: 100%;
+                       &:hover {
+                               overflow: auto;
+                       }
+                       
+                       .notificationItem {
+
+                       }
+
+                       th {
+                               text-align: left;
+                padding: 0.5rem;
+                background: $gray-darker;
+                border: 1px solid black;
+                               color: $white;
+                               &.source {
+                                       width: 20%;
+                               }
+                               &.timestamp {
+                                       width: 20%;
+                               }
+                               &.event {
+                                       width: 20%;
+                               }
+                               &.details {
+                                       width: 40%;
+                               }
+                       }
+
+                       tr {
+                               padding: 0.5rem;
+                               border: 1px solid black;
+
+                               &:nth-child(odd) {
+                                       background: $white;
+                                       td {
+                           border: 1px solid black;
+                           padding: 0.5rem;
+                       }
+                               }
+
+                               &:nth-child(even) {
+                                       background: $gray-lighter;
+                                       td {
+                           border: 1px solid black;
+                           padding: 0.5rem;
+                       }
+                               }
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeAltInstance.js b/skyquake/framework/widgets/skyquake_container/skyquakeAltInstance.js
new file mode 100644 (file)
index 0000000..0b7876e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+//Alt Instance.
+import Alt from 'alt';
+var path = require('path');
+if (!window.A) {
+    window.A = new Alt();
+    Alt.debug('alt', window.A);
+    console.log('new alt', path.resolve(__dirname));
+}
+
+module.exports = window.A;
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeApp.scss b/skyquake/framework/widgets/skyquake_container/skyquakeApp.scss
new file mode 100644 (file)
index 0000000..4f77d71
--- /dev/null
@@ -0,0 +1,143 @@
+//import a reset
+@import '../../style/_colors.scss';
+html, body {
+    height:100%;
+    width:100%;
+}
+
+
+.skyquakeApp {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    background: $gray-lightest;
+    h1 {
+        text-transform: uppercase;
+    }
+    .active {
+        background-color: $brand-blue!important;
+        border-color: $brand-blue!important;
+        color: #fff!important
+    }
+    .skyquakeNav {
+        display: flex;
+        color:white;
+        background:black;
+        position:relative;
+        z-index: 10;
+        font-size:0.75rem;
+        .secondaryNav {
+            flex: 1 1 auto;
+            display: flex;
+            justify-content: flex-end;
+        }
+        .app {
+            position:relative;
+            h2 {
+                font-size:0.75rem;
+                border-right: 1px solid black;
+                display: flex;
+                align-items: center;
+                .oi {
+                    padding-right: 0.5rem;
+                }
+            }
+            .menu {
+                position:absolute;
+                display:none;
+                z-index:2;
+                width: 100%;
+            }
+            &:first-child{
+                h2 {
+                    border-left: 1px solid black;
+                }
+            }
+            &:hover {
+                a {
+                    color:$brand-blue-light;
+                    cursor:pointer;
+                }
+                .menu {
+                    display:block;
+                    background:black;
+                    a {
+                        color:white;
+                    }
+                    li:hover {
+                        a {
+                            color:$brand-blue-light;
+                        }
+                    }
+                }
+            }
+            &.active {
+                color:white;
+                background:black;
+                a {
+                    color:white;
+                }
+            }
+        }
+        a{
+            display:block;
+            padding:0.5rem 1rem;
+            text-decoration:none;
+            text-transform:uppercase;
+            color:white;
+        }
+        &:before {
+            content: '';
+            height:1.85rem;
+            width:2.5rem;
+            margin:0 1rem;
+            padding:0 0.125rem;
+            // background: url('../../style/img/header-logo.png') no-repeat center center white;
+            background: url('../../style/img/svg/riftio_logo_white.svg') no-repeat center center;
+            background-size:65%;
+        }
+    }
+    .skyquakeContainerWrapper {
+    }
+    .titleBar {
+        padding: 1rem 0 0;
+        h1 {
+        // background: url('../../style/img/header-logo.png') no-repeat;
+        background-size:contain;
+        height: 51px;
+        line-height: 51px;
+        margin-left: 20px;
+        // padding-left: 100px;
+        left: 0;
+        font-size: 1.625rem;
+        font-weight: 400;
+        text-align:left;
+        position:relative;
+        flex: 1 0 auto;
+        }
+    }
+    .corner-accent {
+        border: 1px solid #000;
+        display: block;
+        height: 4px;
+        position: absolute;
+        width: 4px;
+
+        &.top {
+            border-bottom: 0;
+            top: -1px;
+        }
+        &.right {
+            border-left: 0;
+            right: -1px;
+        }
+        &.bottom {
+            border-top: 0;
+            bottom: -1px;
+        }
+        &.left {
+            border-right: 0;
+            left: -1px;
+        }
+    }
+}
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeComponent.jsx b/skyquake/framework/widgets/skyquake_container/skyquakeComponent.jsx
new file mode 100644 (file)
index 0000000..893a4c1
--- /dev/null
@@ -0,0 +1,18 @@
+import React from 'react';
+export default function(Component) {
+  class SkyquakeComponent extends React.Component {
+    constructor(props, context) {
+        super(props, context);
+        this.router = context.router;
+        this.actions = context.flux.actions.global;
+    }
+    render(props) {
+        return <Component {...this.props} router={this.router} actions={this.actions} flux={this.context.flux} />
+    }
+  }
+  SkyquakeComponent.contextTypes = {
+    router: React.PropTypes.object,
+    flux: React.PropTypes.object
+  };
+  return SkyquakeComponent;
+}
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx b/skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx
new file mode 100644 (file)
index 0000000..eca9413
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import AltContainer from 'alt-container';
+import Alt from './skyquakeAltInstance.js';
+import SkyquakeNav from './skyquakeNav.jsx';
+import EventCenter from './eventCenter.jsx';
+import SkyquakeContainerActions from './skyquakeContainerActions.js'
+import SkyquakeContainerStore from './skyquakeContainerStore.js';
+import Breadcrumbs from 'react-breadcrumbs';
+import Utils from 'utils/utils.js';
+import _ from 'lodash';
+import Crouton from 'react-crouton';
+import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
+import './skyquakeApp.scss';
+// import 'style/reset.css';
+import 'style/core.css';
+export default class skyquakeContainer extends React.Component {
+    constructor(props) {
+        super(props);
+        let self = this;
+        this.state = SkyquakeContainerStore.getState();
+        //This will be populated via a store/source
+        this.state.nav = this.props.nav || [];
+        this.state.eventCenterIsOpen = false;
+        this.state.currentPlugin = SkyquakeContainerStore.currentPlugin;
+    }
+
+    componentWillMount() {
+        let self = this;
+
+        Utils.bootstrapApplication().then(function() {
+            SkyquakeContainerStore.listen(self.listener);
+            SkyquakeContainerStore.getNav();
+            SkyquakeContainerStore.getEventStreams();
+        });
+
+        // Load multiplex-client
+        const script = document.createElement("script");
+
+        script.src = "/multiplex-client";
+        script.async = true;
+
+        document.body.appendChild(script);
+
+        Utils.setupMultiplexClient();
+    }
+
+    componentWillUnmount() {
+        SkyquakeContainerStore.unlisten(this.listener);
+    }
+    listener = (state) => {
+        this.setState(state);
+    }
+    matchesLoginUrl() {
+        //console.log("window.location.hash=", window.location.hash);
+        // First element in the results of match will be the part of the string
+        // that matched the expression. this string should be true against
+        // (window.location.hash.match(re)[0]).startsWith(Utils.loginHash)
+        var re = /#\/login?(\?|\/|$)/i;
+        //console.log("res=", window.location.hash.match(re));
+        return (window.location.hash.match(re)) ? true : false;
+    }
+    onToggle = (isOpen) => {
+        this.setState({
+            eventCenterIsOpen: isOpen
+        });
+    }
+
+    render() {
+        const {displayNotification, notificationMessage, displayScreenLoader, ...state} = this.state;
+        var html;
+
+        if (this.matchesLoginUrl()) {
+            html = (
+                <AltContainer>
+                    <div className="skyquakeApp">
+                        {this.props.children}
+                    </div>
+                </AltContainer>
+            );
+        } else {
+            let tag = this.props.routes[this.props.routes.length-1].name ? ': '
+                + this.props.routes[this.props.routes.length-1].name : '';
+            let routeName = this.props.location.pathname.split('/')[1];
+            html = (
+                <AltContainer flux={Alt}>
+                    <div className="skyquakeApp wrap">
+                        <Crouton
+                            id={Date.now()}
+                            message={notificationMessage}
+                            type={"error"}
+                            hidden={!(displayNotification && notificationMessage)}
+                            onDismiss={SkyquakeContainerActions.hideNotification}
+                        />
+                        <ScreenLoader show={displayScreenLoader}/>
+                        <SkyquakeNav nav={this.state.nav}
+                            currentPlugin={this.state.currentPlugin}
+                            store={SkyquakeContainerStore} />
+                        <div className="titleBar">
+                            <h1>{this.state.currentPlugin + tag}</h1>
+                        </div>
+                        <div className={"application " + routeName}>
+                            {this.props.children}
+                        </div>
+                        <EventCenter className="eventCenter"
+                            notifications={this.state.notifications}
+                            newNotificationEvent={this.state.newNotificationEvent}
+                            newNotificationMsg={this.state.newNotificationMsg}
+                            onToggle={this.onToggle} />
+                    </div>
+                </AltContainer>
+            );
+        }
+        return html;
+    }
+}
+skyquakeContainer.contextTypes = {
+    router: React.PropTypes.object
+  };
+
+/*
+<Breadcrumbs
+                            routes={this.props.routes}
+                            params={this.props.params}
+                            separator=" | "
+                        />
+ */
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js
new file mode 100644 (file)
index 0000000..773978b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from './skyquakeAltInstance.js';
+export default Alt.generateActions(
+       'getSkyquakeNavSuccess',
+       'openNotificationsSocketLoading',
+       'openNotificationsSocketSuccess',
+       'openNotificationsSocketError',
+       'getEventStreamsLoading',
+       'getEventStreamsSuccess',
+       'getEventStreamsError',
+    //Notifications
+    'showNotification',
+    'hideNotification',
+    //Screen Loader
+    'showScreenLoader',
+    'hideScreenLoader'
+);
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js
new file mode 100644 (file)
index 0000000..2ee50c0
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from './skyquakeAltInstance.js';
+import $ from 'jquery';
+import SkyquakeContainerActions from './skyquakeContainerActions'
+
+let Utils = require('utils/utils.js');
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = require('utils/rw.js').getSearchParams(window.location).dev_mode || false;
+let RW_REST_API_PORT = require('utils/rw.js').getSearchParams(window.location).rw_rest_api_port || 8008;
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+export default {
+    getNav() {
+        return {
+            remote: function() {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: '/nav',
+                        type: 'GET',
+                        // beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    })
+                })
+            },
+            success: SkyquakeContainerActions.getSkyquakeNavSuccess
+        }
+    },
+
+    getEventStreams() {
+        return {
+            remote: function(state, recordID) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: '//' + window.location.hostname + ':' + NODE_PORT + '/api/operational/restconf-state/streams?api_server=' + API_SERVER,
+                        type: 'GET',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    }).fail(function(xhr) {
+                        //Authentication and the handling of fail states should be wrapped up into a connection class.
+                        Utils.checkAuthentication(xhr.status);
+                    });;
+                });
+            },
+            loading: SkyquakeContainerActions.getEventStreamsLoading,
+            success: SkyquakeContainerActions.getEventStreamsSuccess,
+            error: SkyquakeContainerActions.getEventStreamsError
+        }
+    },
+
+    openNotificationsSocket() {
+        return {
+            remote: function(state, location, streamSource) {
+                return new Promise((resolve, reject) => {
+                    $.ajax({
+                        url: '//' + window.location.hostname + ':' + NODE_PORT + '/socket-polling?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        data: {
+                            url: location
+                        },
+                        success: (data) => {
+                            // var url = Utils.webSocketProtocol() + '//' + window.location.hostname + ':' + data.port + data.socketPath;
+                            // var ws = new WebSocket(url);
+                            // resolve({
+                            //     ws: ws,
+                            //     streamSource: streamSource
+                            // });
+                            const checker = () => {
+                                if (!Utils.isMultiplexerLoaded()) {
+                                    setTimeout(() => {
+                                        checker();
+                                    }, 500);
+                                } else {
+                                    resolve({
+                                        connection: data.id,
+                                        streamSource: streamSource
+                                    });
+                                }
+                            };
+
+                            checker();
+                        }
+                    });
+                });
+            },
+            loading: SkyquakeContainerActions.openNotificationsSocketLoading,
+            success: SkyquakeContainerActions.openNotificationsSocketSuccess,
+            error: SkyquakeContainerActions.openNotificationsSocketError
+        }
+    }
+}
+
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js
new file mode 100644 (file)
index 0000000..fe4a7b0
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+//This will reach out to the global routes endpoint
+
+import Alt from './skyquakeAltInstance.js';
+import SkyquakeContainerSource from './skyquakeContainerSource.js';
+import SkyquakeContainerActions from './skyquakeContainerActions';
+import _ from 'lodash';
+//Temporary, until api server is on same port as webserver
+var rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var UPLOAD_SERVER = rw.getSearchParams(window.location).upload_server;
+
+class SkyquakeContainerStore {
+    constructor() {
+        this.currentPlugin = getCurrentPlugin();
+        this.nav = {};
+        this.notifications = [];
+        this.socket = null;
+        //Notification defaults
+        this.notificationMessage = '';
+        this.displayNotification = false;
+        //Screen Loader default
+        this.displayScreenLoader = false;
+        this.bindActions(SkyquakeContainerActions);
+        this.exportAsync(SkyquakeContainerSource);
+
+
+        this.exportPublicMethods({
+            // getNav: this.getNav
+        });
+
+    }
+    getSkyquakeNavSuccess = (data) => {
+        var self = this;
+        this.setState({
+            nav: decorateAndTransformNav(data, self.currentPlugin)
+        })
+    }
+
+    closeSocket = () => {
+        if (this.socket) {
+            window.multiplexer.channel(this.channelId).close();
+        }
+        this.setState({
+            socket: null
+        });
+    }
+    //Remove once logging plugin is implemented
+    getSysLogViewerURLSuccess(data){
+        window.open(data.url);
+    }
+    getSysLogViewerURLError(data){
+        console.log('failed', data)
+    }
+
+    openNotificationsSocketLoading = () => {
+        this.setState({
+            isLoading: true
+        })
+    }
+
+    openNotificationsSocketSuccess = (data) => {
+        var self = this;
+
+        let connection = data.connection;
+        let streamSource = data.streamSource;
+        console.log('Success opening notification socket for stream ', streamSource);
+        
+        let ws = window.multiplexer.channel(connection);
+        
+        if (!connection) return;
+        self.setState({
+            socket: ws.ws,
+            isLoading: false,
+            channelId: connection
+        });
+
+        ws.onmessage = (socket) => {
+            try {
+                var data = JSON.parse(socket.data);
+                if (!data.notification) {
+                    console.warn('No notification in the received payload: ', data);
+                } else {
+                    // Temp to test before adding multi-sources
+                    data.notification.source = streamSource;
+                    if (_.indexOf(self.notifications, data.notification) == -1) {
+                        // newly appreared event.
+                        // Add to the notifications list and setState
+                        self.notifications.unshift(data.notification);
+                        self.setState({
+                            newNotificationEvent: true,
+                            newNotificationMsg: data.notification,
+                            notifications: self.notifications,
+                            isLoading: false
+                        });
+                    }
+                }
+            } catch(e) {
+                console.log('Error in parsing data on notification socket');
+            }
+        };
+
+        ws.onclose = () => {
+            self.closeSocket();
+        };
+    }
+
+    openNotificationsSocketError = (data) => {
+        console.log('Error opening notification socket', data);
+    }
+
+    getEventStreamsLoading = () => {
+        this.setState({
+            isLoading: true
+        });
+    }
+
+    getEventStreamsSuccess = (streams) => {
+        console.log('Found streams: ', streams);
+        let self = this;
+
+        streams['ietf-restconf-monitoring:streams'] &&
+        streams['ietf-restconf-monitoring:streams']['stream'] &&
+        streams['ietf-restconf-monitoring:streams']['stream'].map((stream) => {
+            stream['access'] && stream['access'].map((streamLocation) => {
+                if (streamLocation['encoding'] == 'ws_json') {
+                    setTimeout(() => {
+                        self.getInstance().openNotificationsSocket(streamLocation['location'], stream['name']);
+                    }, 0);
+                }
+            })
+        })
+
+        this.setState({
+            isLoading: true,
+            streams: streams
+        })
+    }
+
+    getEventStreamsError = (error) => {
+        console.log('Failed to get streams object');
+        this.setState({
+            isLoading: false
+        })
+    }
+
+    //Notifications
+    showNotification = (data) => {
+        if(typeof(data) == 'string') {
+            this.setState({
+                displayNotification: true,
+                notificationMessage: data
+            });
+        } else {
+            if(data.type == 'error') {
+                this.setState({
+                    displayNotification: true,
+                    notificationMessage: data.msg,
+                    displayScreenLoader: false
+                });
+            }
+        }
+    }
+    hideNotification = () => {
+        this.setState({
+            displayNotification: false
+        })
+    }
+    //ScreenLoader
+    showScreenLoader = () => {
+        this.setState({
+            displayScreenLoader: true
+        });
+    }
+    hideScreenLoader = () => {
+        this.setState({
+            displayScreenLoader: false
+        })
+    }
+
+}
+
+/**
+ * Receives nav data from routes rest endpoint and decorates the data with internal/external linking information
+ * @param  {object} nav           Nav item from /nav endoingpoint
+ * @param  {string} currentPlugin Current plugin name taken from url path.
+ * @return {array}               Returns list of constructed nav items.
+ */
+function decorateAndTransformNav(nav, currentPlugin) {
+    for ( let k in nav) {
+        nav[k].pluginName = k;
+            if (k != currentPlugin)  {
+                nav[k].routes.map(function(route, i) {
+                    if (API_SERVER) {
+                        route.route = '/' + k + '/index.html?api_server=' + API_SERVER + '&upload_server=' + UPLOAD_SERVER + '#' + route.route;
+                    } else {
+                        route.route = '/' + k + '/#' + route.route;
+                    }
+                    route.isExternal = true;
+                })
+            }
+        }
+        return nav;
+}
+
+function getCurrentPlugin() {
+    var paths = window.location.pathname.split('/');
+    var currentPath = null;
+    if (paths[0] != "") {
+        currentPath = paths[0]
+    } else {
+        currentPath = paths[1];
+    }
+    if (currentPath != null) {
+        return currentPath;
+    } else {
+        console.error('Well, something went horribly wrong with discovering the current plugin name - perhaps you should consider moving this logic to the server?')
+    }
+}
+
+export default Alt.createStore(SkyquakeContainerStore);
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx b/skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx
new file mode 100644 (file)
index 0000000..73a2f02
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import { Link } from 'react-router';
+import Utils from 'utils/utils.js';
+import Crouton from 'react-crouton';
+import 'style/common.scss';
+
+//Temporary, until api server is on same port as webserver
+var rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var UPLOAD_SERVER = rw.getSearchParams(window.location).upload_server;
+
+//
+// Internal classes/functions
+//
+
+class LogoutAppMenuItem extends React.Component {
+    handleLogout() {
+        Utils.clearAuthentication();
+    }
+    render() {
+        return (
+            <div className="app">
+                <h2>
+                    <a onClick={this.handleLogout}>
+                        Logout
+                    </a>
+                </h2>
+            </div>
+        );
+    }
+}
+
+
+//
+// Exported classes and functions
+//
+
+//
+/**
+ * Skyquake Nav Component. Provides navigation functionality between all plugins
+ */
+export default class skyquakeNav extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.validateErrorEvent = 0;
+        this.state.validateErrorMsg = '';
+    }
+    validateError = (msg) => {
+        this.setState({
+            validateErrorEvent: true,
+            validateErrorMsg: msg
+        });
+    }
+    validateReset = () => {
+        this.setState({
+            validateErrorEvent: false
+        });
+    }
+    returnCrouton = () => {
+        return <Crouton
+            id={Date.now()}
+            message={this.state.validateErrorMsg}
+            type={"error"}
+            hidden={!(this.state.validateErrorEvent && this.state.validateErrorMsg)}
+            onDismiss={this.validateReset}
+        />;
+    }
+    render() {
+        let html;
+        html = (
+                <div>
+                {this.returnCrouton()}
+            <nav className="skyquakeNav">
+                {buildNav.call(this, this.props.nav, this.props.currentPlugin)}
+            </nav>
+
+            </div>
+        )
+        return html;
+    }
+}
+skyquakeNav.defaultProps = {
+    nav: {}
+}
+/**
+ * Returns a React Component
+ * @param  {object} link  Information about the nav link
+ * @param  {string} link.route Hash route that the SPA should resolve
+ * @param  {string} link.name Link name to be displayed
+ * @param  {number} index index of current array item
+ * @return {object} component A React LI Component
+ */
+//This should be extended to also make use of internal/external links and determine if the link should refer to an outside plugin or itself.
+export function buildNavListItem (k, link, index) {
+    let html = false;
+    if (link.type == 'external') {
+        this.hasSubNav[k] = true;
+        html = (
+            <li key={index}>
+                {returnLinkItem(link)}
+            </li>
+        );
+    }
+    return html;
+}
+
+/**
+ * Builds a link to a React Router route or a new plugin route.
+ * @param  {object} link Routing information from nav object.
+ * @return {object}  component   returns a react component that links to a new route.
+ */
+export function returnLinkItem(link) {
+    let ref;
+    let route = link.route;
+    if(link.isExternal) {
+        ref = (
+            <a href={route}>{link.label}</a>
+        )
+    } else {
+        if(link.path && link.path.replace(' ', '') != '') {
+            route = link.path;
+        }
+        if(link.query) {
+            let query = {};
+            query[link.query] = '';
+            route = {
+                pathname: route,
+                query: query
+            }
+        }
+        ref = (
+           <Link to={route}>
+                {link.label}
+            </Link>
+        )
+    }
+    return ref;
+}
+
+/**
+ * Constructs nav for each plugin, along with available subnavs
+ * @param  {array} nav List returned from /nav endpoint.
+ * @return {array}     List of constructed nav element for each plugin
+ */
+export function buildNav(nav, currentPlugin) {
+    let navList = [];
+    let navListHTML = [];
+    let secondaryNav = [];
+    let self = this;
+    self.hasSubNav = {};
+    let secondaryNavHTML = (
+        <div className="secondaryNav" key="secondaryNav">
+        {secondaryNav}
+            <LogoutAppMenuItem />
+        </div>
+    )
+    for (let k in nav) {
+        if (nav.hasOwnProperty(k)) {
+            self.hasSubNav[k] = false;
+            let header = null;
+            let navClass = "app";
+            let routes = nav[k].routes;
+            let navItem = {};
+            //Primary plugin title and link to dashboard.
+            let route;
+            let NavList;
+            if (API_SERVER) {
+                route = routes[0].isExternal ? '/' + k + '/index.html?api_server=' + API_SERVER + '' + '&upload_server=' + UPLOAD_SERVER + '' : '';
+            } else {
+                route = routes[0].isExternal ? '/' + k + '/' : '';
+            }
+            let dashboardLink = returnLinkItem({
+                isExternal: routes[0].isExternal,
+                pluginName: nav[k].pluginName,
+                label: nav[k].label || k,
+                route: route
+            });
+            if (nav[k].pluginName == currentPlugin) {
+                navClass += " active";
+            }
+            NavList = nav[k].routes.map(buildNavListItem.bind(self, k));
+            navItem.priority = nav[k].priority;
+            navItem.order = nav[k].order;
+            navItem.html = (
+                <div key={k} className={navClass}>
+                    <h2>{dashboardLink} {self.hasSubNav[k] ? <span className="oi" data-glyph="caret-bottom"></span> : ''}</h2>
+                    <ul className="menu">
+                        {
+                            NavList
+                        }
+                    </ul>
+                </div>
+            );
+            navList.push(navItem)
+        }
+    }
+    //Sorts nav items by order and returns only the markup
+    navListHTML = navList.sort((a,b) => a.order - b.order).map(function(n) {
+        if((n.priority  < 2)){
+            return n.html;
+        } else {
+            secondaryNav.push(n.html);
+        }
+    });
+    navListHTML.push(secondaryNavHTML);
+    return navListHTML;
+}
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeRouter.jsx b/skyquake/framework/widgets/skyquake_container/skyquakeRouter.jsx
new file mode 100644 (file)
index 0000000..fc3231d
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import {
+    Router, Route, hashHistory, IndexRoute
+}
+from 'react-router';
+import SkyquakeContainer from 'widgets/skyquake_container/skyquakeContainer.jsx';
+
+export default function(config, context) {
+    let routes = [];
+    let index = null;
+    let components = null;
+    if (config && config.routes) {
+        routes =  buildRoutes(config.routes)
+        function buildRoutes(routes) {
+            return routes.map(function(route, index) {
+                let routeConfig = {};
+                if (route.route && route.component) {
+                    // ES6 modules need to specify default
+                    let path = route.route;
+                    if(route.path && route.path.replace(' ', '') != '') {
+                        path = route.path
+                    }
+                    routeConfig = {
+                        path: path,
+                        name: route.label,
+                        getComponent: function(location, cb) {
+                            require.ensure([], (require) => {
+                                cb(null, context(route.component).default)
+                            })
+                        }
+                    }
+                    if(route.routes && (route.routes.length > 0)){
+                        routeConfig.childRoutes = buildRoutes(route.routes)
+                    }
+                } else {
+                    console.error('Route not properly configured. Check that both path and component are specified');
+                }
+                return routeConfig;
+            });
+        }
+        routes.push({
+            path: '/login',
+            name: 'Login',
+            component:  require('../login/login.jsx').default
+        });
+        routes.push({
+            path:'*',
+            name: 'Dashboard',
+            getComponent: function(loc, cb) {
+                cb(null, context(config.dashboard).default);
+            }
+        });
+        if (config.dashboard) {
+            // ES6 modules need to specify default
+            index = <IndexRoute component={context(config.dashboard).default} />;
+        } else {
+            index = DefaultDashboard
+        }
+
+        const rootRoute = {
+            component: SkyquakeContainer,
+            path: '/',
+            name: 'Dashboard',
+            indexRoute: {
+                component: (config.dashboard) ? context(config.dashboard).default : DefaultDashboard
+            },
+            childRoutes: routes
+        }
+
+        return((
+            <Router history={hashHistory} routes={rootRoute}>
+            </Router>
+        ))
+    } else {
+        console.error('There are no routes configured in the config.json file');
+    }
+}
+
+//When no default dashboard is specified in the plugin_config.json, use this component.
+class DefaultDashboard extends React.Component {
+    constructor(props) {
+        super(props)
+    }
+    render() {
+        let html;
+        html = <div> This is a default dashboard page component </div>;
+        return html;
+    }
+}
diff --git a/skyquake/framework/widgets/sq-input-range-slider/sq-input-range-slider.jsx b/skyquake/framework/widgets/sq-input-range-slider/sq-input-range-slider.jsx
new file mode 100644 (file)
index 0000000..6a0bb97
--- /dev/null
@@ -0,0 +1,84 @@
+import React from 'react';
+import './sq-input-range-slider.scss';
+
+export default class SqInputRangeSlider extends React.Component {
+    constructor(props){
+        super(props);
+        this.state = {};
+        this.state.position = {
+            left: 50
+        };
+        this.className = "SqRangeInput";
+    }
+
+    updateHandle = (e) => {
+        this.props.onChange(e.target.valueAsNumber);
+    }
+
+    render() {
+        const {vertical, className, min, max, step,  width, disabled, ...props} = this.props;
+        let class_name = this.className;
+        let dataListHTML = null;
+        let dataListOptions = null;
+        let dataListID = null;
+        let inputStyle = {};
+        let inputContainer = {
+        };
+        let style = {
+            width: width + 'px'
+        }
+        if(vertical) {
+            class_name += ' ' + this.className + '--vertical';
+            style.position = 'absolute';
+            style.left = (width * -1 + 32) + 'px';
+            style.width = width + 'px';
+            inputContainer.margin = '0 10px';
+            inputContainer.width = '70px';
+            inputContainer.height = (width + 40) + 'px';
+            inputContainer.background = 'white';
+            inputContainer.border = '1px solid #ccc';
+        } else {
+            class_name += ' ' + this.className + '--horizontal';
+            // style.position = 'absolute';
+            // style.top = 12 + 'px';
+            inputContainer.margin = '10px 0px';
+            inputContainer.height = '70px';
+            inputContainer.width = (width + 40) + 'px';
+            inputContainer.background = 'white';
+            inputContainer.border = '1px solid #ccc';
+        }
+        return (
+                <div className={this.className + '--container'} style={inputContainer}>
+                    <div className={class_name + ' ' + className + (disabled ? ' is-disabled' : '')}>
+                        <input
+                            style={style}
+                            orient= {vertical ? "vertical" : "horizontal"}
+                            type="range"
+                            onChange={this.updateHandle}
+                            ref="range"
+                            max={max}
+                            min={min}
+                            step={step}
+                            disabled={disabled}
+                         />
+                     </div>
+                 </div>
+        )
+    }
+}
+
+SqInputRangeSlider.defaultProps = {
+    //Horizontal vs Vertical Slider
+    vertical: false,
+    //Override classes
+    className: '',
+    min:0,
+    max:100,
+    step: 1,
+    //width/length in px
+    width:100,
+    disabled: false,
+    onChange: function(value) {
+        console.log(value);
+    }
+}
diff --git a/skyquake/framework/widgets/sq-input-range-slider/sq-input-range-slider.scss b/skyquake/framework/widgets/sq-input-range-slider/sq-input-range-slider.scss
new file mode 100644 (file)
index 0000000..b09dd16
--- /dev/null
@@ -0,0 +1,176 @@
+@import '../../style/_colors.scss';
+$slider-background: rgba(19, 82, 150, 0.2);
+$disabled-slider-background: $dark-gray;
+//Generates ticks on bar. Not currently used
+$slider-background-ticks: repeating-linear-gradient(to right, $slider-background, $slider-background 0%, #fff 0%, #fff 1%, $slider-background 1%, $slider-background 25%);
+$thumb-color: rgba(0, 119, 200, 1);
+$disabled-thumb-color: $dark-gray;
+$track-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
+$thumb-height: 50;
+$track-height: 3;
+$input-margin: 20;
+$-webkit-handle-offset: ($track-height - $thumb-height) / 2;
+
+//(thH-ttW) / 2
+
+@mixin thumbStyling {
+    box-shadow: $track-shadow;
+    border: 0px solid #000000;
+    background: $thumb-color;
+    box-shadow: 2px 2px 2px 0px #ccc;
+    height: $thumb-height + px;
+    width: 20px;
+    cursor: pointer;
+}
+@mixin inputTrack {
+    width: 100%;
+    height: $track-height + px;
+    cursor: pointer;
+    animate: 0.2s;
+}
+@mixin infoBase {
+    display: flex;
+    justify-content: space-between;
+}
+@mixin sliderBase {
+    input[type=range] {
+        position:absolute;
+        -webkit-appearance: none;
+        margin: $input-margin + px 0;
+        width: 100%;
+        &:focus {
+            outline: none;
+        }
+        &::-webkit-slider-thumb {
+            @include thumbStyling;
+            -webkit-appearance: none;
+            margin-top: $-webkit-handle-offset + px;
+
+        }
+        &::-moz-range-thumb {
+            @include thumbStyling;
+        }
+        &::-ms-thumb {
+            @include thumbStyling;
+        }
+        &::-webkit-slider-runnable-track {
+            @include inputTrack;
+            box-shadow: $track-shadow;
+            background: $slider-background;
+            border: 0px solid #000101;
+        }
+        &:focus::-webkit-slider-runnable-track {
+            background: $slider-background;
+        }
+        &::-moz-range-track {
+            @include inputTrack;
+            box-shadow: $track-shadow;
+            background: $slider-background;
+            border: 0px solid #000101;
+        }
+        &::-ms-track {
+            @include inputTrack;
+            background: transparent;
+            border-color: transparent;
+            border-width: 39px 0;
+            color: transparent;
+        }
+        &::-ms-fill-lower {
+            background: $slider-background;
+            border: 0px solid #000101;
+            box-shadow: $track-shadow;
+        }
+        &::-ms-fill-upper {
+            background: #ac51b5;
+            border: 0px solid #000101;
+            box-shadow: $track-shadow;
+        }
+        &:focus::-ms-fill-lower {
+            background: $slider-background;
+        }
+        &:focus::-ms-fill-upper {
+            background: $slider-background;
+        }
+    }
+    &-info {
+        @include infoBase
+    }
+}
+.SqRangeInput {
+    &--container {
+        background:white;
+        border: 1px solid #ccc;
+    }
+    &--horizontal {
+        @include sliderBase;
+        position: relative;
+        height:$thumb-height + px;
+        margin: $input-margin / 2 + px;
+    }
+    &--vertical {
+        @include sliderBase;
+        position: relative;
+
+        input[type=range] {
+            -webkit-appearance: none;
+            height: 100%;
+            width: $track-height + px;
+            transform: rotate(270deg);
+            transform-origin: right;
+            &::-webkit-slider-thumb {
+                box-shadow: -2px 2px 2px 0px #ccc;
+            }
+            &::-moz-range-thumb {
+                box-shadow: -2px 2px 2px 0px #ccc;
+            }
+            &::-ms-thumb {
+                box-shadow: -2px 2px 2px 0px #ccc;
+            }
+        }
+        &-info {
+            @include infoBase;
+
+            div {
+                transform: translateY(10px) rotate(90deg);
+            }
+        }
+    }
+    &.is-disabled {
+        input[type=range] {
+            &:disabled {
+                &::-webkit-slider-thumb {
+                    background: $disabled-thumb-color;
+                }
+                &::-moz-range-thumb {
+                    background: $disabled-thumb-color;
+                }
+                &::-ms-thumb {
+                    background: $disabled-thumb-color;
+                }
+                &::-webkit-slider-runnable-track {
+                    background: $disabled-slider-background;
+                }
+                &:focus::-webkit-slider-runnable-track {
+                    background: $disabled-slider-background;
+                }
+                &::-moz-range-track {
+                    background: $disabled-slider-background;
+                }
+                &::-ms-track {
+                }
+                &::-ms-fill-upper {
+                    background: $disabled-slider-background;
+                }
+                &::-ms-fill-lower {
+                    background: $disabled-slider-background;
+                }
+                &:focus::-ms-fill-lower {
+                    background: $disabled-slider-background;
+                }
+                &:focus::-ms-fill-upper {
+                    background: $disabled-slider-background;
+                }
+            }
+        }
+    }
+}
diff --git a/skyquake/framework/widgets/text-area/rw.text-area.js b/skyquake/framework/widgets/text-area/rw.text-area.js
new file mode 100644 (file)
index 0000000..7a036a6
--- /dev/null
@@ -0,0 +1,232 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
+
+
+/**
+ *  A text input component.
+ *  It's props values and a brief description below
+ *
+ *  value: Holds the initial text content of the input.
+ *  label: The text content of the label.
+ *  requiredText: The text content of the "if required" message.
+ *  errorText: The text content of the error message.
+ *  placeholder: The initial placeholder text of the input
+ *  ClassName: Css Classes applied to the element.
+ *  rows: Number of text lines the input element displays at one time.
+ *  cols: Number of characters per line.
+ *  resizable: If the input element is resizable.
+ *  isRequired: A boolean indicating whether or not the input is required.
+ *  isDisabled: A boolean indicating the disabled state of the element.
+ *  isReadONly: A boolean indicating whether or not the input is read only.
+ *  maxLength: The hard limit on how many characters can be in the input.
+ **/
+module.exports = React.createClass({
+  displayName: "TextArea",
+  mixins:[ButtonEventListenerMixin],
+  propTypes: {
+    value:           React.PropTypes.string,
+    label:           React.PropTypes.string,
+    requiredText:    React.PropTypes.string,
+    errorText:       React.PropTypes.string,
+    placeholder:     React.PropTypes.string,
+    className:       React.PropTypes.string,
+    rows:            React.PropTypes.number,
+    cols:            React.PropTypes.number,
+    resizable:       React.PropTypes.bool,
+    isRequired:      React.PropTypes.bool,
+    isDisabled:      React.PropTypes.bool,
+    isReadOnly:      React.PropTypes.bool,
+    maxLength:       React.PropTypes.number,
+    instructions:    React.PropTypes.string
+  },
+
+
+  /**
+   * Sets the default input state.
+   * If there is no description for the variable, assume it's the same as it's props counterpart.
+   *
+   * value: Holds the current text contents of the input element.
+   * isActive: Boolean to indicate if input is active.
+   * isHovered: Boolean to indicate if the input is being hovered over.
+   * isFocused: Boolean to indicate if the input has been focused.
+   * isDisabled: Boolean to indicate if input has been disabled.
+   *
+   * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
+   * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
+   * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
+   * isValid: null, isSuccess: null}}
+   */
+  getInitialState: function() {
+    return {
+      value:            this.props.value || "",
+      label:            this.props.label || "",
+      requiredText:     this.props.requiredText || "Required",
+      errorText:        this.props.errorText || "",
+      instructionsText: this.props.instructions || "",
+      isActive:         false,
+      isHovered:        false,
+      isFocused:        false,
+      isDisabled:       this.props.isDisabled || false,
+      isReadOnly:       this.props.isReadOnly || false,
+      isRequired:       this.props.isRequired || null,
+      isValid:          null,      // Three way bool. Valid: true.   Invalid: false. Not acted on: null.
+      isSuccess:        null     // Three way bool. Success: true. Error: false.   Not acted on: null.
+
+    }
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
+   * "this.props" and "this.state" hold the state and property variables as they were before the update.
+   * returns true if the state have changed. Otherwise returns false.
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
+      this.state.isHovered + this.state.isValid + this.state.isSuccess + this.state.value;
+    var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
+      nextState.isHovered + nextState.isValid + nextState.isSuccess + nextState.value;
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    return true;
+  },
+  /**
+   * Makes sure that when the user types new input, the contents of the input changes accordingly.
+   *
+   * @param event
+   */
+  handleChange: function(event) {
+    this.setState({value:event.target.value});
+  },
+
+  /**
+   * Returns a string reflecting the current state of the input.
+   * If the component state "isDisabled" is true, returns a string "disabled".
+   * If the component state "isReadOnly" is true, returns a string "readonly".
+   * Otherwise returns a string containing a word for each state that has been set to true.
+   * (ie "active focused" if the states active and focused are true, but hovered is false).
+   * @returns {string}
+   */
+  setComponentState: function() {
+    var ret = "";
+    if (this.state.isDisabled) {
+      return "disabled";
+    }
+    if (this.state.isReadOnly) {
+      return "readonly";
+    }
+    if (this.state.isActive) {
+      ret += "active ";
+    }
+    if (this.state.isHovered) {
+      ret += "hovered ";
+    }
+    if (this.state.isFocused) {
+      ret += "focused ";
+    }
+    return ret;
+  },
+
+  /**
+   * Renders the Text Input component.
+   *
+   **/
+  render: function() {
+    var value = this.state.value;
+    var input = null;
+    var textarea_style = {};
+    var textarea_state = this.setComponentState();
+
+    // creates a style for the "resizable" attribute.
+    if (!this.props.resizable) {
+      textarea_style.resize = "none";
+    }
+
+    // The input element.
+    input = React.createElement("textarea", {
+        ref:               "inputRef",
+        "data-state":      textarea_state,
+        value:             value,
+        "style":           textarea_style,
+        placeholder:       this.props.placeholder,
+        rows:              this.props.rows,
+        cols:              this.props.cols,
+        maxLength:         this.props.maxLength,
+        required:          this.state.isRequired,
+        disabled:          this.state.isDisabled,
+        readOnly:          this.state.isReadOnly,
+        onChange:          this.handleChange,
+        onClick:           this.onClick,
+        onMouseUp:         this.onMouseUp,
+        onMouseDown:       this.onMouseDown,
+        onMouseOver:       this.onMouseOver,
+        onMouseEnter:      this.onMouseEnter,
+        onMouseLeave:      this.onMouseLeave,
+        onMouseOut:        this.onMouseOut,
+        onTouchCancel:     this.onTouchCancel,
+        onTouchEnd:        this.onTouchEnd,
+        onTouchMove:       this.onTouchMove,
+        onTouchStart:      this.onTouchStart,
+        onKeyDown:         this.onKeyDown,
+        onKeyPress:        this.onKeyPress,
+        onKeyUp:           this.onKeyUp,
+        onFocus:           this.onFocus,
+        onBlur:            this.onBlur,
+          className:         (this.props.className || "rw-textarea"),
+          tabIndex:          0
+      },
+      null
+    );
+
+    // The "if required" element. It displays a label if the element is required.
+    if(this.props.isRequired == true){
+      var requiredEle = React.createElement("small", {className: "rw-form-requiredLabel"}, this.state.requiredText);
+    }
+
+    // The label element associated with the input.
+    var label = React.createElement("label", null, this.state.label, requiredEle, input);
+
+    // The "error" element.  It pops up as a message if there is an error with the input.
+    if(this.state.errorText != "") {
+      var error = React.createElement("p", {className: "rw-form-errorMsg"}, this.state.errorText);
+    }
+
+    //
+    if(this.state.instructionsText != ""){
+      var instructions = React.createElement("p", {className: "rw-form-instructions"}, this.state.instructionsText)
+    }
+
+    // The parent element for all.
+    var ret = React.createElement("div", {
+      "data-state":      textarea_state,
+      required:          this.state.isRequired,
+      disabled:          this.state.isDisabled,
+      readOnly:          this.state.isReadOnly
+    }, label, error, instructions);
+
+    return ret;
+  }
+});
diff --git a/skyquake/framework/widgets/text-input/check-box/rw.check-box.js b/skyquake/framework/widgets/text-input/check-box/rw.check-box.js
new file mode 100644 (file)
index 0000000..db8f37e
--- /dev/null
@@ -0,0 +1,233 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
+
+
+/**
+ *  A check-box component.
+ *  It's props values and a brief description below
+ *
+ *  label:        The label for the checkbox group.
+ *  checkboxes:   The object that creates each checkbox.  Each object has a property "label" and "checked".
+ *    label:        The label for the individual checkbox.
+ *    checked:      If set to true, the individual checkbox is initialized with a check.
+ *  requiredText: The text content of the "if required" message.
+ *  errorText:    The text content of the error message.
+ *  ClassName:    Css Classes applied to the element.
+ *  size:         The size of the element.
+ *  isRequired:   A boolean indicating whether or not the input is required.
+ *  isDisabled:   A boolean indicating the disabled state of the element.
+ *  isReadOnly:   A boolean indicating whether or not the input is read only.
+ *  instructions: The text content of the instructions
+ **/
+module.exports = React.createClass({
+  displayName: "CheckBox",
+  mixins:[ButtonEventListenerMixin],
+  propTypes: {
+    label:           React.PropTypes.string,
+    checkboxes:        React.PropTypes.arrayOf(
+      React.PropTypes.shape(
+        {
+          label: React.PropTypes.string,
+          checked: React.PropTypes.bool,
+          indeterminate: React.PropTypes.bool
+        }
+      )),
+    requiredText:    React.PropTypes.string,
+    instructionText: React.PropTypes.string,
+    errorText:       React.PropTypes.string,
+    className:       React.PropTypes.string,
+    size:            React.PropTypes.string,
+    isRequired:      React.PropTypes.bool,
+    isDisabled:      React.PropTypes.bool,
+    isReadOnly:      React.PropTypes.bool
+  },
+
+
+  /**
+   * Sets the default input state.
+   * If there is no description for the variable, assume it's the same as it's props counterpart.
+   *
+   * isActive: Boolean to indicate if input is active.
+   * isHovered: Boolean to indicate if the input is being hovered over.
+   * isFocused: Boolean to indicate if the input has been focused.
+   * isDisabled: Boolean to indicate if input has been disabled.
+   *
+   * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
+   * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
+   * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
+   * isValid: null, isSuccess: null}}
+   */
+  getInitialState: function() {
+
+    return {
+      mounted:              false,
+      label:                this.props.label || "",
+      requiredText:         this.props.requiredText || "Required",
+      instructionsText:     this.props.instructions || "",
+      errorText:            this.props.errorText || "",
+      size:                 this.props.size || '',
+      isActive:             false,
+      isHovered:            false,
+      isFocused:            false,
+      isDisabled:           this.props.disabled || false,
+      isReadOnly:           this.props.isReadOnly || false,
+      isRequired:           this.props.isRequired || null,
+      isValid:              null,      // Three way bool. Valid: true.   Invalid: false. Not acted on: null.
+      isSuccess:            null       // Three way bool. Success: true. Error: false.   Not acted on: null.
+    }
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
+   * "this.props" and "this.state" hold the state and property variables as they were before the update.
+   * returns true if the state have changed. Otherwise returns false.
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
+      this.state.isHovered + this.state.isValid + this.state.isSuccess;
+    var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
+      nextState.isHovered + nextState.isValid + nextState.isSuccess;
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    return true;
+  },
+
+  componentDidMount: function() {
+    this.state.mounted = true;
+    this.render();
+  },
+
+  /**
+   * Returns a string reflecting the current state of the input.
+   * If the component state "isDisabled" is true, returns a string "disabled".
+   * If the component state "isReadOnly" is true, returns a string "readonly".
+   * Otherwise returns a string containing a word for each state that has been set to true.
+   * (ie "active focused" if the states active and focused are true, but hovered is false).
+   * @returns {string}
+   */
+  setComponentState: function() {
+
+    var ret = "";
+    if (this.state.isDisabled) {
+      return "disabled";
+    }
+    if (this.state.isReadOnly) {
+      return "readonly";
+    }
+    if (this.state.isActive) {
+      ret += "active ";
+    }
+    if (this.state.isHovered) {
+      ret += "hovered ";
+    }
+    if (this.state.isFocused) {
+      ret += "focused ";
+    }
+    return ret;
+  },
+
+  localOnClick: function(e) {
+    this.onClick(e);
+  },
+
+  /**
+   * Renders the checkbox component.
+   *
+   **/
+  render: function() {
+    var input = [];
+    var checkbox = [];
+    var label = [];
+    var input_style = {};
+    var input_state = this.setComponentState();
+
+    // The group label element
+    label = React.createElement("label", {className: "rw-form__label"}, this.props.label);
+
+    // Creates each individual checkbox element and the label for each.
+    for (var i = 0; i < this.props.checkboxes.length; i++) {
+      checkbox[i] = React.createElement("input",{
+        key:               i,
+        defaultChecked:    this.props.checkboxes[i].checked,
+        //indeterminate: true,
+        type:              "checkbox",
+        readOnly:          this.props.readonly,
+        disabled:          this.props.disabled,
+        onClick:           this.localOnClick,
+        onMouseUp:         this.onMouseUp,
+        onMouseDown:       this.onMouseDown,
+        onMouseOver:       this.onMouseOver,
+        onMouseEnter:      this.onMouseEnter,
+        onMouseLeave:      this.onMouseLeave,
+        onMouseOut:        this.onMouseOut,
+        onTouchCancel:     this.onTouchCancel,
+        onTouchEnd:        this.onTouchEnd,
+        onTouchMove:       this.onTouchMove,
+        onTouchStart:      this.onTouchStart,
+        onKeyDown:         this.onKeyDown,
+        onKeyPress:        this.onKeyPress,
+        onKeyUp:           this.onKeyUp,
+        onFocus:           this.onFocus,
+        onBlur:            this.onBlur
+      }, null);
+      if (this.state.mounted) {
+        this.getDOMNode().children[i + 1].children[0].indeterminate = this.props.checkboxes[i].indeterminate;
+      }
+
+
+      input[i] = React.createElement("label", {className: "rw-form__label-checkBox", key:i, readOnly:this.props.readonly, disabled:this.props.disabled}, checkbox[i], this.props.checkboxes[i].label);
+
+    }
+
+    // The "if required" element. It displays a label if the element is required.
+    if(this.props.isRequired == true){
+      var requiredEle = React.createElement("small", {className: "rw-form__required-label"}, this.state.requiredText);
+    }
+
+    // The "error" element.  It pops up as a message if there is an error with the input.
+    if(this.state.errorText != "") {
+      var error = React.createElement("p", {className: "rw-form__message-error"}, this.state.errorText);
+    }
+
+    // The "instruction" element.
+    if(this.state.instructionsText != ""){
+      var instructions = React.createElement("p", {className: "rw-form-instructions"}, this.state.instructionsText)
+    }
+
+    // The parent element for all.
+    var ret = React.createElement("div", {
+      "data-state":      input_state,
+      required:          this.state.isRequired,
+      disabled:          this.state.isDisabled,
+      readOnly:          this.state.isReadOnly,
+      className:         "rw-form"
+
+    }, requiredEle, label, input, error, instructions);
+
+    return ret;
+  }
+});
diff --git a/skyquake/framework/widgets/text-input/check-box/rw.check-box2.js b/skyquake/framework/widgets/text-input/check-box/rw.check-box2.js
new file mode 100644 (file)
index 0000000..cc8ea87
--- /dev/null
@@ -0,0 +1,228 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
+
+
+/**
+ *  A check-box component.
+ *  It's props values and a brief description below
+ *
+ *  label:        The label for the checkbox group.
+ *  checkboxes:   The object that creates each checkbox.  Each object has a property "label" and "checked".
+ *    label:        The label for the individual checkbox.
+ *    checked:      If set to true, the individual checkbox is initialized with a check.
+ *  requiredText: The text content of the "if required" message.
+ *  errorText:    The text content of the error message.
+ *  ClassName:    Css Classes applied to the element.
+ *  size:         The size of the element.
+ *  isRequired:   A boolean indicating whether or not the input is required.
+ *  isDisabled:   A boolean indicating the disabled state of the element.
+ *  isReadOnly:   A boolean indicating whether or not the input is read only.
+ *  instructions: The text content of the instructions
+ **/
+module.exports = React.createClass({
+  displayName: "CheckBox",
+  mixins:[ButtonEventListenerMixin],
+  propTypes: {
+    children:        React.PropTypes.arrayOf(React.PropTypes.object),
+    label:           React.PropTypes.string,
+    checked:         React.PropTypes.bool,
+    indeterminate:   React.PropTypes.bool,
+    requiredText:    React.PropTypes.string,
+    instructionText: React.PropTypes.string,
+    errorText:       React.PropTypes.string,
+    className:       React.PropTypes.string,
+    size:            React.PropTypes.string,
+    isRequired:      React.PropTypes.bool,
+    isDisabled:      React.PropTypes.bool,
+    isReadOnly:      React.PropTypes.bool
+  },
+
+
+  /**
+   * Sets the default input state.
+   * If there is no description for the variable, assume it's the same as it's props counterpart.
+   *
+   * isActive: Boolean to indicate if input is active.
+   * isHovered: Boolean to indicate if the input is being hovered over.
+   * isFocused: Boolean to indicate if the input has been focused.
+   * isDisabled: Boolean to indicate if input has been disabled.
+   *
+   * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
+   * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
+   * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
+   * isValid: null, isSuccess: null}}
+   */
+  getInitialState: function() {
+
+    return {
+      //mounted:              false,
+      label:                this.props.label || "",
+      requiredText:         this.props.requiredText || "Required",
+      instructionsText:     this.props.instructions || "",
+      errorText:            this.props.errorText || "",
+      size:                 this.props.size || '',
+      isActive:             false,
+      isHovered:            false,
+      isFocused:            false,
+      isDisabled:           this.props.disabled || false,
+      isReadOnly:           this.props.isReadOnly || false,
+      isRequired:           this.props.isRequired || null,
+      isValid:              null,      // Three way bool. Valid: true.   Invalid: false. Not acted on: null.
+      isSuccess:            null       // Three way bool. Success: true. Error: false.   Not acted on: null.
+    }
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
+   * "this.props" and "this.state" hold the state and property variables as they were before the update.
+   * returns true if the state have changed. Otherwise returns false.
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
+      this.state.isHovered + this.state.isValid + this.state.isSuccess;
+    var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
+      nextState.isHovered + nextState.isValid + nextState.isSuccess;
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    return true;
+  },
+
+  componentDidMount: function() {
+    this.state.mounted = true;
+    this.render();
+  },
+
+  /**
+   * Returns a string reflecting the current state of the input.
+   * If the component state "isDisabled" is true, returns a string "disabled".
+   * If the component state "isReadOnly" is true, returns a string "readonly".
+   * Otherwise returns a string containing a word for each state that has been set to true.
+   * (ie "active focused" if the states active and focused are true, but hovered is false).
+   * @returns {string}
+   */
+  setComponentState: function() {
+
+    var ret = "";
+    if (this.state.isDisabled) {
+      return "disabled";
+    }
+    if (this.state.isReadOnly) {
+      return "readonly";
+    }
+    if (this.state.isActive) {
+      ret += "active ";
+    }
+    if (this.state.isHovered) {
+      ret += "hovered ";
+    }
+    if (this.state.isFocused) {
+      ret += "focused ";
+    }
+    return ret;
+  },
+
+  localOnClick: function(e) {
+    this.onClick(e);
+  },
+
+  /**
+   * Renders the checkbox component.
+   *
+   **/
+  render: function() {
+    var input = [];
+    var checkbox = [];
+    var label = [];
+    var input_style = {};
+    var input_state = this.setComponentState();
+
+    // The group label element
+    label = React.createElement("label", {className: "rw-form__label"}, this.props.label);
+
+    // Creates each individual checkbox element and the label for each.
+    for (var i = 0; i < this.props.checkboxes.length; i++) {
+      checkbox[i] = React.createElement("input",{
+        key:               i,
+        defaultChecked:    this.props.checkboxes[i].checked,
+        //indeterminate: true,
+        type:              "checkbox",
+        readOnly:          this.props.readonly,
+        disabled:          this.props.disabled,
+        onClick:           this.localOnClick,
+        onMouseUp:         this.onMouseUp,
+        onMouseDown:       this.onMouseDown,
+        onMouseOver:       this.onMouseOver,
+        onMouseEnter:      this.onMouseEnter,
+        onMouseLeave:      this.onMouseLeave,
+        onMouseOut:        this.onMouseOut,
+        onTouchCancel:     this.onTouchCancel,
+        onTouchEnd:        this.onTouchEnd,
+        onTouchMove:       this.onTouchMove,
+        onTouchStart:      this.onTouchStart,
+        onKeyDown:         this.onKeyDown,
+        onKeyPress:        this.onKeyPress,
+        onKeyUp:           this.onKeyUp,
+        onFocus:           this.onFocus,
+        onBlur:            this.onBlur
+      }, null);
+      if (this.state.mounted) {
+        this.getDOMNode().children[i + 1].children[0].indeterminate = this.props.checkboxes[i].indeterminate;
+      }
+
+
+      input[i] = React.createElement("label", {className: "rw-form__label-checkBox", key:i, readOnly:this.props.readonly, disabled:this.props.disabled}, checkbox[i], this.props.checkboxes[i].label);
+
+    }
+
+    // The "if required" element. It displays a label if the element is required.
+    if(this.props.isRequired == true){
+      var requiredEle = React.createElement("small", {className: "rw-form__required-label"}, this.state.requiredText);
+    }
+
+    // The "error" element.  It pops up as a message if there is an error with the input.
+    if(this.state.errorText != "") {
+      var error = React.createElement("p", {className: "rw-form__message-error"}, this.state.errorText);
+    }
+
+    // The "instruction" element.
+    if(this.state.instructionsText != ""){
+      var instructions = React.createElement("p", {className: "rw-form-instructions"}, this.state.instructionsText)
+    }
+
+    // The parent element for all.
+    var ret = React.createElement("div", {
+      "data-state":      input_state,
+      required:          this.state.isRequired,
+      disabled:          this.state.isDisabled,
+      readOnly:          this.state.isReadOnly,
+      className:         "rw-form"
+
+    }, requiredEle, label, input, error, instructions);
+
+    return ret;
+  }
+});
diff --git a/skyquake/framework/widgets/text-input/rw.text-input.js b/skyquake/framework/widgets/text-input/rw.text-input.js
new file mode 100644 (file)
index 0000000..62e1bcc
--- /dev/null
@@ -0,0 +1,280 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
+var validator = require('validator');
+
+/**
+ *  A text input component.
+ *  It's props values and a brief description below
+ *
+ *  value: Holds the initial text content of the input.
+ *  label: The text content of the label.
+ *  requiredText: The text content of the "if required" message.
+ *  errorText: The text content of the error message.
+ *  placeholder: The initial placeholder text of the input
+ *  ClassName: Css Classes applied to the element.
+ *  size: The size of the element.
+ *  minWidth: Minimum width of the element.
+ *  maxWidth: Maximum width of the element.
+ *  isRequired: A boolean indicating whether or not the input is required.
+ *  isDisabled: A boolean indicating the disabled state of the element.
+ *  isReadOnly: A boolean indicating whether or not the input is read only.
+ *  pattern: A regex putting constraints on what the user input can be.
+ *  maxLength: The hard limit on how many characters can be in the input.
+ **/
+module.exports = React.createClass({
+  displayName: "TextInput",
+  mixins:[ButtonEventListenerMixin],
+  propTypes: {
+    value:           React.PropTypes.string,
+    label:           React.PropTypes.string,
+    requiredText:    React.PropTypes.string,
+    errorText:       React.PropTypes.string,
+    placeholder:     React.PropTypes.string,
+    className:       React.PropTypes.string,
+    size:            React.PropTypes.string,
+    minWidth:        React.PropTypes.number,
+    maxWidth:        React.PropTypes.number,
+    isRequired:      React.PropTypes.bool,
+    isDisabled:      React.PropTypes.bool,
+    isReadOnly:      React.PropTypes.bool,
+    pattern:         React.PropTypes.string,
+    maxLength:       React.PropTypes.number,
+    instructions:    React.PropTypes.string
+  },
+
+
+  /**
+   * Sets the default input state.
+   * If there is no description for the variable, assume it's the same as it's props counterpart.
+   *
+   * value: The current text contents of the input.
+   * isActive: Boolean to indicate if input is active.
+   * isHovered: Boolean to indicate if the input is being hovered over.
+   * isFocused: Boolean to indicate if the input has been focused.
+   * isDisabled: Boolean to indicate if input has been disabled.
+   *
+   * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
+   * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
+   * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
+   * isValid: null, isSuccess: null}}
+   */
+  getInitialState: function() {
+    return {
+      value:                this.props.value || '',
+      label:                this.props.label || "",
+      requiredText:         this.props.requiredText || "Required",
+      instructionsText:     this.props.instructions || "",
+      errorText:            "",
+      size:                this.props.size || '',
+      isActive:            false,
+      isHovered:           false,
+      isFocused:           false,
+      isDisabled:     this.props.isDisabled || false,
+      isReadOnly:     this.props.isReadOnly || false,
+      isRequired:     this.props.isRequired || null,
+      isValid:        null,      // Three way bool. Valid: true.   Invalid: false. Not acted on: null.
+      isSuccess:      null       // Three way bool. Success: true. Error: false.   Not acted on: null.
+    }
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
+   * "this.props" and "this.state" hold the state and property variables as they were before the update.
+   * returns true if the state have changed. Otherwise returns false.
+   * @param nextProps
+   * @param nextState
+   * @returns {boolean}
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+    var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
+      this.state.isHovered + this.state.isValid + this.state.isSuccess + this.state.value;
+    var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
+      nextState.isHovered + nextState.isValid + nextState.isSuccess + nextState.value;
+    if (currentStateString == nextStateString) {
+      return false;
+    }
+    return true;
+  },
+
+  /**
+   * Makes sure that when the user types new input, the contents of the input changes accordingly.
+   *
+   * @param event
+   */
+  handleChange: function(event) {
+    this.setState({value:event.target.value});
+  },
+
+  /**
+   * Makes sure that when the user types new input, the contents of the input changes accordingly.
+   *
+   * @param event
+   */
+  handleValidation: function(event) {
+    if (this.props.isRequired) {
+      if (validator.isNull(event.target.value) || event.target.value == '') {
+        this.setState({
+          errorText: this.props.errorText,
+          isValid: false
+        });
+      } else {
+        this.setState({
+          errorText: '',
+          isValid: true
+        });
+      }
+    }
+    if (this.props.pattern) {
+      if (!validator.matches(event.target.value, this.props.pattern)) {
+        this.setState({
+          errorText: this.props.errorText,
+          isValid: false
+        });
+      } else {
+        this.setState({
+          errorText: '',
+          isValid: true
+        });
+      }
+    }
+
+  },
+
+  /**
+   * Returns a string reflecting the current state of the input.
+   * If the component state "isDisabled" is true, returns a string "disabled".
+   * If the component state "isReadOnly" is true, returns a string "readonly".
+   * Otherwise returns a string containing a word for each state that has been set to true.
+   * (ie "active focused" if the states active and focused are true, but hovered is false).
+   * @returns {string}
+   */
+  setComponentState: function() {
+    var ret = "";
+    if (this.state.isDisabled) {
+      return "disabled";
+    }
+    if (this.state.isReadOnly) {
+      return "readonly";
+    }
+    if (this.state.isActive) {
+      ret += "active ";
+    }
+    if (this.state.isHovered) {
+      ret += "hovered ";
+    }
+    if (this.state.isFocused) {
+      ret += "focused ";
+    }
+    return ret;
+  },
+
+  /**
+   * Renders the Text Input component.
+   *
+   **/
+  render: function() {
+    var value = this.state.value;
+    var input = null;
+    var input_style = {};
+    var input_state = this.setComponentState();
+
+    // The following if statements translates the min/max width from a number into a string.
+    if (this.props.minWidth) {
+      input_style['min-width'] = String(this.props.minWidth) + 'px';
+    }
+    if (this.props.maxWidth) {
+      input_style['max-width'] = String(this.props.maxWidth) + 'px';
+    }
+
+    // The input element.
+    input = React.createElement("input", {
+        ref:               "inputRef",
+        "data-state":      input_state,
+        "data-validate":   this.state.isValid,
+        value:             value,
+        placeholder:       this.props.placeholder,
+        pattern:           this.props.pattern,
+        maxLength:         this.props.maxLength,
+        required:          this.state.isRequired,
+        disabled:          this.state.isDisabled,
+        readOnly:          this.state.isReadOnly,
+        onChange:          this.handleChange,
+        onClick:           this.onClick,
+        onMouseUp:         this.onMouseUp,
+        onMouseDown:       this.onMouseDown,
+        onMouseOver:       this.onMouseOver,
+        onMouseEnter:      this.onMouseEnter,
+        onMouseLeave:      this.onMouseLeave,
+        onMouseOut:        this.onMouseOut,
+        onTouchCancel:     this.onTouchCancel,
+        onTouchEnd:        this.onTouchEnd,
+        onTouchMove:       this.onTouchMove,
+        onTouchStart:      this.onTouchStart,
+        onKeyDown:         this.onKeyDown,
+        onKeyPress:        this.onKeyPress,
+        onKeyUp:           this.handleValidation,
+        onFocus:           this.onFocus,
+        onBlur:            this.handleValidation,
+        className:         (this.props.className || "rw-textinput"),
+        tabIndex:          0
+      },
+      null
+    );
+
+    // The "if required" element. It displays a label if the element is required.
+    if(this.props.isRequired == true){
+      var requiredEle = React.createElement("small", {className: "rw-form__required-label"}, this.state.requiredText);
+    }
+
+    //
+    if(this.state.isValid == false) {
+      var validations  = React.createElement("svg", {className: "rw-form__icon"}, this.state.errorText);
+    }
+    // The label element associated with the input.
+    var label = React.createElement("label", {className: "rw-form__label"}, this.state.label, requiredEle, input, validations);
+
+    // The "error" element.  It pops up as a message if there is an error with the input.
+    if(this.state.errorText != "") {
+      var error = React.createElement("p", {className: "rw-form__message-error"}, this.state.errorText);
+    }
+
+    //
+    if(this.state.instructionsText != ""){
+      var instructions = React.createElement("p", {className: "rw-form__instructions"}, this.state.instructionsText)
+    }
+
+
+
+    // The parent element for all.
+    var ret = React.createElement("div", {
+      "data-state":      input_state,
+      required:          this.state.isRequired,
+      disabled:          this.state.isDisabled,
+      readOnly:          this.state.isReadOnly,
+      "data-validate":   this.state.isValid,
+      className:         "rw-form"
+    }, label, error, instructions);
+
+    return ret;
+  }
+});
diff --git a/skyquake/framework/widgets/topology/topologyL2Graph.jsx b/skyquake/framework/widgets/topology/topologyL2Graph.jsx
new file mode 100644 (file)
index 0000000..fe4360b
--- /dev/null
@@ -0,0 +1,253 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import d3 from 'd3';
+import DashboardCard from '../dashboard_card/dashboard_card.jsx';
+
+export default class TopologyL2Graph extends React.Component {
+    constructor(props) {
+        super(props);
+        this.data = props.data;
+        this.selectedID = 0;
+        this.nodeCount = 0;
+        this.network_coding = {}
+        this.nodeEvent = props.nodeEvent || null;
+    }
+    componentDidMount(){
+        var weight = 400;
+        var handler = this;
+        this.force = d3.layout.force()
+            .size([this.props.width, this.props.height])
+            .charge(-weight)
+            .linkDistance(weight)
+            .on("tick", this.tick.bind(this));
+
+        this.drag = this.force.drag()
+            .on("dragstart", function(d) {
+                handler.dragstart(d, handler);
+            });
+
+    }
+    componentWillUnmount() {
+        d3.select('svg').remove();
+    }
+    componentWillReceiveProps(props) {
+        if(!this.svg) {
+            // NOTE: We may need to revisit how D3 accesses DOM elements
+             this.svg = d3.select(document.querySelector('#topologyL2')).append("svg")
+            .attr("width", this.props.width)
+            .attr("height", this.props.height)
+            .classed("topology", true);
+        }
+
+        if (props.data.links.length > 0) {
+            this.network_coding = this.create_group_coding(props.data.network_ids.sort());
+            this.update(props.data);
+        }
+    }
+
+    create_group_coding(group_ids) {
+        var group_coding = {};
+        group_ids.forEach(function(element, index, array) {
+            group_coding[element] = index+1;
+        });
+        return group_coding;
+    }
+    getNetworkCoding(network_id) {
+        var group = this.network_coding[network_id];
+        if (group != undefined) {
+            return group;
+        } else {
+            return 0;
+        }
+    }
+
+    drawLegend(graph) {
+        // Hack to prevent multiple legends being displayed
+        this.svg.selectAll(".legend").remove();
+
+        var showBox = false;
+        var svg = this.svg;
+        var item_count = (graph.network_ids) ? graph.network_ids.length : 0;
+        var pos = {
+            anchorX: 5,
+            anchorY: 5,
+            height: 40,
+            width: 200,
+            items_y: 35,
+            items_x: 7,
+            item_height: 25
+        };
+        pos.height += item_count * pos.item_height;
+        var legend_translate = "translate("+pos.anchorX+","+pos.anchorY+")";
+
+        var legend = svg.append("g")
+            .attr("class", "legend")
+            .attr("transform", legend_translate);
+
+        var legend_box = (showBox) ? legend.append("rect")
+                .attr("x", 0)
+                .attr("y", 0)
+                .attr("height", pos.height)
+                .attr("width", pos.width)
+                .style("stroke", "black")
+                .style("fill", "none") : null;
+
+        legend.append("text")
+            .attr("x", 5)
+            .attr("y", 15)
+            .text("Network color mapping:");
+
+        legend.selectAll("g").data(graph.network_ids)
+            .enter()
+            .append("g")
+            .each(function(d, i) {
+                var colors = ["green", "orange", "red" ];
+                var g = d3.select(this);
+                var group_number = i+1;
+                g.attr('class', "node-group-" + group_number);
+
+                g.append("circle")
+                    .attr("cx", pos.items_x + 3)
+                    .attr("cy", pos.items_y + i * pos.item_height)
+                    .attr("r", 6);
+
+                g.append("text")
+                    .attr("x", pos.items_x + 25)
+                    .attr("y", pos.items_y + (i * pos.item_height + 4))
+                    .attr("height", 20)
+                    .attr("width", 80)
+                    .text(d);
+            })
+    }
+
+    update(graph) {
+        var svg = this.svg;
+        var handler = this;
+        this.force
+            .nodes(graph.nodes)
+            .links(graph.links)
+            .start();
+
+        this.link = svg.selectAll(".link")
+            .data(graph.links)
+            .enter().append("line")
+                .attr("class", "link");
+
+        this.gnodes = svg.selectAll('g.gnode')
+            .data(graph.nodes)
+            .enter()
+            .append('g')
+            .classed('gnode', true)
+            .attr('data-network', function(d) { return d.network; })
+            .attr('class', function(d) {
+                return d3.select(this).attr('class') + ' node-group-'+ handler.getNetworkCoding(d.network);
+            });
+
+        this.node = this.gnodes.append("circle")
+            .attr("class", "node")
+            .attr("r", this.props.radius)
+            .on("dblclick", function(d) {
+                handler.dblclick(d, handler)
+            })
+            .call(this.drag)
+            .on('click', function(d) {
+                handler.click.call(this, d, handler)
+            });
+        var labels = this.gnodes.append("text")
+            .attr("text-anchor", "middle")
+            .attr("fill", "black")
+            .attr("font-size", "12")
+            .attr("y", "-10")
+            .text(function(d) { return d.name; });
+        this.drawLegend(graph);
+    }
+
+    tick = () => {
+        this.link.attr("x1", function(d) { return d.source.x; })
+               .attr("y1", function(d) { return d.source.y; })
+               .attr("x2", function(d) { return d.target.x; })
+               .attr("y2", function(d) { return d.target.y; });
+
+        this.gnodes.attr("transform", function(d) {
+            return 'translate(' + [d.x, d.y] + ')';
+        });
+
+    }
+
+    click(d, topo) {
+        console.log("TopologyL2Graph.click called");
+        // 'This' is the svg circle element
+        var gnode = d3.select(this.parentNode);
+
+        topo.svg.selectAll("text").transition()
+            .duration(topo.props.nodeText.transitionTime)
+            .attr("font-size", topo.props.nodeText.size)
+            .attr("fill", topo.props.nodeText.color)
+
+        // Set focus node text properties
+        d3.select(this.parentNode).selectAll('text').transition()
+            .duration(topo.props.nodeText.transitionTime)
+            .attr("font-size", topo.props.nodeText.focus.size)
+            .attr("fill", topo.props.nodeText.focus.color);
+
+        // Perform detail view
+        topo.selectedID = d.id;
+        if (topo.nodeEvent) {
+            topo.nodeEvent(d.id);
+        }
+        // set record view as listener
+    }
+
+    dblclick(d, topo) {
+        this.d3.select(this).classed("fixed", d.fixed = false);
+    }
+
+    dragstart(d) {
+        //d3.select(this).classed("fixed", d.fixed = true);
+    }
+
+    render() {
+        return ( <DashboardCard showHeader={true} title="Topology L2 Graph">
+                <div id="topologyL2"></div>
+                </DashboardCard>)
+    }
+}
+
+TopologyL2Graph.defaultProps = {
+    width: 700,
+    height: 500,
+    maxLabel: 150,
+    duration: 500,
+    radius: 6,
+    data: {
+        nodes: [],
+        links: [],
+        network_ids: []
+    },
+    nodeText: {
+        size: 12,
+        color: 'black',
+        focus: {
+            size: 14,
+            color: 'blue'
+        },
+        transitionTime: 250
+    }
+}
diff --git a/skyquake/framework/widgets/topology/topologyTree.jsx b/skyquake/framework/widgets/topology/topologyTree.jsx
new file mode 100644 (file)
index 0000000..5e0d895
--- /dev/null
@@ -0,0 +1,256 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import ReactDOM from 'react-dom';
+import d3 from 'd3';
+import DashboardCard from '../dashboard_card/dashboard_card.jsx';
+import _ from 'lodash';
+import $ from 'jquery';
+import './topologyTree.scss';
+
+export default class TopologyTree extends React.Component {
+    constructor(props) {
+        super(props);
+        this.data = props.data;
+        this.selectedID = 0;
+        this.nodeCount = 0;
+        this.size = this.wrapperSize();
+        this.tree = d3.layout.tree()
+            .size([this.props.treeHeight, this.props.treeWidth]);
+        this.diagonal = d3.svg.diagonal()
+            .projection(function(d) { return [d.y, d.x]; });
+        this.svg = null;
+    }
+    componentWillReceiveProps(props) {
+        let self = this;
+        if(!this.svg) {
+            let zoom = d3.behavior.zoom()
+                .translate([this.props.maxLabel, 0])
+                .scaleExtent([this.props.minScale, this.props.maxScale])
+                .on("zoom", self.zoom);
+            let svg = this.selectParent().append("svg")
+                    .attr("width", this.size.width)
+                    .attr("height", this.size.height)
+                .append("g")
+                    .call(zoom)
+                .append("g")
+                    .attr("transform", "translate(" + this.props.maxLabel + ",0)");
+
+            svg.append("rect")
+                .attr("class", "overlay")
+                .attr("width", this.size.width)
+                .attr("height", this.size.height);
+            // this.svg = d3.select()
+            this.svg = svg;
+            this.props.selectNode(props.data);
+        }
+        if(props.data.hasOwnProperty('type') && !this.props.hasSelected) {
+            this.selectedID = props.data.id;
+            //Commenting out to prevent transmitter push error
+            //this.props.selectNode(props.data);
+        }
+        if(this.svg) {
+          this.update(_.cloneDeep(props.data));
+          // this.selectedID = props.data.id;
+        }
+    }
+
+    wrapperSize() {
+        if (this.props.useDynamicWrapperSize) {
+            try {
+                let wrapper = $(".topologyTreeGraph-body");
+
+                return {
+                    width: wrapper.width(),
+                    height: wrapper.height()
+                }
+            } catch (e) {
+                console.log("ERROR: cannot get width and/or height from element."+
+                    " Using props for width and height. e=", e);
+                return {
+                    width: this.props.width,
+                    height: this.props.height
+                }
+            }
+        } else {
+            return {
+                width: this.props.width,
+                height: this.props.height
+            }
+        }
+    }
+    selectParent() {
+        return d3.select(document.querySelector('#topology'));
+    }
+    computeRadius(d) {
+        // if(d.parameters && d.parameters.vcpu) {
+        //     return this.props.radius + d.parameters.vcpu.total;
+        // } else {
+            return this.props.radius;
+        // }
+    }
+    click = (d) => {
+        this.props.selectNode(d);
+        this.selectedID = d.id;
+        // if (d.children){
+        //     d._children = d.children;
+        //     d.children = null;
+        // }
+        // else{
+        //     d.children = d._children;
+        //     d._children = null;
+        // }
+        // this.update(d);
+    }
+    zoom = () => {
+        this.svg.attr("transform", "translate(" + d3.event.translate +
+            ")scale(" + d3.event.scale + ")");
+    }
+    update = (source) => {
+        // Compute the new tree layout.
+        var svg = this.svg;
+        var nodes = this.tree.nodes(source).reverse();
+        var links = this.tree.links(nodes);
+        var self = this;
+
+        // Normalize for fixed-depth.
+        nodes.forEach(function(d) { d.y = d.depth * self.props.maxLabel; });
+        // Update the nodes…
+        var node = svg.selectAll("g.node")
+            .data(nodes, function(d){
+                return d.id || (d.id = ++self.nodeCount);
+            });
+        // Enter any new nodes at the parent's previous position.
+        var nodeEnter = node.enter()
+            .append("g")
+            .attr("class", "node")
+            .attr("transform", function(d){
+                return "translate(" + source.y0 + "," + source.x0 + ")"; })
+            .on("click", this.click);
+
+        nodeEnter.append("circle")
+            .attr("r", 0)
+            .style("fill", function(d){
+                return d._children ? "lightsteelblue" : "white";
+            });
+
+        nodeEnter.append("text")
+            .attr("x", function(d){
+                var spacing = self.computeRadius(d) + 5;
+                    return d.children || d._children ? -spacing : spacing; })
+            .attr("transform", function(d, i) {
+                    return "translate(0," + ((i%2) ? 15 : -15) + ")"; })
+            .attr("dy", "3")
+            .attr("text-anchor", function(d){
+                    return d.children || d._children ? "end" : "start";
+                })
+            .text(function(d){ return d.name; })
+            .style("fill-opacity", 0);
+
+        // Transition nodes to their new position.
+        var nodeUpdate = node
+            .transition()
+            .duration(this.props.duration)
+            .attr("transform", function(d) {
+                return "translate(" + d.y + "," + d.x + ")"; });
+
+        nodeUpdate.select("circle")
+            .attr("r", function(d){ return self.computeRadius(d); })
+            .style("fill", function(d) {
+                return d.id == self.selectedID ? "green" : "lightsteelblue"; });
+
+        nodeUpdate.select("text")
+            .style("fill-opacity", 1)
+            .style("font-weight", function(d) {
+                return d.id == self.selectedID ? "900" : "inherit";
+            })
+            .attr("transform", function(d, i) {
+                return "translate(0," + ((i%2) ? 15 : -15) + ")" +
+                    (d.id == self.selectedID ? "scale(1.125)" : "scale(1)");
+            });
+
+        // Transition exiting nodes to the parent's new position.
+        var nodeExit = node.exit()
+            .transition()
+            .duration(this.props.duration)
+            .attr("transform", function(d) {
+                return "translate(" + source.y + "," + source.x + ")"; })
+            .remove();
+
+        nodeExit.select("circle").attr("r", 0);
+        nodeExit.select("text").style("fill-opacity", 0);
+
+        // Update the links…
+        var link = svg.selectAll("path.link")
+            .data(links, function(d){ return d.target.id; });
+
+        // Enter any new links at the parent's previous position.
+        link.enter().insert("path", "g")
+            .attr("class", "link")
+            .attr("d", function(d){
+                var o = {x: source.x0, y: source.y0};
+                return self.diagonal({source: o, target: o});
+            });
+
+        // Transition links to their new position.
+        link
+            .transition()
+            .duration(this.props.duration)
+            .attr("d", self.diagonal);
+
+        // Transition exiting nodes to the parent's new position.
+        link.exit()
+            .transition()
+            .duration(this.props.duration)
+            .attr("d", function(d){
+                var o = {x: source.x, y: source.y};
+                return self.diagonal({source: o, target: o});
+            })
+            .remove();
+
+        // Stash the old positions for transition.
+        nodes.forEach(function(d){
+            d.x0 = d.x;
+            d.y0 = d.y;
+        });
+    }
+    render() {
+        let html = (
+            <DashboardCard  className="topologyTreeGraph" showHeader={true} title="Topology Tree"
+                headerExtras={this.props.headerExtras} >
+                <div id="topology"></div>
+            </DashboardCard>
+        );
+        return html;
+    }
+}
+
+TopologyTree.defaultProps = {
+    treeWidth: 800,
+    treeHeight: 500,
+    width: 800,
+    height: 800,
+    minScale: 0.5,
+    maxScale: 2,
+    maxLabel: 150,
+    duration: 500,
+    radius: 5,
+    useDynamicWrapperSize: false,
+    data: {}
+}
diff --git a/skyquake/framework/widgets/topology/topologyTree.scss b/skyquake/framework/widgets/topology/topologyTree.scss
new file mode 100644 (file)
index 0000000..f975f8e
--- /dev/null
@@ -0,0 +1,8 @@
+.topologyTreeGraph {
+    min-width:800px;
+
+    .overlay {
+      fill:none;
+      pointer-events: all;
+    }
+}
diff --git a/skyquake/framework/widgets/transmit-receive/transmit-receive.js b/skyquake/framework/widgets/transmit-receive/transmit-receive.js
new file mode 100644 (file)
index 0000000..ff03af1
--- /dev/null
@@ -0,0 +1,104 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require("react");
+var MIXINS = require("../mixins/ButtonEventListener.js");
+
+
+
+
+/**
+ *  Transmit and Receive Component
+ *  It's props values and a brief description below
+ *
+ *
+ *
+ **/
+module.exports = React.createClass({
+  displayName: 'TransmitReceive',
+  mixins:MIXINS,
+  propTypes: {
+    component_data:React.PropTypes.shape({
+      incoming:React.PropTypes.shape({
+        bytes:React.PropTypes.number,
+        packets:React.PropTypes.number,
+        label:React.PropTypes.string, 
+        "byte-rate":React.PropTypes.number,
+        "packet-rate":React.PropTypes.number
+      }),
+      outgoing:React.PropTypes.shape({
+        bytes:React.PropTypes.number,
+        packets:React.PropTypes.number,
+        label:React.PropTypes.string, 
+        "byte-rate":React.PropTypes.number,
+        "packet-rate":React.PropTypes.number
+      })
+    })
+  },
+
+  /**
+   * Defines default state.
+   *
+
+   */
+  getInitialState: function() {
+  },
+
+
+  /**
+   *  Called when props are changed.  Syncs props with state.
+   */
+  componentWillReceiveProps: function(nextProps) {
+
+  },
+
+  /**
+   * Calls the render on the gauge object once the component first mounts
+   */
+  componentDidMount: function() {
+    this.canvasRender(this.state);
+  },
+
+  /**
+   * If any of the state variables have changed, the component should update.
+   * Note, this is where the render step occures for the gauge object.
+   */
+  shouldComponentUpdate: function(nextProps, nextState) {
+
+  },
+
+  /**
+   * Renders the Gauge Component
+   * Returns the canvas element the gauge will be housed in.
+   * @returns {*}
+   */
+  render: function() {
+    var gaugeDOM = React.createElement("div", null,
+      React.createElement("canvas",
+        {className: "rwgauge", style:
+          {width:'100%',height:'100%','maxWidth':this.state.width + 'px','maxHeight':'240px'},
+          ref:'gaugeDOM'
+        }
+      )
+    )
+
+
+
+    return gaugeDOM;
+  }
+});
diff --git a/skyquake/framework/widgets/transmit-receive/transmit-receive.jsx b/skyquake/framework/widgets/transmit-receive/transmit-receive.jsx
new file mode 100644 (file)
index 0000000..f8ea287
--- /dev/null
@@ -0,0 +1,85 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './transmit-receive.scss'
+class TransmitReceive extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+  // getDigits(number) {
+  //   return Math.log(number) * Math.LOG10E + 1 | 0;
+  // }
+  getUnits(number) {
+    if (number < Math.pow(10,3)) {
+      return [number, ''];
+    } else if (number < Math.pow(10,6)) {
+      return [(number / Math.pow(10,3)), 'K'];
+    } else if (number < Math.pow(10,9)) {
+      return [(number / Math.pow(10,6)), 'M'];
+    } else if (number < Math.pow(10,12)) {
+      return [(number / Math.pow(10,9)), 'G'];
+    } else if (number < Math.pow(10,15)) {
+      return [(number / Math.pow(10,12)), 'T'];
+    } else if (number < Math.pow(10,18)) {
+      return [(number / Math.pow(10,15)), 'P'];
+    } else if (number < Math.pow(10,21)) {
+      return [(number / Math.pow(10,18)), 'E'];
+    } else if (number < Math.pow(10,24)) {
+      return [(number / Math.pow(10,21)), 'Z'];
+    } else if (number < Math.pow(10,27)) {
+      return [(number / Math.pow(10,24)), 'Z'];
+    } else {
+      return [(number / Math.pow(10,27)), 'Y'];
+    }
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    if (JSON.stringify(this.props.data) === JSON.stringify(nextProps.data)) {
+      return false;
+    }
+    return true;
+  }
+
+  render() {
+    let html;
+
+    html = (
+            <div className="transmit-receive-container">
+              <div className="transmit-container">
+                <div className="label">{this.props.data.outgoing.label}</div>
+                <div className="measure">{this.getUnits(this.props.data.outgoing.bytes)[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.outgoing.bytes)[1]}B</div>
+                <div className="measure">{this.getUnits(this.props.data.outgoing.packets)[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.outgoing.packets)[1]}P</div>
+                <div className="measure">{this.getUnits(this.props.data.outgoing['byte-rate'])[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.outgoing['byte-rate'])[1]}BPS</div>
+                <div className="measure">{this.getUnits(this.props.data.outgoing['packet-rate'])[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.outgoing['packet-rate'])[1]}PPS</div>
+              </div>
+              <div className="receive-container">
+                <div className="label">{this.props.data.incoming.label}</div>
+                <div className="measure">{this.getUnits(this.props.data.incoming.bytes)[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.incoming.bytes)[1]}B</div>
+                <div className="measure">{this.getUnits(this.props.data.incoming.packets)[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.incoming.packets)[1]}P</div>
+                <div className="measure">{this.getUnits(this.props.data.incoming['byte-rate'])[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.incoming['byte-rate'])[1]}BPS</div>
+                <div className="measure">{this.getUnits(this.props.data.incoming['packet-rate'])[0].toFixed(1)}</div><div className="units">{this.getUnits(this.props.data.incoming['packet-rate'])[1]}PPS</div>
+              </div>
+            </div>
+            );
+    return html;
+  }
+}
+
+
+export default TransmitReceive;
diff --git a/skyquake/framework/widgets/transmit-receive/transmit-receive.scss b/skyquake/framework/widgets/transmit-receive/transmit-receive.scss
new file mode 100644 (file)
index 0000000..c1336a6
--- /dev/null
@@ -0,0 +1,49 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.transmit-receive-container {
+      flex: 1 0;
+      display: flex;
+      flex-direction: row;
+      justify-content: space-around;
+      font-weight:bold;
+      text-align:center;
+      margin: 10px 0px;
+      padding: 0px 10px 0px 10px;
+      background-color:rgb(230,230,230);
+
+      .transmit-container, .receive-container {
+        padding:10px;
+        background-color:rgb(219,219,219);
+      }
+      .transmit-container {
+        margin-right:3px;
+      }
+      .units {
+        font-size:.5rem;
+        margin-bottom:5px;
+
+      }
+      .measure {
+        font-size:1.2rem;
+      }
+      .label {
+        font-size:.8rem;
+        margin-bottom:10px;
+      }
+ }
diff --git a/skyquake/framework/widgets/uptime/uptime.jsx b/skyquake/framework/widgets/uptime/uptime.jsx
new file mode 100644 (file)
index 0000000..39b5faf
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+function debugDump(funcName, state, props) {
+      console.log("UpTime." + funcName + ": called");
+      console.log(" -> props = ", props);
+      console.log(" -> state = ", state);
+    }
+
+/**
+ * Uptime Compoeent
+ * Accepts two properties:
+ * initialtime {number} number of milliseconds.
+ * run {boolean} determines whether the uptime ticker should run
+ */
+export default class UpTime extends React.Component {
+
+    constructor(props) {
+      super(props);
+      if (props.debugMode) {
+        console.log("UpTime.constructor called");
+      }
+      let initialTime = Math.floor(props.initialTime);
+      this.state = {
+        run: props.run,
+        initialTime: initialTime,
+        time: this.handleConvert(this.calculateDuration({
+          intialTime: initialTime
+        })),
+        noisySeconds: props.noisySeconds,
+        debugMode: props.debugMode
+      }
+      this.tick;
+      this.handleConvert = this.handleConvert.bind(this);
+      this.updateTime = this.updateTime.bind(this);
+      if (props.debugMode) {
+        debugDump("constructor", this.state, props);
+      }
+    }
+
+    componentWillReceiveProps(nextProps) {
+      if (this.state.debugMode) {
+        debugDump("componentWillReceiveProps", this.state, nextProps);
+      }
+      let initialTime = Math.floor(nextProps.initialTime);
+      if (initialTime > this.state.initialTime) {
+        initialTime = this.state.initialTime;
+      }
+      this.state = {
+        initialTime: initialTime,
+        time: this.handleConvert(this.calculateDuration({
+          intialTime: initialTime
+        }))
+      }
+    }
+
+    calculateDuration(args={}) {
+      let initialTime = args.initialTime;
+      if (!initialTime) {
+        initialTime =  this.state && this.state.initialTime
+          ? this.state.initialTime
+          : 0;
+      }
+      let timeNow = args.timeNow ? args.timeNow : Date.now();
+      if (initialTime) {
+        return Math.floor((timeNow/ 1000)) - initialTime;
+      } else {
+        return 0;
+      }
+    }
+
+    handleConvert(input) {
+      var ret = {
+        days: 0,
+        hours: 0,
+        minutes: 0,
+        seconds: 0
+      };
+      if (input == "inactive" || typeof(input) === 'undefined') {
+        ret.seconds = -1;
+      } else if (input !== "" && input != "Expired") {
+        input = Math.floor(input);
+        ret.seconds = input % 60;
+        ret.minutes = Math.floor(input / 60) % 60;
+        ret.hours = Math.floor(input / 3600) % 24;
+        ret.days = Math.floor(input / 86400);
+      }
+      return ret;
+    }
+
+    toString() {
+        var self = this;
+        var ret = "";
+        var unitsRendered = [];
+
+        if (self.state.time.days > 0) {
+          ret += self.state.time.days + "d:";
+          unitsRendered.push("d");
+        }
+
+        if (self.state.time.hours > 0 || unitsRendered.length > 0) {
+          ret += self.state.time.hours + "h:";
+          unitsRendered.push("h");
+        }
+
+        if (self.state.time.minutes > 0 || unitsRendered.length > 0) {
+          ret += self.state.time.minutes + "m:";
+          unitsRendered.push("m");
+        }
+
+        if (self.props.noisySeconds || unitsRendered.length == 0
+            || unitsRendered.indexOf('m') == 0)
+        {
+            // console.log(" -> toString adding seconds: ", self.state.time.seconds);
+            ret += self.state.time.seconds + "s";
+        }
+
+        if (ret.endsWith(':')) {
+          ret = ret.slice(0,-1);
+        }
+        if (ret.length > 0) {
+          return ret;
+        } else {
+          return "--";
+        }
+    }
+
+    updateTime() {
+      if (this.state.initialTime) {
+        this.setState({
+          time: this.handleConvert(this.calculateDuration())
+        });
+      }
+    }
+
+    componentDidMount() {
+      var self = this;
+      if (self.state.run) {
+        clearInterval(self.tick);
+        self.tick = setInterval(self.updateTime, 250);
+      }
+    }
+
+    componentWillUnmount() {
+      clearInterval(this.tick);
+    }
+
+    render() {
+      return (<span>{this.toString()}</span>);
+    }
+}
+UpTime.defaultProps = {
+  noisySeconds: false,
+  caller: '',
+  systemId: '' // System identifyer for uptime (e.g.: VM, NS, or process)
+}
+
diff --git a/skyquake/installed_plugins.txt b/skyquake/installed_plugins.txt
new file mode 100644 (file)
index 0000000..5c7c9f2
--- /dev/null
@@ -0,0 +1,5 @@
+about
+composer
+debug
+launchpad
+login
diff --git a/skyquake/package.json b/skyquake/package.json
new file mode 100644 (file)
index 0000000..1ea4db2
--- /dev/null
@@ -0,0 +1,68 @@
+{
+  "name": "skyquake",
+  "version": "0.0.1",
+  "description": "RIFT.io UI Framework",
+  "main": "skyquake.js",
+  "scripts": {
+    "test": "./node_modules/.bin/intern-client config=tests/intern",
+    "storybook": "start-storybook -p 9001"
+  },
+  "author": "Kiran Kashalkar (kiran.kashalkar@riftio.com)",
+  "license": "Apache 2.0",
+  "dependencies": {
+    "alt": "^0.18.3",
+    "alt-container": "^1.0.2",
+    "bluebird": "^3.4.1",
+    "body-parser": "^1.14.2",
+    "cors": "^2.7.1",
+    "d3": "^3.5.16",
+    "ejs": "^2.3.4",
+    "express": "^4.13.3",
+    "express-session": "^1.13.0",
+    "history": "^1.17.0",
+    "jquery": "^2.2.1",
+    "json2yaml": "^1.1.0",
+    "lodash": "^4.0.0",
+    "minimist": "^1.2.0",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.3.0",
+    "promise": "^7.1.1",
+    "react": "^0.14.6",
+    "react-addons-pure-render-mixin": "^0.14.7",
+    "react-breadcrumbs": "^1.3.9",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.6",
+    "react-router": "^2.0.1",
+    "react-slick": "^0.11.1",
+    "react-treeview": "^0.4.5",
+    "request": "^2.67.0",
+    "request-promise": "^3.0.0",
+    "require-json": "0.0.1",
+    "require-reload": "^0.2.2",
+    "sockjs": "^0.3.17",
+    "sockjs-client": "^1.1.1",
+    "underscore": "^1.8.3",
+    "url": "^0.11.0",
+    "webpack": "^1.12.11",
+    "websocket-multiplex": "^0.1.0",
+    "ws": "^1.0.1"
+  },
+  "devDependencies": {
+    "babel-core": "^6.6.4",
+    "babel-loader": "^6.2.4",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.5.0",
+    "css-loader": "^0.23.1",
+    "file-loader": "^0.8.5",
+    "intern": "^3.0.6",
+    "loaders.css": "^0.1.2",
+    "node-sass": "^3.4.2",
+    "react-addons-css-transition-group": "^0.14.7",
+    "react-style-guide": "^1.1.8",
+    "react-to-jsx": "^1.3.2",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "webpack-hot-middleware": "^2.10.0"
+  }
+}
diff --git a/skyquake/plugins/CMakeLists.txt b/skyquake/plugins/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ae9bdec
--- /dev/null
@@ -0,0 +1,55 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+
+##
+# Include the subdirs
+##
+set(
+  subdirs
+    about
+    composer
+    debug
+#    goodbyworld
+#    helloworld
+    launchpad
+    accounts
+    logging
+  )
+rift_add_subdirs(
+  SUBDIR_LIST
+    ${subdirs}
+  )
diff --git a/skyquake/plugins/about/CMakeLists.txt b/skyquake/plugins/about/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bc69175
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  about
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/about/about-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/about/about-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/about/api/about.js b/skyquake/plugins/about/api/about.js
new file mode 100644 (file)
index 0000000..d77a43a
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var request = require('request');
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var constants = require('../../../framework/core/api_utils/constants.js');
+var _ = require('underscore');
+var APIVersion = '/v1';
+var About = {};
+
+About.getVCS = function(req) {
+  var api_server = req.query["api_server"];
+
+  return new Promise(function(resolve, reject) {
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+    request({
+        url: utils.confdPort(api_server) + APIVersion + '/api/operational/vcs/info?deep',
+        type: 'GET',
+        headers: requestHeaders,
+        forever: constants.FOREVER_ON,
+        rejectUnauthorized: false,
+      },
+      function(error, response, body) {
+        var data;
+        console.log(error);
+        if (utils.validateResponse('About/vcs.get', error, response, body, resolve, reject)) {
+          try {
+            data = JSON.parse(response.body)["rw-base:info"]
+          } catch (e) {
+            return reject({});
+          }
+
+          return resolve(data);
+        }
+      });
+  });
+}
+
+About.getVersion = function(req) {
+  var api_server = req.query["api_server"];
+
+  return new Promise(function(resolve, reject) {
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+    request({
+        url: utils.confdPort(api_server) + APIVersion + '/api/operational/version?deep',
+        type: 'GET',
+        headers: requestHeaders,
+        forever: constants.FOREVER_ON,
+        rejectUnauthorized: false,
+      },
+      function(error, response, body) {
+        var data;
+        console.log(error);
+        if (utils.validateResponse('About/version.get', error, response, body, resolve, reject)) {
+          try {
+            data = JSON.parse(response.body)['rw-base:version']
+          } catch (e) {
+            return reject({});
+          }
+
+          return resolve(data);
+        }
+      });
+  });
+}
+
+About.get = function(req) {
+
+  var api_server = req.query["api_server"];
+
+  return new Promise(function(resolve, reject) {
+    Promise.all([
+        About.getVCS(req),
+        About.getVersion(req)
+      ])
+      .then(function(results) {
+        var AboutObject = {};
+        AboutObject.vcs = results[0];
+        AboutObject.version = results[1];
+        resolve(AboutObject);
+      }, function(error) {
+        console.log('error getting vcs data', error);
+        reject(error)
+      });
+  });
+};
+
+About.uptime = function(req) {
+  var api_server = req.query["api_server"];
+  return new Promise(function(resolve, reject) {
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+    request({
+        url: utils.confdPort(api_server) + APIVersion + '/api/operational/uptime/uptime',
+        type: 'GET',
+        headers: requestHeaders,
+        forever: constants.FOREVER_ON,
+        rejectUnauthorized: false
+      },
+      function(error, response, body) {
+        if (utils.validateResponse('About.uptime', error, response, body, resolve, reject)) {
+          try {
+            data = JSON.parse(response.body);
+          } catch (e) {
+            return reject({});
+          }
+          return resolve(data)
+
+        }
+      })
+  })
+}
+module.exports = About;
diff --git a/skyquake/plugins/about/config.json b/skyquake/plugins/about/config.json
new file mode 100644 (file)
index 0000000..1100c71
--- /dev/null
@@ -0,0 +1,14 @@
+{
+    "root": "public",
+    "name": "About",
+    "dashboard": "./about.jsx",
+    "order": 99,
+    "priority":2,
+     "routes" : [{
+        "label": "Dashboard",
+        "route": "/",
+        "component": "./about.jsx",
+        "path": "",
+        "type": "internal"
+    }]
+}
diff --git a/skyquake/plugins/about/package.json b/skyquake/plugins/about/package.json
new file mode 100644 (file)
index 0000000..cb92cf9
--- /dev/null
@@ -0,0 +1,53 @@
+{
+  "name": "about",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "RIFT.io",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "alt": "^0.18.3",
+    "bluebird": "^3.4.1",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "jquery": "^2.2.1",
+    "json-loader": "^0.5.4",
+    "normalizr": "^2.1.0",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.4.1",
+    "react": "^0.14.8",
+    "react-breadcrumbs": "^1.3.9",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.6",
+    "react-router": "^2.0.1",
+    "react-slick": "^0.11.1",
+    "react-tabs": "^0.5.3",
+    "react-treeview": "^0.4.2",
+    "request-promise": "^3.0.0",
+    "underscore": "^1.8.3"
+  },
+  "devDependencies": {
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-polyfill": "^6.9.1",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "cors": "^2.7.1",
+    "css-loader": "^0.23.1",
+    "file-loader": "^0.8.5",
+    "html-webpack-plugin": "^2.9.0",
+    "http-proxy": "^1.12.0",
+    "loaders.css": "^0.1.2",
+    "node-sass": "^3.4.2",
+    "react-addons-css-transition-group": "^0.14.7",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "webpack": "^1.3.0",
+    "webpack-dev-server": "^1.10.1"
+  }
+}
diff --git a/skyquake/plugins/about/routes.js b/skyquake/plugins/about/routes.js
new file mode 100644 (file)
index 0000000..9502116
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var router = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js')
+var About = require('./api/about.js');
+router.get('/api/', cors(), function(req, res) {
+    About.get(req).then(function(data) {
+        res.send(data);
+    }, function(error) {
+        utils.sendErrorResponse(error, res);
+    });
+});
+router.get('/api/create-time', cors(), function(req, res) {
+    About.uptime(req).then(function(data) {
+        res.send(data);
+    }, function(error) {
+        utils.sendErrorResponse(error, res);
+    });
+});
+
+module.exports = router;
diff --git a/skyquake/plugins/about/scripts/build.sh b/skyquake/plugins/about/scripts/build.sh
new file mode 100755 (executable)
index 0000000..03db9bd
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=about
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/about/scripts/install.sh b/skyquake/plugins/about/scripts/install.sh
new file mode 100755 (executable)
index 0000000..da5936d
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=about
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
+
diff --git a/skyquake/plugins/about/server.js b/skyquake/plugins/about/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/about/src/about.jsx b/skyquake/plugins/about/src/about.jsx
new file mode 100644 (file)
index 0000000..6458764
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './about.scss';
+import UpTime from 'widgets/uptime/uptime.jsx';
+import AppHeader from 'widgets/header/header.jsx';
+var aboutActions = require('./aboutActions.js');
+var aboutStore = require('./aboutStore.js');
+//var MissionControlStore = require('./missionControlStore.js');
+class About extends React.Component {
+  constructor(props) {
+    super(props)
+    var self = this;
+    this.state = aboutStore.getState();
+    aboutStore.listen(this.listenerUpdate);
+    aboutStore.get();
+    aboutStore.createTime();
+  }
+  componentWillUnmount() {
+    aboutStore.listen(this.listenerUpdate);
+  }
+  listenerUpdate = (data) => {
+      if (data.aboutList) {
+        this.setState({
+          list:data.aboutList
+        })
+      }
+      if (data.createTime) {
+        // Required cause backend won't provide a create-time
+        let createTime = (data.createTime) ? Math.floor((new Date() / 1000)) - parseInt(data.createTime) : null;
+        this.setState({
+          createTime: createTime
+        })
+      }
+      if (data.descriptorCount) {
+        this.setState({
+          descriptorCount: data.descriptorCount
+        });
+      }
+    }
+  render() {
+    let self = this;
+    let refPage = window.sessionStorage.getItem('refPage') || '{}';
+    refPage = JSON.parse(refPage);
+
+    let mgmtDomainName = window.location.hash.split('/')[2];
+    // If in the mission control, create an uptime table;
+    var uptime = this.state.createTime && this.state.createTime;
+
+    var uptimeComponent = (
+      <div className="table-container">
+                  <h2> Uptime Info </h2>
+                  <table>
+                    <thead>
+                      <tr>
+                        <th>
+                          Uptime
+                        </th>
+                        <th>
+                          <UpTime initialTime={uptime} run={true} />
+                        </th>
+                      </tr>
+                    </thead>
+                  </table>
+                </div>
+    );
+
+    var vcs_info = [];
+
+    for (let i = 0; this.state && this.state.list && i < this.state.list.vcs.components.component_info.length; i++) {
+      var node = this.state.list.vcs.components.component_info[i];
+      vcs_info.push(
+          <tr key={i}>
+            <td>
+              {node.component_name}
+            </td>
+            <td>
+              {node.component_type}
+            </td>
+            <td>
+              {node.state}
+            </td>
+          </tr>
+
+        )
+    }
+
+    if (this.state != null) {
+      var html = (
+              <div className="table-container-wrapper">
+                {uptimeComponent}
+                <div className="table-container">
+                  <h2> Version Info </h2>
+                  <table>
+                    <thead>
+                      <tr>
+                        <th>
+                          Build SHA
+                        </th>
+                        <th>
+                          Version
+                        </th>
+                        <th>
+                          Build Date
+                        </th>
+                      </tr>
+                    </thead>
+                    <tbody>
+                      <tr>
+                        <td>
+                          {this.state.list ? this.state.list.version.build_sha : null}
+                        </td>
+                        <td>
+                          {this.state.list ? this.state.list.version.version : null}
+                        </td>
+                        <td>
+                          {this.state.list ? this.state.list.version.build_date : null}
+                        </td>
+                      </tr>
+                    </tbody>
+                  </table>
+                </div>
+                <div className="table-container">
+                  <h2> Component Info </h2>
+                  <table>
+                    <thead>
+                      <tr>
+                        <th>
+                          Component Name
+                        </th>
+                        <th>
+                          Component Type
+                        </th>
+                        <th>
+                          State
+                        </th>
+                      </tr>
+                    </thead>
+                    <tbody>
+                      {vcs_info}
+                    </tbody>
+                  </table>
+                </div>
+              </div>
+              );
+    } else {
+      html = ''
+    }
+    return (
+            <div className="about-container">
+              {html}
+            </div>
+            )
+  }
+}
+export default About;
diff --git a/skyquake/plugins/about/src/about.scss b/skyquake/plugins/about/src/about.scss
new file mode 100644 (file)
index 0000000..06b9bbd
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.about-container {
+  height: 100%;
+  display: flex;
+  flex-direction: row;
+  align-items: stretch;
+  align-content: stretch;
+  width: 100%;
+  flex: 1 1 100%;
+  overflow-y: auto;
+
+  .table-container-wrapper {
+    flex: 1;
+    .table-container {
+      padding:40px 20px 10px 20px;
+      font-family: 'roboto-thin', Helvetica, Arial, sans-serif;
+    }
+  }
+
+  table {
+    border-collapse: separate;
+    border-spacing: 0.0625rem solid;
+    width: 100%;
+  
+    thead  {
+      th {
+        background-color: #e5e5e5;
+        border-right: 1px solid #dadada;
+        padding: 1.125rem 1.125rem;
+        text-align:left;
+        font-size: .8rem;
+        font-weight: bold;
+        text-transform: uppercase;
+      }
+      td:last-child {
+        border: 0;
+      }
+    }
+    tbody {
+      td {
+        border-bottom: 1px solid #e5e5e5;
+        padding: .75rem 0rem .75rem 1.125rem;
+        text-align: left;
+        width: 40%;
+        font-size: .8rem;
+      }
+      tr:nth-child(even) td {
+        background-color: #e5e5e5;
+      }
+    }
+  }
+  h2 {
+    background-color: #ffffff;
+    margin-bottom: 0.125rem;
+    font-size: 0.9rem;
+    padding: 1.125rem;
+    font-weight: bold;
+    text-transform: uppercase;
+  }
+}
\ No newline at end of file
diff --git a/skyquake/plugins/about/src/aboutActions.js b/skyquake/plugins/about/src/aboutActions.js
new file mode 100644 (file)
index 0000000..848aa07
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+var aboutActions = Alt.generateActions(
+                                                'getAboutSuccess',
+                                                'getAboutLoading',
+                                                'getAboutFail',
+                                                'getCreateTimeSuccess',
+                                                'getCreateTimeLoading',
+                                                'getCreateTimeFail'
+                                                );
+
+module.exports = aboutActions;
diff --git a/skyquake/plugins/about/src/aboutSource.js b/skyquake/plugins/about/src/aboutSource.js
new file mode 100644 (file)
index 0000000..cfdf67e
--- /dev/null
@@ -0,0 +1,80 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var aboutActions = require('./aboutActions.js');
+var Utils = require('utils/utils.js');
+import $ from 'jquery';
+var aboutSource = {
+  get: function() {
+    return {
+      remote: function(state) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'api/?api_server=' + API_SERVER,
+            type:'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            contentType: "application/json",
+            success: function(data) {
+              resolve(data);
+            },
+            error: function(error) {
+              console.log("There was an error getting the crash details: ", error);
+              reject(error);
+            }
+          }).fail(function(xhr){
+            console.log(xhr)
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });
+
+        }).catch(function(){});
+      },
+      success: aboutActions.getAboutSuccess,
+      loading: aboutActions.getAboutLoading,
+      error: aboutActions.getAboutFail
+    }
+  },
+  createTime: function() {
+    return {
+      remote: function(state) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'api/create-time?api_server=' + API_SERVER,
+            type:'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            contentType: "application/json",
+            success: function(data) {
+              resolve(data);
+            },
+            error: function(error) {
+              console.log("There was an error getting the uptime : ", error);
+              reject(error);
+            }
+          })
+
+        }).catch(function(){});;
+      },
+      success: aboutActions.getCreateTimeSuccess,
+      loading: aboutActions.getCreateTimeLoading,
+      error: aboutActions.getCreateTimeFail
+    }
+  }
+}
+module.exports = aboutSource;
diff --git a/skyquake/plugins/about/src/aboutStore.js b/skyquake/plugins/about/src/aboutStore.js
new file mode 100644 (file)
index 0000000..934522b
--- /dev/null
@@ -0,0 +1,41 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+function aboutStore () {
+  this.descriptorCount = 0;
+  this.exportAsync(require('./aboutSource.js'));
+  this.bindActions(require('./aboutActions.js'));
+}
+
+aboutStore.prototype.getAboutSuccess = function(list) {
+  this.setState({
+    aboutList:list
+  })
+  console.log('success', list)
+};
+
+aboutStore.prototype.getCreateTimeSuccess = function(time) {
+       this.setState({
+               createTime:time['uptime']
+       })
+       console.log('uptime success', time)
+}
+
+module.exports = Alt.createStore(aboutStore);;
+
diff --git a/skyquake/plugins/about/src/main.js b/skyquake/plugins/about/src/main.js
new file mode 100644 (file)
index 0000000..b10dc1d
--- /dev/null
@@ -0,0 +1,11 @@
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/about/webpack.production.config.js b/skyquake/plugins/about/webpack.production.config.js
new file mode 100644 (file)
index 0000000..5be840c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass'
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="app"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/accounts/CMakeLists.txt b/skyquake/plugins/accounts/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4caa157
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  accounts
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/accounts/accounts-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/accounts/accounts-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/accounts/api/accounts.js b/skyquake/plugins/accounts/api/accounts.js
new file mode 100644 (file)
index 0000000..1b51c7b
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var request = require('request');
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var constants = require('../../../framework/core/api_utils/constants.js');
+var _ = require('underscore');
+var Cloud = require('./cloud_account/cloudAccount')
+var Sdn = require('./sdn_account/sdnAccount')
+var ConfigAgent = require('./config_agent/configAgent')
+var Accounts = {};
+var nameSpace = {
+    cloud: 'cloud',
+    sdn: 'sdn-account',
+    'config-agent': 'config-agent'
+};
+Accounts.get = function(req) {
+    return new Promise(function(resolve, reject) {
+        if (req.params.type || req.params.name) {
+            getAccount(req)
+                .then(function(data) {
+                    resolve({
+                        statusCode: 200,
+                        data: Object.assign(data, {
+                            type: req.params.type
+                        })
+                    });
+                })
+        } else {
+            getAll(req, resolve, reject);
+        }
+    });
+
+    function getAll(req, resolve, reject) {
+        Promise.all([
+            Cloud.get(req),
+            Sdn.get(req),
+            ConfigAgent.get(req)
+        ]).then(function(result) {
+            var ReturnData = {
+                cloud: result[0],
+                sdn: result[1],
+                'config-agent': result[2]
+            };
+            ReturnData.cloud.type = 'cloud';
+            ReturnData.sdn.type = 'sdn';
+            ReturnData['config-agent'].type = 'config';
+            resolve({
+                statusCode: 200,
+                data: ReturnData
+            });
+        })
+    }
+}
+
+Accounts.update = updateAccount;
+Accounts.create = updateAccount;
+Accounts.delete = deleteAccount;
+Accounts.refreshAccountConnectionStatus = refreshAccountConnectionStatus
+function getAccount(req) {
+    return new Promise(function(resolve, reject) {
+        var self = this;
+        var api_server = req.query["api_server"];
+        var id = req.params.id || req.params.name;
+        var requestHeaders = {};
+        var type = nameSpace[req.params.type];
+        var url = utils.confdPort(api_server) + '/api/operational/' + type;
+        //SDN model doesn't follow convention
+        if (type != 'sdn-account') {
+            url += '/account';
+        }
+        if (id) {
+            url += '/' + id;
+        }
+
+        _.extend(
+            requestHeaders,
+            id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+                'Authorization': req.get('Authorization')
+            }
+        );
+
+        request({
+                url: url + '?deep',
+                type: 'GET',
+                headers: requestHeaders,
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false
+            },
+            function(error, response, body) {
+                var data;
+                var objKey = 'rw-' + type + ':account';
+                //SDN model doesn't follow convention
+                if (type == 'sdn-account') {
+                    objKey = 'rw-sdn:sdn-account';
+                }
+                if (utils.validateResponse(type.toUpperCase() + '.get', error, response, body, resolve, reject)) {
+                    try {
+                        data = JSON.parse(response.body);
+                        if (!id) {
+                            data = data.collection;
+                        }
+
+                        data = data[objKey]
+                    } catch (e) {
+                        console.log('Problem with "' + type.toUpperCase() + '.get"', e);
+                        var err = {};
+                        err.statusCode = 500;
+                        err.errorMessage = {
+                            error: 'Problem with "' + type.toUpperCase() + '.get": ' + e
+                        }
+                        return reject(err);
+                    }
+                    return resolve({
+                        statusCode: response.statusCode,
+                        data: data
+                    });
+                };
+            });
+    });
+}
+
+function updateAccount(req) {
+    var self = this;
+    var id = req.params.id || req.params.name;
+    var api_server = req.query["api_server"];
+    var type = nameSpace[req.params.type];
+    var data = req.body;
+    var requestHeaders = {};
+    var createData = {};
+    var url = utils.confdPort(api_server) + '/api/config/' + type;
+    var method = 'POST'
+    if (!id) {
+        if (type == 'sdn-account') {
+            createData = {
+                'sdn-account': Array.isArray(data) ? data : [data]
+            }
+        } else {
+            createData = {
+                'account': Array.isArray(data) ? data : [data]
+            }
+        }
+        console.log('Creating ' + type + ' account: ', createData);
+    } else {
+        method = 'PUT';
+        if (type == 'sdn-account') {
+            url += '/' + id;
+            createData['rw-sdn:sdn-account'] = Array.isArray(data) ? data : [data];
+
+        } else {
+            url += '/account/' + id;
+            createData['rw-' + type + ':account'] = Array.isArray(data) ? data : [data];
+        }
+        //createData = createData[0];
+    }
+
+
+
+    return new Promise(function(resolve, reject) {
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            });
+        request({
+            url: url,
+            method: method,
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: createData,
+        }, function(error, response, body) {
+            if (utils.validateResponse(type.toUpperCase() + '.' + method, error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    })
+}
+
+function deleteAccount(req) {
+    var self = this;
+    var id = req.params.id || req.params.name;
+    var api_server = req.query["api_server"];
+    var type = nameSpace[req.params.type];
+    var data = req.body;
+    var requestHeaders = {};
+    var createData = {};
+    var url = utils.confdPort(api_server) + '/api/config/' + type;
+    if (type == 'sdn-account') {
+        url += '/' + id;
+    } else {
+        url += '/account/' + id;
+    }
+    return new Promise(function(resolve, reject) {
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            });
+        request({
+            url: url,
+            method: 'DELETE',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse(type.toUpperCase() + '.DELETE', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    })
+}
+
+function refreshAccountConnectionStatus (req) {
+    var api_server = req.query['api_server'];
+    var Name = req.params.name;
+    var Type = req.params.type;
+    var jsonData = {
+        input: {}
+    };
+    var rpcInfo = {
+        sdn: {
+            label: 'sdn-account',
+            rpc: 'update-sdn-status'
+        },
+        'config': {
+            label: 'cfg-agent-account',
+            rpc: 'update-cfg-agent-status'
+        },
+        cloud: {
+            label: 'cloud-account',
+            rpc: 'update-cloud-status'
+        }
+    }
+    jsonData.input[rpcInfo[Type].label] = Name;
+    var headers = _.extend({},
+        constants.HTTP_HEADERS.accept.data,
+        constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        }
+    );
+    return new Promise(function(resolve, reject) {
+
+        request({
+            uri: utils.confdPort(api_server) + '/api/operations/' + rpcInfo[Type].rpc,
+            method: 'POST',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('RPC.refreshAccountConnectionStatus', error, response, body, resolve, reject)) {
+
+                resolve({
+                    statusCode: response.statusCode,
+                    data: body
+                });
+            }
+        });
+    }).catch(function(error) {
+        console.log('Error refreshing account info');
+    });
+};
+
+module.exports = Accounts;
diff --git a/skyquake/plugins/accounts/api/cloud_account/cloudAccount.js b/skyquake/plugins/accounts/api/cloud_account/cloudAccount.js
new file mode 100644 (file)
index 0000000..5475750
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+// Cloud-Account APIs
+
+
+var Cloud = {};
+var request = require('request');
+var Promise = require('promise');
+var _ = require('underscore');
+var utils = require('../../../../framework/core/api_utils/utils.js');
+var constants = require('../../../../framework/core/api_utils/constants.js');
+var APIVersion = '/v1';
+
+
+Cloud.get = function(req) {
+  var self = this;
+
+  var api_server = req.query["api_server"];
+  var id = req.params.id || req.params.name;
+
+  if (!id) {
+    // Get all cloud accounts
+    return new Promise(function(resolve, reject) {
+
+      var requestHeaders = {};
+      _.extend(requestHeaders,
+        constants.HTTP_HEADERS.accept.collection, {
+          'Authorization': req.get('Authorization')
+        });
+
+      request({
+          url: utils.confdPort(api_server) + APIVersion + '/api/operational/cloud/account',
+          type: 'GET',
+          headers: requestHeaders,
+          forever: constants.FOREVER_ON,
+          rejectUnauthorized: false
+        },
+        function(error, response, body) {
+          var data;
+          if (utils.validateResponse('Cloud.get', error, response, body, resolve, reject)) {
+            try {
+              data = JSON.parse(response.body).collection['rw-cloud:account']
+            } catch (e) {
+              console.log('Problem with "Cloud.get"', e);
+              var err = {};
+              err.statusCode = 500;
+              err.errorMessage = {
+                error: 'Problem with "Cloud.get": ' + e // + e.toString()
+              }
+              return reject(err);
+            }
+            return resolve({
+              statusCode: response.statusCode,
+              data: self.poolAggregate(data)
+            });
+          };
+        });
+    });
+  } else {
+    //Get a specific cloud account
+    return new Promise(function(resolve, reject) {
+      var requestHeaders = {};
+      _.extend(requestHeaders,
+        constants.HTTP_HEADERS.accept.data, {
+          'Authorization': req.get('Authorization')
+        });
+
+      request({
+          url: utils.confdPort(api_server) + APIVersion + '/api/operational/cloud/account/' + id,
+          type: 'GET',
+          headers: requestHeaders,
+          forever: constants.FOREVER_ON,
+          rejectUnauthorized: false
+        },
+        function(error, response, body) {
+          var data;
+          if (utils.validateResponse('Cloud.get', error, response, body, resolve, reject)) {
+            try {
+              data = JSON.parse(response.body)['rw-cloud:account'];
+            } catch (e) {
+              console.log('Problem with "Cloud.get"', e);
+              var err = {};
+              err.statusCode = 500;
+              err.errorMessage = {
+                error: 'Problem with "Cloud.get": ' + e.toString()
+              }
+              return reject(err);
+            }
+
+            return resolve({
+              statusCode: response.statusCode,
+              data: data
+            });
+          }
+        });
+    });
+  }
+};
+
+Cloud.create = function(req) {
+
+  var api_server = req.query["api_server"];
+  var data = req.body;
+
+  return new Promise(function(resolve, reject) {
+    var jsonData = {
+      "account": Array.isArray(data) ? data : [data]
+    };
+
+    console.log('Creating with', JSON.stringify(jsonData));
+
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data,
+      constants.HTTP_HEADERS.content_type.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+      url: utils.confdPort(api_server) + APIVersion + '/api/config/cloud',
+      method: 'POST',
+      headers: requestHeaders,
+      forever: constants.FOREVER_ON,
+      rejectUnauthorized: false,
+      json: jsonData,
+    }, function(error, response, body) {
+      console.log('Handling Cloud Create response')
+      if (utils.validateResponse('Cloud.create', error, response, body, resolve, reject)) {
+        return resolve({
+          statusCode: response.statusCode,
+          data: JSON.stringify(response.body)
+        });
+      };
+    });
+  });
+};
+
+Cloud.update = function(req) {
+
+  var api_server = req.query["api_server"];
+  var id = req.params.id || req.params.name;
+  var data = req.body;
+
+  return new Promise(function(resolve, reject) {
+    var jsonData = {
+      "rw-cloud:account": data
+    };
+
+    console.log('Updating ', id, ' with', JSON.stringify(jsonData));
+
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data,
+      constants.HTTP_HEADERS.content_type.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+      url: utils.confdPort(api_server) + APIVersion + '/api/config/cloud/account/' + id,
+      method: 'PUT',
+      headers: requestHeaders,
+      forever: constants.FOREVER_ON,
+      rejectUnauthorized: false,
+      json: jsonData,
+    }, function(error, response, body) {
+      if (utils.validateResponse('Cloud.update', error, response, body, resolve, reject)) {
+        return resolve({
+          statusCode: response.statusCode,
+          data: JSON.stringify(response.body)
+        });
+      };
+    });
+  });
+};
+
+Cloud.delete = function(req) {
+
+  var api_server = req.query["api_server"];
+  var id = req.params.id || req.params.name;
+
+  if (!id || !api_server) {
+    return new Promise(function(resolve, reject) {
+      console.log('Must specifiy api_server and id to delete cloud account');
+      return reject({
+        statusCode: 500,
+        errorMessage: {
+          error: 'Must specifiy api_server and id to delete cloud account'
+        }
+      });
+    });
+  };
+
+  return new Promise(function(resolve, reject) {
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+    request({
+      url: utils.confdPort(api_server) + APIVersion + '/api/config/cloud/account/' + id,
+      method: 'DELETE',
+      headers: requestHeaders,
+      forever: constants.FOREVER_ON,
+      rejectUnauthorized: false
+    }, function(error, response, body) {
+      if (utils.validateResponse('Cloud.delete', error, response, body, resolve, reject)) {
+        return resolve({
+          statusCode: response.statusCode,
+          data: JSON.stringify(response.body)
+        });
+      };
+    });
+  });
+};
+
+Cloud.getResources = function(req) {
+
+  var api_server = req.query["api_server"];
+  var cloudAccount = req.query["cloud_account"];
+
+  return new Promise(function(resolve, reject) {
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+        url: utils.confdPort(api_server) + APIVersion + '/api/operational/cloud/account/' + cloudAccount + '/resources?deep',
+        type: 'GET',
+        headers: requestHeaders,
+        forever: constants.FOREVER_ON,
+        rejectUnauthorized: false
+      },
+      function(error, response, body) {
+        var data;
+        if (utils.validateResponse('Cloud.getResources', error, response, body, resolve, reject)) {
+          try {
+            data = JSON.parse(response.body)['rw-cloud:resources']
+          } catch (e) {
+            console.log('Problem with "Cloud.getResources"', e);
+
+            var err = {};
+            err.statusCode = 500;
+            err.errorMessage = {
+              error: 'Problem with "Cloud.getResources": ' + e.toString()
+            }
+
+            return reject(err);
+          }
+
+          return resolve(data);
+        };
+      });
+  });
+};
+
+Cloud.getPools = function(req) {
+
+  var api_server = req.query["api_server"];
+  var cloudAccount = req.query["cloud-account"];
+
+  return new Promise(function(resolve, reject) {
+
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+        url: utils.confdPort(api_server) + APIVersion + '/api/operational/cloud/account/' + cloudAccount + '/pools',
+        type: 'GET',
+        headers: requestHeaders,
+        forever: constants.FOREVER_ON,
+        rejectUnauthorized: false
+      },
+      function(error, response, body) {
+        var data;
+        if (utils.validateResponse('Cloud.getPools', error, response, body, resolve, reject)) {
+          try {
+            data = JSON.parse(response.body)['rw-cloud:pools']
+          } catch (e) {
+            console.log('Problem with "Cloud.getPools"', e);
+            var err = {};
+            err.statusCode = 500;
+            err.errorMessage = {
+              error: 'Problem with "Cloud.getPools": ' + e.toString()
+            }
+
+            return reject(err);
+          }
+
+          return resolve({
+            statusCode: response.statusCode,
+            data: data
+          });
+        }
+      });
+  });
+}
+
+Cloud.poolAggregate = function(cloudAccounts) {
+  cloudAccounts.forEach(function(ca) {
+    var oldPools = ca.pools;
+    var newPools = [];
+    for (type in oldPools) {
+      oldPools[type].forEach(function(pool) {
+        pool.type = type;
+        newPools.push(pool);
+      })
+    }
+    ca.pools = newPools;
+  });
+  return cloudAccounts;
+}
+
+
+
+module.exports = Cloud;
diff --git a/skyquake/plugins/accounts/api/config_agent/configAgent.js b/skyquake/plugins/accounts/api/config_agent/configAgent.js
new file mode 100644 (file)
index 0000000..8d1734b
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var request = require('request');
+var Promise = require('promise');
+var _ = require('underscore');
+var utils = require('../../../../framework/core/api_utils/utils.js');
+var constants = require('../../../../framework/core/api_utils/constants.js');
+var ConfigAgentAccount = {};
+
+
+// Config-Agent Account APIs
+ConfigAgentAccount.get = function(req) {
+    var self = this;
+
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+
+    if (!id) {
+        // Get all config accounts
+        return new Promise(function(resolve, reject) {
+
+            var requestHeaders = {};
+            _.extend(requestHeaders,
+                constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                });
+
+            request({
+                    url: utils.confdPort(api_server) + '/api/operational/config-agent/account',
+                    type: 'GET',
+                    headers: requestHeaders,
+                    forever: constants.FOREVER_ON,
+                    rejectUnauthorized: false,
+                },
+                function(error, response, body) {
+                    var data;
+                    var statusCode;
+                    if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
+                        try {
+                            data = JSON.parse(response.body).collection['rw-config-agent:account'];
+                            statusCode = response.statusCode;
+                        } catch (e) {
+                            console.log('Problem with "ConfigAgentAccount.get"', e);
+                            var err = {};
+                            err.statusCode = 500;
+                            err.errorMessage = {
+                                error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
+                            }
+                            return reject(err);
+                        }
+
+                        return resolve({
+                            statusCode: statusCode,
+                            data: data
+                        });
+                    };
+                });
+        });
+    } else {
+        //Get a specific config account
+        return new Promise(function(resolve, reject) {
+            var requestHeaders = {};
+            _.extend(requestHeaders,
+                constants.HTTP_HEADERS.accept.data, {
+                    'Authorization': req.get('Authorization')
+                });
+
+            request({
+                    url: utils.confdPort(api_server) + '/api/operational/config-agent/account/' + id,
+                    type: 'GET',
+                    headers: requestHeaders,
+                    forever: constants.FOREVER_ON,
+                    rejectUnauthorized: false,
+                },
+                function(error, response, body) {
+                    var data;
+                    var statusCode;
+                    if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
+                        try {
+                            data = JSON.parse(response.body)['rw-config-agent:account'];
+                            statusCode = response.statusCode;
+                        } catch (e) {
+                            console.log('Problem with "ConfigAgentAccount.get"', e);
+                            var err = {};
+                            err.statusCode = 500;
+                            err.errorMessage = {
+                                error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
+                            }
+                            return reject(err);
+                        }
+
+                        return resolve({
+                            statusCode: statusCode,
+                            data: data
+                        });
+                    }
+                });
+        });
+    }
+};
+
+ConfigAgentAccount.create = function(req) {
+
+    var api_server = req.query["api_server"];
+    var data = req.body;
+
+    return new Promise(function(resolve, reject) {
+        var jsonData = {
+            "account": Array.isArray(data) ? data : [data]
+        };
+
+        console.log('Creating with', JSON.stringify(jsonData));
+
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            });
+
+        request({
+            url: utils.confdPort(api_server) + '/api/config/config-agent',
+            method: 'POST',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData,
+        }, function(error, response, body) {
+            if (utils.validateResponse('ConfigAgentAccount.create', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body),
+                    body:response.body.body
+                });
+            };
+        });
+    });
+};
+
+ConfigAgentAccount.update = function(req) {
+
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+    var data = req.body;
+
+    return new Promise(function(resolve, reject) {
+        var jsonData = {
+            "rw-config-agent:account": data
+        };
+
+        console.log('Updating config-agent', id, ' with', JSON.stringify(jsonData));
+
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            });
+
+        request({
+            url: utils.confdPort(api_server) + '/api/config/config-agent/account/' + id,
+            method: 'PUT',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData,
+        }, function(error, response, body) {
+            if (utils.validateResponse('ConfigAgentAccount.update', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    });
+};
+
+ConfigAgentAccount.delete = function(req) {
+
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+
+    if (!id || !api_server) {
+        return new Promise(function(resolve, reject) {
+            console.log('Must specifiy api_server and id to delete config-agent account');
+            return reject({
+                statusCode: 500,
+                errorMessage: {
+                    error: 'Must specifiy api_server and id to delete config agent account'
+                }
+            });
+        });
+    };
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            });
+        request({
+            url: utils.confdPort(api_server) + '/api/config/config-agent/account/' + id,
+            method: 'DELETE',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('ConfigAgentAccount.delete', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    });
+};
+
+
+
+module.exports = ConfigAgentAccount;
diff --git a/skyquake/plugins/accounts/api/sdn_account/sdnAccount.js b/skyquake/plugins/accounts/api/sdn_account/sdnAccount.js
new file mode 100644 (file)
index 0000000..c2b592d
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+// SDN-Account APIs
+
+
+var Sdn = {};
+var request = require('request');
+var Promise = require('promise');
+var utils = require('../../../../framework/core/api_utils/utils.js');
+var constants = require('../../../../framework/core/api_utils/constants.js');
+var _ = require('underscore');
+
+//Sdn Account APIs
+Sdn.get = function(req) {
+
+  var api_server = req.query["api_server"];
+  var id = req.params.id;
+
+  var self = this;
+  if (!id) {
+    // Get all sdn accounts
+    return new Promise(function(resolve, reject) {
+      var requestHeaders = {};
+      _.extend(requestHeaders,
+        constants.HTTP_HEADERS.accept.collection, {
+          'Authorization': req.get('Authorization')
+        });
+      request({
+          url: utils.confdPort(api_server) + '/api/operational/sdn-account?deep',
+          type: 'GET',
+          headers: requestHeaders,
+          forever: constants.FOREVER_ON,
+          rejectUnauthorized: false
+        },
+        function(error, response, body) {
+          var data;
+          if (utils.validateResponse('Sdn.get', error, response, body, resolve, reject)) {
+            try {
+              data = JSON.parse(response.body).collection['rw-sdn:sdn-account']
+            } catch (e) {
+              console.log('Problem with "Sdn.get"', e);
+
+              var err = {};
+              err.statusCode = 500;
+              err.errorMessage = {
+                error: 'Problem with "Sdn.get": ' + e.toString()
+              }
+
+              return reject(err);
+            }
+
+            return resolve({
+              data: data,
+              statusCode: response.statusCode
+            });
+          }
+        });
+    });
+  } else {
+    //Get a specific sdn account
+    return new Promise(function(resolve, reject) {
+      var requestHeaders = {};
+      _.extend(requestHeaders,
+        constants.HTTP_HEADERS.accept.data, {
+          'Authorization': req.get('Authorization')
+        });
+
+      request({
+          url: utils.confdPort(api_server) + '/api/operational/sdn-account/' + id + '?deep',
+          type: 'GET',
+          headers: requestHeaders,
+          forever: constants.FOREVER_ON,
+          rejectUnauthorized: false
+        },
+        function(error, response, body) {
+          var data;
+          if (utils.validateResponse('Sdn.get', error, response, body, resolve, reject)) {
+            try {
+              data = JSON.parse(response.body)['rw-sdn:sdn-account'];
+            } catch (e) {
+              console.log('Problem with "Sdn.get"', e);
+
+              var err = {};
+              err.statusCode = 500;
+              err.errorMessage = {
+                error: 'Problem with "Sdn.get": ' + e.toString()
+              }
+
+              return reject(err);
+            }
+
+            return resolve({
+              data: data,
+              statusCode: response.statusCode
+            });
+          }
+        });
+    });
+  }
+};
+
+Sdn.create = function(req) {
+
+  var api_server = req.query["api_server"];
+  var data = req.body;
+
+  return new Promise(function(resolve, reject) {
+    var jsonData = {
+      "sdn-account": Array.isArray(data) ? data : [data]
+    };
+
+    console.log('Creating SDN account with', JSON.stringify(jsonData));
+
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data,
+      constants.HTTP_HEADERS.content_type.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+      url: utils.confdPort(api_server) + '/api/config/sdn-account',
+      method: 'POST',
+      headers: requestHeaders,
+      forever: constants.FOREVER_ON,
+      rejectUnauthorized: false,
+      json: jsonData,
+    }, function(error, response, body) {
+      if (utils.validateResponse('Sdn.create', error, response, body, resolve, reject)) {
+        return resolve({
+          data: JSON.stringify(response.body),
+          statusCode: response.statusCode
+        });
+      }
+    });
+  });
+};
+
+Sdn.update = function(req) {
+
+  var api_server = req.query["api_server"];
+  var id = req.params.id;
+  var data = req.body;
+
+  return new Promise(function(resolve, reject) {
+    var jsonData = {
+      "rw-sdn:sdn-account": data
+    };
+
+    console.log('Updating SDN account ', id, ' with', JSON.stringify(jsonData));
+
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data,
+      constants.HTTP_HEADERS.content_type.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+      url: utils.confdPort(api_server) + '/api/config/sdn-account/' + id,
+      method: 'PUT',
+      headers: requestHeaders,
+      forever: constants.FOREVER_ON,
+      rejectUnauthorized: false,
+      json: jsonData,
+    }, function(error, response, body) {
+      if (utils.validateResponse('Sdn.update', error, response, body, resolve, reject)) {
+        return resolve({
+          data: JSON.stringify(response.body),
+          statusCode: response.statusCode
+        });
+      }
+    });
+  });
+};
+
+Sdn.delete = function(req) {
+
+  var api_server = req.query["api_server"];
+  var id = req.params.id;
+
+  if (!id || !api_server) {
+    return new Promise(function(resolve, reject) {
+      console.log('Must specifiy api_server and id to delete sdn account');
+      reject({
+        statusCode: 500,
+        errorMessage: {
+          error: 'Must specifiy api_server and id to delete sdn account'
+        }
+      });
+    });
+  };
+
+  return new Promise(function(resolve, reject) {
+
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+
+    request({
+      url: utils.confdPort(api_server) + '/api/config/sdn-account/' + id,
+      method: 'DELETE',
+      headers: requestHeaders,
+      forever: constants.FOREVER_ON,
+      rejectUnauthorized: false
+    }, function(error, response, body) {
+      if (utils.validateResponse('Sdn.delete', error, response, body, resolve, reject)) {
+        return resolve({
+          data: JSON.stringify(response.body),
+          statusCode: response.statusCode
+        });
+      }
+    });
+  });
+};
+
+module.exports = Sdn
diff --git a/skyquake/plugins/accounts/config.json b/skyquake/plugins/accounts/config.json
new file mode 100644 (file)
index 0000000..81bb702
--- /dev/null
@@ -0,0 +1,23 @@
+{
+    "root": "public",
+    "name": "Accounts",
+    "dashboard": "./account/accountsDashboard.jsx",
+    "order": 1,
+    "priority":1,
+    "routes": [
+    {
+        "label": "Accounts Dashboard",
+        "route": "accounts",
+        "component": "./account/accountsDashboard.jsx",
+        "path": "accounts",
+        "type": "internal",
+        "routes": [
+            {
+                "route": ":type/:name",
+                "component": "./account/account.jsx",
+                "path": ":type/:name",
+                "type": "internal"
+            }
+        ]
+    }]
+}
diff --git a/skyquake/plugins/accounts/images/OpenDaylight_logo.png b/skyquake/plugins/accounts/images/OpenDaylight_logo.png
new file mode 100644 (file)
index 0000000..b9064ec
Binary files /dev/null and b/skyquake/plugins/accounts/images/OpenDaylight_logo.png differ
diff --git a/skyquake/plugins/accounts/images/aws.png b/skyquake/plugins/accounts/images/aws.png
new file mode 100644 (file)
index 0000000..ca57e1c
Binary files /dev/null and b/skyquake/plugins/accounts/images/aws.png differ
diff --git a/skyquake/plugins/accounts/images/juju.svg b/skyquake/plugins/accounts/images/juju.svg
new file mode 100644 (file)
index 0000000..142f608
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="1190.55px" height="841.89px" viewBox="0 0 1190.55 841.89" enable-background="new 0 0 1190.55 841.89"
+        xml:space="preserve">
+<g>
+       <g>
+               <path fill="#DD4814" d="M657.621,123.565c-73.488,0-133.063,59.573-133.063,133.062s59.576,133.069,133.063,133.069
+                       c73.49,0,133.064-59.58,133.064-133.069S731.111,123.565,657.621,123.565z"/>
+               <path fill="#FFFFFF" d="M593.043,338.909c-1.128,1.128-2.632,1.75-4.233,1.75l0,0c-1.605,0-3.112-0.624-4.244-1.757
+                       c-1.129-1.128-1.751-2.632-1.751-4.234c0-1.602,0.622-3.105,1.751-4.235c1.133-1.132,2.64-1.756,4.243-1.756
+                       c1.601,0,3.104,0.622,4.233,1.751c1.131,1.131,1.753,2.637,1.753,4.24C594.797,336.273,594.174,337.779,593.043,338.909z"/>
+               <path fill="#FFFFFF" d="M619.154,249.424c-0.603-1.92-1.47-3.498-2.579-4.69c-1.105-1.193-2.443-2.085-3.978-2.653
+                       c-1.543-0.574-3.291-0.865-5.194-0.865s-3.636,0.29-5.147,0.863c-1.509,0.569-2.834,1.462-3.939,2.654
+                       c-1.107,1.19-1.974,2.769-2.578,4.691c-0.606,1.933-0.914,4.299-0.914,7.032v69.735h-12.038V255.39
+                       c0-3.572,0.484-6.896,1.438-9.88c0.957-2.996,2.463-5.641,4.475-7.863c2.015-2.226,4.586-3.976,7.643-5.203
+                       c3.05-1.226,6.742-1.848,10.973-1.848c4.229,0,7.949,0.622,11.059,1.847c3.115,1.227,5.717,2.978,7.732,5.204
+                       c2.01,2.219,3.532,4.863,4.52,7.861c0.985,2.985,1.485,6.311,1.485,9.882V265h-12.038v-8.544
+                       C620.072,253.733,619.763,251.367,619.154,249.424z"/>
+               <path fill="#FFFFFF" d="M669.396,298.309c0,3.579-0.499,6.905-1.483,9.885c-0.985,2.99-2.507,5.634-4.521,7.86
+                       c-2.016,2.225-4.617,3.976-7.732,5.203c-3.112,1.226-6.833,1.848-11.06,1.848s-7.917-0.622-10.972-1.849
+                       c-3.055-1.226-5.626-2.976-7.642-5.201c-2.014-2.226-3.52-4.872-4.476-7.864c-0.954-2.983-1.437-6.308-1.437-9.882v-30.425h12.037
+                       v29.361c0,2.734,0.309,5.099,0.914,7.029c0.603,1.924,1.471,3.502,2.578,4.694c1.106,1.194,2.434,2.087,3.938,2.654
+                       c1.511,0.573,3.242,0.863,5.147,0.863c1.903,0,3.651-0.291,5.193-0.864c1.533-0.568,2.871-1.461,3.979-2.653
+                       c1.108-1.194,1.979-2.773,2.579-4.693c0.607-1.94,0.917-4.305,0.917-7.03v-29.361h12.038V298.309z"/>
+               <path fill="#FFFFFF" d="M657.387,259.099c0-3.302,2.685-5.989,5.986-5.989c3.305,0,5.995,2.687,5.995,5.989
+                       c0,3.305-2.69,5.994-5.995,5.994C660.071,265.093,657.387,262.404,657.387,259.099z"/>
+               <path fill="#FFFFFF" d="M693.726,174.163c-0.603-1.92-1.472-3.499-2.581-4.693c-1.107-1.193-2.446-2.085-3.979-2.652
+                       c-1.54-0.573-3.288-0.863-5.193-0.863c-1.903,0-3.635,0.29-5.146,0.862c-1.508,0.569-2.834,1.462-3.941,2.653
+                       c-1.105,1.193-1.973,2.772-2.575,4.693c-0.606,1.932-0.914,4.298-0.914,7.032v69.734h-12.038v-70.8
+                       c0-3.571,0.482-6.896,1.438-9.881c0.958-2.996,2.463-5.642,4.477-7.863c2.012-2.224,4.584-3.975,7.643-5.202
+                       c3.055-1.227,6.744-1.849,10.969-1.849c4.227,0,7.948,0.622,11.06,1.848c3.119,1.228,5.719,2.979,7.731,5.203
+                       c2.014,2.22,3.535,4.865,4.522,7.86c0.983,2.988,1.483,6.314,1.483,9.885v9.609h-12.04v-8.543
+                       C694.64,178.467,694.332,176.101,693.726,174.163z"/>
+               <path fill="#FFFFFF" d="M743.963,223.048c0,3.577-0.499,6.903-1.482,9.884c-0.986,2.993-2.506,5.638-4.518,7.86
+                       c-2.018,2.226-4.619,3.976-7.732,5.203c-3.115,1.226-6.837,1.848-11.06,1.848c-4.229,0-7.921-0.622-10.974-1.849
+                       c-3.057-1.226-5.626-2.976-7.642-5.201c-2.012-2.223-3.518-4.868-4.476-7.863c-0.954-2.989-1.438-6.313-1.438-9.881v-30.426
+                       h12.038v29.361c0,2.729,0.308,5.095,0.915,7.031c0.603,1.92,1.469,3.499,2.58,4.692c1.106,1.194,2.432,2.087,3.937,2.654
+                       c1.513,0.573,3.243,0.863,5.146,0.863c1.907,0,3.654-0.291,5.194-0.864c1.534-0.566,2.872-1.459,3.981-2.653
+                       c1.106-1.19,1.975-2.769,2.577-4.692c0.607-1.936,0.916-4.301,0.916-7.031v-29.361h12.037V223.048z"/>
+       </g>
+       <g>
+               <path d="M360.49,646.299c-2.566,0-5.878-0.32-9.943-0.962c-4.06-0.642-7.482-1.498-10.264-2.565l3.849-24.377
+                       c2.14,0.641,4.601,1.172,7.377,1.603c2.781,0.427,5.347,0.642,7.698,0.642c10.265,0,17.586-3.157,21.972-9.461
+                       c4.38-6.311,6.575-15.557,6.575-27.746V419.527h29.83v163.584c0,21.38-4.866,37.257-14.594,47.631
+                       C393.257,641.112,379.094,646.299,360.49,646.299z"/>
+               <path d="M595.598,581.507c-6.847,1.714-15.877,3.528-27.103,5.454c-11.227,1.924-24.217,2.887-38.972,2.887
+                       c-12.83,0-23.63-1.875-32.396-5.614c-8.771-3.738-15.826-9.03-21.168-15.876c-5.348-6.842-9.197-14.916-11.547-24.218
+                       c-2.356-9.302-3.528-19.616-3.528-30.952v-93.66h29.83v87.245c0,20.317,3.208,34.856,9.622,43.622
+                       c6.416,8.771,17.21,13.15,32.396,13.15c3.208,0,6.52-0.105,9.943-0.32c3.417-0.211,6.625-0.481,9.623-0.802
+                       c2.992-0.321,5.718-0.642,8.179-0.963c2.457-0.32,4.22-0.691,5.293-1.122V419.527h29.83V581.507z"/>
+               <path d="M615.162,646.299c-2.566,0-5.879-0.32-9.943-0.962c-4.06-0.642-7.484-1.498-10.265-2.565l3.85-24.377
+                       c2.14,0.641,4.601,1.172,7.377,1.603c2.782,0.427,5.348,0.642,7.698,0.642c10.265,0,17.587-3.157,21.972-9.461
+                       c4.38-6.311,6.575-15.557,6.575-27.746V419.527h29.83v163.584c0,21.38-4.866,37.257-14.595,47.631
+                       C647.929,641.112,633.766,646.299,615.162,646.299z"/>
+               <path d="M850.27,581.507c-6.846,1.714-15.878,3.528-27.104,5.454c-11.227,1.924-24.217,2.887-38.972,2.887
+                       c-12.83,0-23.63-1.875-32.396-5.614c-8.771-3.738-15.827-9.03-21.17-15.876c-5.347-6.842-9.196-14.916-11.547-24.218
+                       c-2.355-9.302-3.528-19.616-3.528-30.952v-93.66h29.83v87.245c0,20.317,3.207,34.856,9.622,43.622
+                       c6.415,8.771,17.211,13.15,32.396,13.15c3.207,0,6.521-0.105,9.942-0.32c3.419-0.211,6.627-0.481,9.624-0.802
+                       c2.991-0.321,5.718-0.642,8.179-0.963c2.455-0.32,4.22-0.691,5.292-1.122V419.527h29.83V581.507z"/>
+       </g>
+</g>
+</svg>
diff --git a/skyquake/plugins/accounts/images/openmano.png b/skyquake/plugins/accounts/images/openmano.png
new file mode 100644 (file)
index 0000000..0557c00
Binary files /dev/null and b/skyquake/plugins/accounts/images/openmano.png differ
diff --git a/skyquake/plugins/accounts/images/openstack-horizontal.png b/skyquake/plugins/accounts/images/openstack-horizontal.png
new file mode 100644 (file)
index 0000000..e1426e5
Binary files /dev/null and b/skyquake/plugins/accounts/images/openstack-horizontal.png differ
diff --git a/skyquake/plugins/accounts/images/openstack.png b/skyquake/plugins/accounts/images/openstack.png
new file mode 100644 (file)
index 0000000..9ee6d77
Binary files /dev/null and b/skyquake/plugins/accounts/images/openstack.png differ
diff --git a/skyquake/plugins/accounts/images/riftio.png b/skyquake/plugins/accounts/images/riftio.png
new file mode 100644 (file)
index 0000000..19bdf36
Binary files /dev/null and b/skyquake/plugins/accounts/images/riftio.png differ
diff --git a/skyquake/plugins/accounts/package.json b/skyquake/plugins/accounts/package.json
new file mode 100644 (file)
index 0000000..e126042
--- /dev/null
@@ -0,0 +1,54 @@
+{
+  "name": "accounts",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "RIFT.io",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "alt": "^0.18.3",
+    "bluebird": "^3.4.1",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "jquery": "^2.2.1",
+    "json-loader": "^0.5.4",
+    "lodash": "^4.10.0",
+    "normalizr": "^2.1.0",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.4.1",
+    "react": "^0.14.8",
+    "react-breadcrumbs": "^1.3.9",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.6",
+    "react-router": "^2.0.1",
+    "react-slick": "^0.11.1",
+    "react-tabs": "^0.5.3",
+    "react-treeview": "^0.4.2",
+    "request-promise": "^3.0.0",
+    "underscore": "^1.8.3"
+  },
+  "devDependencies": {
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-polyfill": "^6.9.1",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "cors": "^2.7.1",
+    "css-loader": "^0.23.1",
+    "file-loader": "^0.8.5",
+    "html-webpack-plugin": "^2.9.0",
+    "http-proxy": "^1.12.0",
+    "loaders.css": "^0.1.2",
+    "node-sass": "^3.4.2",
+    "react-addons-css-transition-group": "^0.14.7",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "webpack": "^1.3.0",
+    "webpack-dev-server": "^1.10.1"
+  }
+}
diff --git a/skyquake/plugins/accounts/routes.js b/skyquake/plugins/accounts/routes.js
new file mode 100644 (file)
index 0000000..46eb736
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var app = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js')
+var accountsAPI = require('./api/accounts.js')
+ // Begin Accounts API
+    app.get('/all', cors(), function(req, res) {
+        accountsAPI.get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/:type', cors(), function(req, res) {
+        accountsAPI.get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/:type/:name', cors(), function(req, res) {
+        accountsAPI.get(req).then(function(data) {
+            utils.sendSuccessResponse(data.data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.post('/:type', cors(), function(req, res) {
+        accountsAPI.create(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.put('/:type/:id', cors(), function(req, res) {
+        accountsAPI.update(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.delete('/:type/:id', cors(), function(req, res) {
+        accountsAPI.delete(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.post('/:type/:name/refresh', cors(), function(req, res) {
+        accountsAPI.refreshAccountConnectionStatus(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    })
+
+
+module.exports = app;
diff --git a/skyquake/plugins/accounts/scripts/build.sh b/skyquake/plugins/accounts/scripts/build.sh
new file mode 100755 (executable)
index 0000000..921cfeb
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=accounts
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/accounts/scripts/install.sh b/skyquake/plugins/accounts/scripts/install.sh
new file mode 100755 (executable)
index 0000000..2b5fdb1
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=accounts
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
diff --git a/skyquake/plugins/accounts/server.js b/skyquake/plugins/accounts/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/accounts/src/account/account.jsx b/skyquake/plugins/accounts/src/account/account.jsx
new file mode 100644 (file)
index 0000000..c40e627
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import Button from 'widgets/button/rw.button.js';
+import _ from 'lodash';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import Crouton from 'react-crouton';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import {AccountConnectivityStatus} from '../account_sidebar/accountSidebar.jsx';
+import 'style/common.scss';
+import './account.scss';
+class Account extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.account = {};
+    }
+    storeListener = (state) => {
+        if(!state.account) {
+            this.setUp(this.props)
+        }
+        state.account && this.setState({account: state.account,accountType: state.accountType, types: state.types, sdnOptions: state.sdnOptions})
+    }
+    componentWillMount() {
+        this.props.store.listen(this.storeListener);
+        this.setUp(this.props);
+    }
+    componentWillReceiveProps(nextProps) {
+        if(JSON.stringify(nextProps.params) != JSON.stringify(this.props.params)){
+              this.setUp(nextProps);
+        }
+    }
+    componentWillUnmount() {
+        this.props.store.unlisten(this.storeListener);
+    }
+    setUp(props){
+        if(props.params.name != 'create') {
+            this.props.store.viewAccount({type: props.params.type, name: props.params.name});
+        } else {
+            this.props.store.setAccountTemplate(props.params.type);
+        }
+    }
+    create(e) {
+        e.preventDefault();
+        var self = this;
+        var Account = this.state.account;
+        let AccountType = this.state.accountType;
+        if (Account.name == "") {
+            self.props.flux.actions.global.showNotification("Please give the account a name");
+            return;
+        } else {
+            var type = Account['account-type'];
+            var params = Account.params;
+
+            if(params) {
+                for (var i = 0; i < params.length; i++) {
+                    var param = params[i].ref;
+                    if (typeof(Account[type]) == 'undefined' || typeof(Account[type][param]) == 'undefined' || Account[type][param] == "") {
+                        if (!params[i].optional) {
+                            self.props.flux.actions.global.showNotification("Please fill all account details");
+                            return;
+                        }
+                    }
+                }
+            }
+
+            let nestedParams = Account.nestedParams && Account.nestedParams;
+            if (nestedParams && nestedParams.params) {
+                for (let i = 0; i < nestedParams.params.length; i++) {
+                    let nestedParam = nestedParams.params[i].ref;
+                    if (typeof(Account[type]) == 'undefined' || typeof(Account[type][nestedParams['container-name']][nestedParam]) == 'undefined' || Account[type][nestedParams['container-name']][nestedParam] == "") {
+                        if (!nestedParams.params[i].optional) {
+                            self.props.flux.actions.global.showNotification("Please fill all account details");
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+
+        let newAccount = _.cloneDeep(removeTrailingWhitespace(Account));
+        delete newAccount.params;
+        newAccount.nestedParams &&
+            newAccount.nestedParams['container-name'] &&
+            delete newAccount[newAccount.nestedParams['container-name']];
+        delete newAccount.nestedParams;
+
+        this.props.flux.actions.global.showScreenLoader();
+        this.props.store.create(newAccount, AccountType).then(function() {
+            self.props.router.push({pathname:'accounts'});
+            self.props.flux.actions.global.hideScreenLoader.defer();
+        },
+         function() {
+            self.props.flux.actions.global.showNotification("There was an error creating your account. Please contact your system administrator.");
+            self.props.flux.actions.global.hideScreenLoader.defer();
+         });
+    }
+    update(e) {
+        e.preventDefault();
+        var self = this;
+        var Account = this.state.account;
+        let AccountType = this.state.accountType;
+        this.props.flux.actions.global.showScreenLoader();
+        this.props.store.update(Account, AccountType).then(function() {
+            self.props.router.push({pathname:'accounts'});
+             self.props.flux.actions.global.hideScreenLoader();
+        },
+        function() {
+
+        });
+    }
+    cancel = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+        this.props.router.push({pathname:'accounts'});
+    }
+    handleDelete = () => {
+        let self = this;
+        let msg = 'Preparing to delete "' + self.state.account.name + '"' +
+        ' Are you sure you want to delete this ' + self.state.accountType + ' account?"';
+        if (window.confirm(msg)) {
+            this.props.store.delete(self.state.accountType, self.state.account.name).then(function() {
+                self.props.flux.actions.global.hideScreenLoader();
+                self.props.router.push({pathname:'accounts'});
+            }, function(){
+                // self.props.flux.actions.global.hideScreenLoader.defer();
+                // console.log('Delete Account Fail');
+            });
+        } else {
+           self.props.flux.actions.global.hideScreenLoader();
+        }
+    }
+    handleNameChange(event) {
+       this.props.store.handleNameChange(event);
+    }
+    handleAccountTypeChange(node, event) {
+        this.props.store.handleAccountTypeChange(node, event);
+    }
+    handleSelectSdnAccount = (e) => {
+        var tmp = this.state.account;
+        if(e) {
+            tmp['sdn-account'] = e;
+        } else {
+            if(tmp['sdn-account']) {
+                delete tmp['sdn-account'];
+            }
+        }
+        console.log(e, tmp)
+    }
+    preventDefault = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+    }
+    evaluateSubmit = (e) => {
+        if (e.keyCode == 13) {
+            if (this.props.edit) {
+                this.update(e);
+            } else {
+                this.create(e);
+            }
+            e.preventDefault();
+            e.stopPropagation();
+        }
+    }
+
+    render() {
+        let self = this;
+        let {store, ...props} = this.props;
+        // This section builds elements that only show up on the create page.
+        // var name = <label>Name <input type="text" onChange={this.handleNameChange.bind(this)} style={{'textAlign':'left'}} /></label>;
+        var name = <TextInput label="Name"  onChange={this.handleNameChange.bind(this)} required={true} />;
+        let params = null;
+        let selectAccount = null;
+        let resfreshStatus = null;
+        let Account = this.state.account;
+        // AccountType is for the view, not the data account-type value;
+        let AccountType = this.state.accountType;
+        let Types = this.state.types;
+        let isEdit = this.props.params.name != 'create';
+        var buttons;
+        let cloudResources = Account['cloud-resources-state'] && Account['cloud-resources-state'][Account['account-type']];
+        let cloudResourcesStateHTML = null;
+
+        // Account Type Radio
+        var selectAccountStack = [];
+        if (!isEdit) {
+            buttons = [
+                <Button key="0" onClick={this.cancel} className="cancel light" label="Cancel"></Button>,
+                <Button key="1" role="button" onClick={this.create.bind(this)} className="save dark" label="Save" />
+            ]
+            for (var i = 0; i < Types.length; i++) {
+                var node = Types[i];
+                var isSelected = (Account['account-type'] == node['account-type']);
+                selectAccountStack.push(
+                  <label key={i} className={"accountSelection " + (isSelected ? "accountSelection--isSelected" : "")}>
+                    <div className={"accountSelection-overlay" + (isSelected ? "accountSelection-overlay--isSelected" : "")}></div>
+                    <div className="accountSelection-imageWrapper">
+                        <img src={store.getImage(node['account-type'])}/>
+                    </div>
+                    <input type="radio" name="account" onChange={this.handleAccountTypeChange.bind(this, node)} defaultChecked={node.name == Types[0].name} value={node['account-type']} />{node.name}
+                  </label>
+                )
+            }
+            selectAccount = (
+                <div className="accountForm">
+                    <h3 className="accountForm-title">Select Account Type</h3>
+                    <div className="select-type accountForm-content" >
+                        {selectAccountStack}
+                    </div>
+                </div>
+            );
+        } else {
+            selectAccount = null
+        }
+
+        //Cloud Account: SDN Account Option
+        let sdnAccounts = null;
+        if( (AccountType == 'cloud') ) {
+            if ( !isEdit && (this.state.sdnOptions.length > 1 )) {
+                sdnAccounts = (
+                    <div className="associateSdnAccount accountForm">
+                        <h3 className="accountForm-title">Associate SDN Account</h3>
+                        <div className="accountForm-content">
+                            <SelectOption  options={this.state.sdnOptions} onChange={this.handleSelectSdnAccount} />
+                        </div>
+
+                    </div>
+                );
+            }
+            if(isEdit && Account['sdn-account']) {
+                sdnAccounts = ( <div className="associateSdnAccount">SDN Account: {Account['sdn-account']} </div>)
+            }
+        }
+         //END Cloud Account: SDN Account Option
+         //
+        // This sections builds the parameters for the account details.
+        if (Account.params) {
+            var paramsStack = [];
+            var optionalField = '';
+            for (var i = 0; i < Account.params.length; i++) {
+                var node = Account.params[i];
+                var value = ""
+                if (Account[Account['account-type']]) {
+                    value = Account[Account['account-type']][node.ref]
+                }
+                if (this.props.edit && Account.params) {
+                    value = Account.params[node.ref];
+                }
+                paramsStack.push(
+                    <TextInput key={node.label} className="accountForm-input" label={node.label} required={!node.optional}  onChange={this.props.store.handleParamChange(node)} value={value} />
+                );
+            }
+
+            let nestedParamsStack = null;
+            if (Account.nestedParams) {
+                nestedParamsStack = [];
+                var optionalField = '';
+                for (var i = 0; i < Account.nestedParams.params.length; i++) {
+                    var node = Account.nestedParams.params[i];
+                    var value = ""
+                    if (Account[Account['account-type']] && Account.nestedParams && Account[Account['account-type']][Account.nestedParams['container-name']] && Account[Account['account-type']][Account.nestedParams['container-name']][node.ref]) {
+                        value = Account[Account['account-type']][Account.nestedParams['container-name']][node.ref];
+                    }
+                    if (node.optional) {
+                        optionalField = <span className="optional">Optional</span>;
+                    }
+                    // nestedParamsStack.push(
+                    //     <label key={node.label}>
+                    //       <label className="create-fleet-pool-params">{node.label} {optionalField}</label>
+                    //       <input className="create-fleet-pool-input" type="text" onChange={this.props.store.handleNestedParamChange(Account.nestedParams['container-name'], node)} value={value}/>
+                    //     </label>
+                    // );
+                    nestedParamsStack.push(
+                          <TextInput key={node.label} label={node.label} required={!node.optional} className="create-fleet-pool-input" type="text" onChange={this.props.store.handleNestedParamChange(Account.nestedParams['container-name'], node)} value={value}/>
+                    );
+                }
+            }
+
+            params = (
+                <li className="create-fleet-pool accountForm">
+                    <h3  className="accountForm-title"> {isEdit ? 'Update' : 'Enter'} Account Details</h3>
+                    <div className="accountForm-content">
+                        {paramsStack}
+                        <div className="accountForm-nestedParams">
+                        {nestedParamsStack}
+                        </div>
+                    </div>
+                </li>
+            )
+        } else {
+            params = (
+                <li className="create-fleet-pool accountForm">
+                    <h3 className="accountForm-title"> {isEdit ? 'Update' : 'Enter'}</h3>
+                    <label style={{'marginLeft':'17px', color:'#888'}}>No Details Required</label>
+                </li>
+            )
+        }
+
+        // This section builds elements that only show up in the edit page.
+        if (isEdit) {
+            name = <label>{Account.name}</label>;
+            buttons = [
+                <Button key="2" onClick={this.handleDelete} className="light" label="Remove Account" />,
+                <Button key="3" onClick={this.cancel} className="light" label="Cancel" />,
+                <Button key="4" role="button" onClick={this.update.bind(this)} className="update dark" label="Update" />
+            ];
+            resfreshStatus = Account['connection-status'] ? (
+                <div className="accountForm">
+                    <div className="accountForm-title accountForm-title--edit">
+                        Connection Status
+                    </div>
+                    <div className="accountForm-content" style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+                        <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+                            <AccountConnectivityStatus status={Account['connection-status'].status} />
+                            {Account['connection-status'].status.toUpperCase()}
+                        </div>
+                            <Button className="refreshList light" onClick={this.props.store.refreshAccount.bind(this, Account.name, AccountType)} label="REFRESH STATUS"></Button>
+                    </div>
+                    {
+                        Account['connection-status'].status.toUpperCase() === 'FAILURE' ?
+                        displayFailureMessage(Account['connection-status'].details) : null
+                    }
+                </div>
+            ) : null;
+            // cloudResourcesStateHTML = (
+            //     <div className="accountForm">
+            //         <h3 className="accountForm-title">Resources Status</h3>
+            //         <div className="accountForm-content" >
+            //         <ul>
+            //             {
+            //                 cloudResources && props.AccountMeta.resources[Account['account-type']].map(function(r, i) {
+
+            //                     return (
+            //                         <li key={i}>
+            //                             {r}: {cloudResources[r]}
+            //                         </li>
+            //                     )
+            //                 }) || 'No Additional Resources'
+            //             }
+            //         </ul>
+            //         </div>
+            //     </div>
+            // )
+        }
+
+        var html = (
+
+              <form className="app-body create Accounts"  onSubmit={this.preventDefault} onKeyDown={this.evaluateSubmit}>
+                <div className="noticeSubText noticeSubText_right">
+                    * required
+                </div>
+                <div className="associateSdnAccount accountForm">
+                    <h3 className="accountForm-title">Account</h3>
+                    <div className="accountForm-content" style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+                        <h4 style={{flex: '1'}}>{name}</h4>
+                        { isEdit ?
+                            (
+                                <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+                                    <img src={store.getImage(Account['account-type'])}/> {props.AccountMeta.labelByType[Account['account-type']]}
+                                </div>)
+                            : null
+                        }
+                    </div>
+                </div>
+
+                  {selectAccount}
+                  {sdnAccounts}
+                  {resfreshStatus}
+                  {cloudResourcesStateHTML}
+                  <ol className="flex-row">
+                      {params}
+                  </ol>
+                  <div className="form-actions">
+                      {buttons}
+                  </div>
+              </form>
+        )
+        return html;
+    }
+}
+
+function displayFailureMessage(msg) {
+    return (
+        <div className="accountForm-content" style={{maxWidth: '600px'}}>
+            <div style={{paddingBottom: '1rem'}}>Details:</div>
+            <div>
+                {msg}
+            </div>
+
+        </div>
+    )
+}
+
+class SelectOption extends React.Component {
+  constructor(props){
+    super(props);
+  }
+  handleOnChange = (e) => {
+    this.props.onChange(JSON.parse(e.target.value));
+  }
+  render() {
+    let html;
+    html = (
+      <select className={this.props.className} onChange={this.handleOnChange}>
+        {
+          this.props.options.map(function(op, i) {
+            return <option key={i} value={JSON.stringify(op.value)}>{op.label}</option>
+          })
+        }
+      </select>
+    );
+    return html;
+  }
+}
+SelectOption.defaultProps = {
+  options: [],
+  onChange: function(e) {
+    console.dir(e)
+  }
+}
+
+function removeTrailingWhitespace(Account) {
+             var type = Account['account-type'];
+            var params = Account.params;
+
+            if(params) {
+                for (var i = 0; i < params.length; i++) {
+                    var param = params[i].ref;
+                    if(typeof(Account[type][param]) == 'string') {
+                        Account[type][param] = Account[type][param].trim();
+                    }
+                }
+            }
+
+            let nestedParams = Account.nestedParams;
+            if (nestedParams && nestedParams.params) {
+                for (let i = 0; i < nestedParams.params.length; i++) {
+                    let nestedParam = nestedParams.params[i].ref;
+                    let nestedParamValue = Account[type][nestedParams['container-name']][nestedParam];
+                    if (typeof(nestedParamValue) == 'string') {
+                        Account[type][nestedParams['container-name']][nestedParam] = nestedParamValue.trim();
+                    }
+                }
+            }
+            return Account;
+}
+
+export default SkyquakeComponent(Account)
diff --git a/skyquake/plugins/accounts/src/account/account.scss b/skyquake/plugins/accounts/src/account/account.scss
new file mode 100644 (file)
index 0000000..62cdf93
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+.Accounts {
+    -ms-flex: 1 1 100%;
+        flex: 1 1 100%;
+
+    .refreshStatus {
+        margin-left: 0.5rem;
+        padding: 1rem 0;
+
+        .currentStatus {
+            text-transform: uppercase;
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-line-pack:center;
+                align-content:center;
+        }
+        span.oi {
+            cursor: pointer;
+        }
+    }
+    .delete, .cancel {
+        cursor: pointer;
+    }
+    .associateSdnAccount {
+        margin: 1rem;
+    }
+    .create > .flex-row > li {
+        -ms-flex: 1 1 auto;
+            flex: 1 1 auto;
+        margin: 0 .25rem;
+    }
+    .create > .flex-row > li:first-child {
+        margin-left: .5rem;
+    }
+    .create > .flex-row > li:last-child {
+        margin-right: .5rem;
+    }
+    /* .flex-row > li h3 {*/
+    /*     background-color: #ffffff;*/
+    /*     padding: 12px 18px;*/
+    /*     text-transform: uppercase;*/
+    /* }*/
+    .create .options {
+        -ms-flex-wrap: wrap;
+            flex-wrap: wrap;
+        text-align: center;
+        margin: 24px auto;
+        width: 90%;
+        flex-wrap: wrap;
+        margin: 24px auto;
+        width: 90%;
+        -ms-flex-pack: start;
+            justify-content: flex-start;
+    }
+    .create .options a {
+        background-color: #ffffff;
+        -ms-flex: 0 1 32%;
+            flex: 0 1 32%;
+        margin: 0 4px 4px 0;
+        padding: 4px;
+        box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+    }
+    .create .options a h5 {
+        font-size: 10px;
+        margin: 5px 0 0 5px;
+        text-align: left;
+    }
+    .create .options a img {
+        margin-top: 10px;
+        width: 70%;
+    }
+    .list-pools {
+        padding: 24px;
+    }
+    .list-pools li a {
+        background-color: #ffffff;
+        display: block;
+        font-size: 12px;
+        margin-bottom: 24px;
+        padding: 12px;
+        text-align: center;
+        box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+    }
+    .list-pools li h4 {
+        text-align: left;
+    }
+    .list-pools li img {
+        margin-top: 24px;
+        width: 65%;
+    }
+    .form-actions {
+        clear: both;
+        margin-top: 36px;
+        text-align: center;
+    }
+    .form-actions a {
+        color: #000000;
+        display: inline-block;
+        font-size: 12px;
+        padding: 8px 64px;
+        text-decoration: none;
+        text-transform: uppercase;
+        box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+    }
+    .form-actions a.save {
+        background-color: #ffffff;
+        border: 1px solid #cccccc;
+        border-top: 0;
+        cursor: pointer;
+        margin-right: 48px;
+    }
+    .form-actions a.launch {
+        background-color: #333333;
+        border: 1px solid #000000;
+        border-top: 0;
+        color: #ffffff;
+    }
+    .form-actions a.launch:hover, .form-actions a.launch:active {
+        background: #00acee;
+        color: #ffffff;
+    }
+    .create .select-type {
+        margin: 0.5rem;
+    }
+    /* .create-fleet-pool label {*/
+    /*     padding: 0.125rem;*/
+    /*     display: block;*/
+    /* }*/
+    /* .create-fleet-pool input {*/
+    /*     width: 350px;*/
+    /*     height: 35px;*/
+    /*     margin: 0px 20px 10px 15px;*/
+    /*     box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;*/
+    /*     font-size: 20px;*/
+    /* }*/
+    .create .optional {
+        font-style: italic;
+    }
+    .name-input input {
+      background:white !important;
+      box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+      display: block;
+      font-size: 120%;
+      height: 35px;
+      margin: 0;
+      margin-top: 0.25rem;
+      width: 350px;
+    }
+    .select-type {
+        display:-ms-flexbox;
+        display:flex;
+    }
+    .accountSelection {
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex:0 1;
+            flex:0 1;
+        position:relative;
+        -ms-flex-direction:column;
+        flex-direction:column;
+        margin-right:0.5rem;
+        -ms-flex-align:center;
+        align-items:center;
+        border-top:$gray-light 1px solid;
+        border-left:$gray-light 1px solid;
+        border-right:$gray-dark 1px solid;
+        border-bottom:$gray-dark 1px solid;
+        box-shadow: $gray 2px 2px 3px;
+        cursor:pointer;
+        background:white;
+        &:last-child {
+            margin-right:0;
+        }
+
+        input[type="radio"] {
+            opacity: 0.01;
+            position:absolute;
+            top:0;
+        }
+        &-imageWrapper {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-direction:column;
+                flex-direction:column;
+            margin:0.5rem;
+            padding:0.25rem;
+            background:white;
+            width:100px;
+            height:50px;
+            -ms-flex-align:center;
+                align-items:center;
+            -ms-flex-pack:center;
+                justify-content:center;
+            img{
+                max-width:100px;
+                max-height:50px;
+            }
+        }
+        span {
+            padding-bottom:0.5rem;
+        }
+        &-overlay {
+            position:absolute;
+            top:0;
+            left:0;
+            right:0;
+            bottom:0;
+            height:100%;
+            width:100%;
+            background: rgba(0, 0, 0, 0.25);
+            opacity: 0.2;
+        }
+        &--isSelected{
+            border-bottom:$gray-light 1px solid;
+            border-right:$gray-light 1px solid;
+            border-top:$gray-dark 1px solid;
+            border-left:$gray-dark 1px solid;
+            box-shadow: $gray 2px 2px 3px inset;
+        }
+    }
+    .accountForm {
+        margin:0.5rem 0;
+        width:100%;
+        background: $gray-lighter;
+        &-title {
+            background-color: #ffffff;
+            padding: 12px 0.5rem;
+            text-transform: uppercase;
+            &--edit {
+                display:-ms-flexbox;
+                display:flex;
+                -ms-flex-pack:justify;
+                    justify-content:space-between;
+                -ms-flex-align: center;
+                    align-items: center;
+                >div {
+                    display:-ms-flexbox;
+                    display:flex;
+                    -ms-flex-align:center;
+                        align-items:center;
+                }
+            }
+        }
+        img {
+            height:2rem;
+            margin:0 0.5rem;
+        }
+        &-content {
+            padding:0.5rem;
+        }
+        &-nestedParams {
+            display:-ms-flexbox;
+            display:flex;
+            > label {
+                margin-right:0.5rem;
+            }
+            > label:last-child {
+                margin-right:0rem;
+            }
+
+        }
+    }
+    .connectivityStatus {
+        display:block;
+        border:1px solid $lightest-gray;
+        border-radius:50%;
+        width:0.5rem;
+        height:0.5rem;
+        margin-right: 0.25rem;
+        margin-top: 0;
+        background:$lightest-gray;
+        &--success {
+            background:$brand-green;
+        }
+        &--failure {
+            background:$error-red;
+        }
+    }
+    .refreshList {
+        padding: 0.5rem;
+        margin: 0;
+        cursor: pointer;
+        text-transform:uppercase;
+    }
+}
diff --git a/skyquake/plugins/accounts/src/account/accountActions.js b/skyquake/plugins/accounts/src/account/accountActions.js
new file mode 100644 (file)
index 0000000..d5111f4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+module.exports = function(Alt) {
+   return Alt.generateActions(
+                                       'openAccountSocketLoading',
+                                       'openAccountSocketSuccess',
+                                       'openAccountSocketError',
+                                       'refreshAllAccountsLoading',
+                                       'refreshAllAccountsSuccess',
+                                       'refreshAllAccountsError',
+                                       'refreshCloudAccountSuccess',
+                                       'refreshCloudAccountFail',
+                                       'createAccountSuccess',
+                                       'createAccountLoading',
+                                       'createAccountFail',
+                                       'deleteAccountSuccess',
+                                       'deleteAccountLoading',
+                                       'deleteAccountFail',
+                                       'viewAccount'
+                                       );
+}
diff --git a/skyquake/plugins/accounts/src/account/accountSource.js b/skyquake/plugins/accounts/src/account/accountSource.js
new file mode 100644 (file)
index 0000000..5fa7869
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import $ from 'jquery';
+var Utils = require('utils/utils.js');
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = require('utils/rw.js').getSearchParams(window.location).dev_mode || false;
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+
+module.exports = function(Alt) {
+    return {
+        openAccountsSocket: {
+          remote: function(state) {
+            return new Promise(function(resolve, reject) {
+              //If socket connection already exists, eat the request.
+              if(state.socket) {
+                return resolve(false);
+              }
+               $.ajax({
+                url: '//' + window.location.hostname + ':' + NODE_PORT + '/socket-polling?api_server=' + API_SERVER ,
+                type: 'POST',
+                beforeSend: Utils.addAuthorizationStub,
+                data: {
+                  url:window.location.protocol + '//' + window.location.host + '/accounts/all?api_server=' + API_SERVER
+                },
+                success: function(data, textStatus, jqXHR) {
+                  Utils.checkAndResolveSocketRequest(data, resolve, reject);
+                }
+              }).fail(function(xhr){
+                //Authentication and the handling of fail states should be wrapped up into a connection class.
+                Utils.checkAuthentication(xhr.status);
+              });;
+            });
+          },
+          loading: Alt.actions.global.openAccountSocketLoading,
+          success: Alt.actions.global.openAccountSocketSuccess,
+          error: Alt.actions.global.openAccountSocketError
+        },
+        refreshAll: {
+            remote: function(state, accounts) {
+                return new Promise(function(resolve, reject) {
+                    let Refreshing = syncRefresh();
+                    Refreshing.next();
+                    function* syncRefresh() {
+                        for (let t of accounts) {
+                            if (t.data.constructor.name == "Array") {
+                               for (let u of t.data) {
+                                  console.log('Refreshing: ' + u.name);
+                                  yield refreshStatus(t.type, u.name);
+                               }
+                            }
+                        }
+                        resolve({})
+                    }
+
+                    function refreshStatus(type, name) {
+                        let url = type + '/' + name + '/refresh?api_server=' + API_SERVER;
+                        setTimeout(function(){
+                          Refreshing.next();
+                        },100);
+                        $.ajax({
+                            url: url,
+                            type: 'POST',
+                            beforeSend: Utils.addAuthorizationStub,
+                            success: function() {
+
+                            },
+                            error: function() {
+                            }
+                          });
+
+                    }
+                })
+            },
+          loading: Alt.actions.global.refreshAllAccountsLoading,
+          success: Alt.actions.global.refreshAllAccountsSuccess,
+          error: Alt.actions.global.refreshAllAccountsError
+        },
+        refreshAccount: {
+          remote: function(state, name, type) {
+            return new Promise(function(resolve, reject) {
+              $.ajax({
+                url: type + '/' + name + '/refresh?api_server=' + API_SERVER,
+                type: 'POST',
+                beforeSend: Utils.addAuthorizationStub,
+                success: function(account) {
+                  resolve(account);
+                }
+              });
+            });
+          },
+          success: Alt.actions.global.refreshCloudAccountSuccess,
+          error: Alt.actions.global.refreshCloudAccountFail
+        },
+        create: {
+          remote: function(state, account, type, cb) {
+            delete account['connection-status'];
+            return new Promise(function(resolve, reject) {
+              $.ajax({
+                url: type + '?api_server=' + API_SERVER,
+                type:'POST',
+                beforeSend: Utils.addAuthorizationStub,
+                data: JSON.stringify(account),
+                contentType: "application/json",
+                success: function(data) {
+                  resolve({data, cb});
+                },
+                error: function(error) {
+                  console.log("There was an error creating the account: ", arguments);
+
+                }
+              }).fail(function(xhr){
+                //Authentication and the handling of fail states should be wrapped up into a connection class.
+                Utils.checkAuthentication(xhr.status);
+                reject();
+              });
+
+            });
+          },
+          success: Alt.actions.global.createAccountSuccess,
+          loading: Alt.actions.global.createAccountLoading,
+          error: Alt.actions.global.createAccountFail
+      },
+        update: {
+          remote: function(state, account, type, cb) {
+            var payload = Object.assign({}, account);
+            delete payload['connection-status'];
+            delete payload['params'];
+            delete payload['pools'];
+            (
+              (payload.nestedParams == null) &&
+              delete payload.nestedParams
+            ) ||
+            (
+              payload.nestedParams &&
+              payload.nestedParams['container-name'] &&
+              delete payload[payload.nestedParams['container-name']] &&
+              delete payload.nestedParams
+            );
+
+
+            return new Promise(function(resolve, reject) {
+              $.ajax({
+                url: type + '/' + account.name + '?api_server=' + API_SERVER,
+                type:'PUT',
+                beforeSend: Utils.addAuthorizationStub,
+                data: JSON.stringify(payload),
+                contentType: "application/json",
+                success: function(data) {
+                  resolve({data, cb});
+                },
+                error: function(error) {
+                  console.log("There was an error updating the account: ", arguments);
+
+                }
+              }).fail(function(xhr){
+                //Authentication and the handling of fail states should be wrapped up into a connection class.
+                Utils.checkAuthentication(xhr.status);
+                reject('error');
+              });
+
+            });
+          },
+          interceptResponse: interceptResponse({
+            'error': 'There was an error updating the account.'
+          }),
+          success: Alt.actions.global.createAccountSuccess,
+          loading: Alt.actions.global.createAccountLoading,
+          error: Alt.actions.global.showNotification
+      },
+        delete: {
+          remote: function(state, type, name, cb) {
+            return new Promise(function(resolve, reject) {
+              $.ajax({
+                url: type + '/' + name + '/?api_server=' + API_SERVER,
+                type:'DELETE',
+                dataType : 'html',
+                beforeSend: Utils.addAuthorizationStub,
+                success: function(data) {
+                  console.log('Account deleted');
+                  resolve(data);
+                }
+              }).fail(function(xhr){
+                //Authentication and the handling of fail states should be wrapped up into a connection class.
+                Utils.checkAuthentication(xhr.status);
+                reject('error');
+              });
+            })
+          },
+          interceptResponse: interceptResponse({
+            'error': 'Something went wrong while trying to delete the account. Check the error logs for more information' }),
+          success: Alt.actions.global.deleteAccountSuccess,
+          loading: Alt.actions.global.deleteAccountLoading,
+          error: Alt.actions.global.showNotification
+      }
+    }
+}
+
+function interceptResponse (responses) {
+  return function(data, action, args) {
+    if(responses.hasOwnProperty(data)) {
+      return {
+        type: data,
+        msg: responses[data]
+      }
+    } else {
+      return data;
+    }
+  }
+}
diff --git a/skyquake/plugins/accounts/src/account/accountStore.js b/skyquake/plugins/accounts/src/account/accountStore.js
new file mode 100644 (file)
index 0000000..f6e2ef1
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import AccountActions from './accountActions.js';
+import AccountSource from './accountSource.js';
+
+
+var rw = require('utils/rw.js');
+var altImage = rw.getSearchParams(window.location).alt_image;
+
+let Params = {
+    //Config Agent
+    ConfigAgent: {
+
+    }
+}
+
+
+
+let AccountMeta = {
+    'config-agent': {
+
+        defaultType: 'juju',
+        params: {
+            "juju": [{
+                label: "IP Address",
+                ref: 'ip-address'
+                }, {
+                    label: "Port",
+                    ref: 'port',
+                    optional: true
+                }, {
+                    label: "Username",
+                    ref: 'user',
+                    optional: true
+                }, {
+                    label: "Secret",
+                    ref: 'secret',
+                    optional: true
+            }]
+        },
+        types: [{
+            "name": "JUJU",
+            "account-type": "juju",
+        }]
+    },
+    'sdn': {
+        defaultType: 'odl',
+        params: {
+            "odl": [{
+                label: "Username",
+                ref: 'username'
+            }, {
+                label: "Password",
+                ref: 'password'
+            }, {
+                label: "URL",
+                ref: 'url'
+            }]
+        },
+        types: [{
+            "name": "ODL",
+            "account-type": "odl",
+        }]
+    },
+    'cloud': {
+        defaultType: 'openstack',
+        params: {
+            "aws": [{
+                label: "Key",
+                ref: 'key'
+            }, {
+                label: "Secret",
+                ref: 'secret'
+            }, {
+              label: "Availability Zone",
+              ref: 'availability-zone'
+            }, {
+              label: "Default Subnet ID",
+              ref: 'default-subnet-id'
+            }, {
+              label: "Region",
+              ref: 'region'
+            }, {
+              label: "VPC ID",
+              ref: 'vpcid'
+            }, {
+              label: "SSH Key",
+              ref: 'ssh-key'
+            }],
+            "cloudsim_proxy": [{
+                label: "Host",
+                ref: "host"
+            }],
+            "openstack": [{
+                label: "Key",
+                ref: 'key'
+            }, {
+                label: "Secret",
+                ref: 'secret'
+            }, {
+                label: "Authentication URL",
+                ref: 'auth_url'
+            }, {
+                label: "Tenant",
+                ref: 'tenant'
+            }, {
+                label: 'Management Network',
+                ref: 'mgmt-network'
+            }, {
+                label: 'Floating IP Pool',
+                ref: 'floating-ip-pool',
+                optional: true
+            }],
+            "openmano": [{
+                label: "Host",
+                ref: 'host'
+            }, {
+                label: "Port",
+                ref: 'port'
+            }, {
+                label: "Tenant ID",
+                ref: 'tenant-id'
+            }],
+            "openvim": [{
+                label: "Host",
+                ref: 'host'
+            }, {
+                label: "Tenant Name",
+                ref: 'tenant-name'
+            }, {
+                label: 'Management Network',
+                ref: 'mgmt-network'
+            }, {
+                label: "Port",
+                ref: 'port',
+                optional: true
+            }]
+        },
+        nestedParams: {
+            "openvim": {
+                "container-name": "image-management",
+                "label": "Image Management",
+                "params": [{
+                    label: "Username",
+                    ref: 'username'
+                }, {
+                    label: "Password",
+                    ref: 'password'
+                }, {
+                    label: 'Image Directory Path',
+                    ref: 'image-directory-path',
+                    optional: true
+                }]
+            }
+        },
+        types: [{
+            "name": "OpenStack",
+            "account-type": "openstack"
+        }, {
+            "name": "Cloudsim",
+            "account-type": "cloudsim_proxy"
+        }, {
+            "name": "Open Mano",
+            "account-type": "openmano"
+        }, {
+            "name": "AWS",
+            "account-type": "aws"
+        }, {
+            "name": "Open VIM",
+            "account-type": "openvim"
+        }]
+    },
+    resources: {
+    },
+    image: {
+        "aws": require("../../images/aws.png"),
+        "openmano": altImage || require("../../images/openmano.png"),
+        "openvim": require("../../images/openmano.png"),
+        "openstack": require("../../images/openstack.png"),
+        "cloudsim_proxy": require("../../images/riftio.png"),
+        "odl": require("../../images/OpenDaylight_logo.png"),
+        "juju": require("../../images/juju.svg")
+
+    },
+    labelByType: {
+        "aws": "AWS",
+        "openmano": "OpenStack",
+        "openvim": "Open VIM",
+        "openstack": "OpenStack",
+        "cloudsim_proxy": "Cloudsim"
+    }
+}
+
+export default class AccountStore {
+    constructor() {
+        this.cloud = [];
+        this['config-agent'] = [];
+        this.sdn = [];
+        this.account = null;
+        this.types = [];
+        this.refreshingAll = false;
+        this.sdnOptions = [];
+        this.AccountMeta = AccountMeta;
+        this.bindActions(AccountActions(this.alt));
+        this.registerAsync(AccountSource);
+        this.exportPublicMethods({
+            closeSocket:this.closeSocket,
+            setAccountTemplate: this.setAccountTemplate,
+            handleParamChange: this.handleParamChange,
+            handleNameChange: this.handleNameChange,
+            handleAccountTypeChange: this.handleAccountTypeChange,
+            updateAccount: this.updateAccount,
+            viewAccount: this.viewAccount,
+            handleNestedParamChange: this.handleNestedParamChange,
+            getImage: this.getImage
+        })
+    }
+    refreshAllAccountsSuccess = () => {
+        this.setState({
+            refreshingAll: false
+        });
+    }
+    refreshAllAccountsLoading = () => {
+        this.setState({
+            refreshingAll: true
+        });
+    }
+    refreshAllAccountsError = () => {
+
+    }
+    refreshCloudAccountFail = () => {
+        console.log(this);
+    }
+    refreshCloudAccountSuccess = () => {
+
+    }
+    deleteAccountSuccess = (response) => {
+        this.setState({
+            currentAccount: false,
+            account: {}
+        });
+    }
+    openAccountSocketSuccess = (connection) => {
+        let self = this;
+        let  ws = window.multiplexer.channel(connection);
+
+        if (!connection) return;
+        this.setState({
+            socket: ws.ws,
+            channelId: connection
+        });
+        ws.onmessage = (socket) => {
+            try {
+                var data = JSON.parse(socket.data);
+                let SdnOptions = [{
+                    label: 'Select an SDN Account',
+                    value: false
+                }];
+                SdnOptions = SdnOptions.concat(this.generateOptionsByName(data.sdn.data))
+                var newState = {
+                    cloud: data.cloud.data,
+                    'config-agent': data['config-agent'].data,
+                    sdn: data.sdn.data,
+                    sdnOptions: SdnOptions
+                };
+
+                //If account is selected, updated connection status only
+                if(self.currentAccount) {
+                    let Account = self.getAccountFromStream(data[self.currentAccount.type].data, self.currentAccount.name);
+                    newState.account = self.account;
+                    newState.account['connection-status'] = Account['connection-status']
+                }
+                self.setState(newState)
+            } catch(error) {
+                console.log('Hit at exception in openAccountSocketSuccess', error)
+            }
+
+        }
+        ws.onclose = () => {
+            self.closeSocket();
+        }
+    }
+    closeSocket = () => {
+        if (this.socket) {
+            window.multiplexer.channel(this.channelId).close();
+        }
+        this.setState({
+            socket: null
+        })
+    }
+    setAccountTemplate = (AccountType, type) => {
+        let account = {
+            name: '',
+            'account-type': type || AccountMeta[AccountType].defaultType,
+            params: AccountMeta[AccountType].params[AccountMeta[AccountType].defaultType],
+            nestedParams: AccountMeta[AccountType].nestedParams ? AccountMeta[AccountType].nestedParams[AccountMeta[AccountType].defaultType]:null,
+            'connection-status': {
+                status: ''
+            }
+        };
+
+        account[type || AccountMeta[AccountType].defaultType] = {}
+        this.setState({
+            account: account,
+            accountType: AccountType,
+            types: AccountMeta[AccountType].types,
+            currentAccount: null
+        })
+    }
+    getAccountFromStream(data, name) {
+        let result = null;
+        data.map(function(a) {
+            if(a.name == name) {
+                result = a;
+            }
+        });
+        return result;
+    }
+    viewAccount = ({type, name}) => {
+        var data = null;
+        var accounts = null;
+        if(this && this[type].length) {
+            accounts = this[type];
+            data = this.getAccountFromStream(accounts, name);
+            if(data) {
+                let accountParams = {
+                    params: AccountMeta[type].params[data['account-type']]
+                };
+
+                let accountNestedParams = {
+                    nestedParams: AccountMeta[type].nestedParams?AccountMeta[type].nestedParams[data['account-type']]:null
+                };
+
+                this.setState({
+                    currentAccount: {type, name},
+                    account: Object.assign(data, accountParams, accountNestedParams),
+                    accountType: type
+                })
+            }
+        }
+    }
+    generateOptionsByName(data) {
+        let results = [];
+        if (data.constructor.name == "Array") {
+          data.map(function(d) {
+              results.push({
+                  label: d.name,
+                  value: d.name
+              })
+          });
+        }
+        return results;
+    }
+    updateAccount = (account) => {
+        this.setState({account:account})
+    }
+    handleNameChange = (event) => {
+        var account = this.account;
+        account.name = event.target.value;
+        this.setState(
+             {
+                account:account
+             }
+        );
+    }
+    handleAccountTypeChange = (node, event) => {
+        var temp = {};
+        temp.name = this.account.name;
+        temp['account-type'] = event.target.value;
+        temp.params= AccountMeta[this.accountType].params[event.target.value];
+        temp.nestedParams = AccountMeta[this.accountType]?AccountMeta[this.accountType].nestedParams[event.target.value]:null;
+        temp[event.target.value] = {};
+        this.setState({
+            account: temp
+        });
+    }
+    handleParamChange(node, event) {
+        return function(event) {
+            var account = this.state.account;
+            account[account['account-type']][node.ref] = event.target.value;
+            account.params[node.ref] = event.target.value;
+            this.updateAccount(account);
+        }.bind(this);
+    }
+    handleNestedParamChange(containerName, node, event) {
+        return function(event) {
+            var account = this.state.account;
+            account[account['account-type']][containerName] = account[account['account-type']][containerName] || {};
+            account[account['account-type']][containerName][node.ref] = event.target.value;
+            account[containerName] = account[containerName] || {};
+            account[containerName].params = account[containerName].params || {};
+            account[containerName].params[node.ref] = event.target.value;
+            this.updateAccount(account);
+        }.bind(this);
+    }
+    getImage = (type) => {
+        return AccountMeta.image[type];
+    }
+}
+
+
+/**
+ *Cloud
+ *
+ * {"name":"eng2","account-type":"openstack","openstack":{"key":"lmaultsb","secret":"mypasswd","auth_url":"http://engstack.eng.riftio.com:5000/v3/","tenant":"lmaultsb","mgmt-network":"private"}}
+Name
+Path
+
+
+SDN
+
+
+ *
+ *
+ */
diff --git a/skyquake/plugins/accounts/src/account/accountsDashboard.jsx b/skyquake/plugins/accounts/src/account/accountsDashboard.jsx
new file mode 100644 (file)
index 0000000..c0e0680
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import AppHeader from 'widgets/header/header.jsx';
+import AccountStore from './accountStore.js';
+import AccountSidebar from '../account_sidebar/accountSidebar.jsx';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import 'style/layout.scss';
+
+class AccountsDashboard extends React.Component {
+    constructor(props) {
+        super(props);
+        this.Store = this.props.flux.stores.hasOwnProperty('AccountStore') ? this.props.flux.stores.AccountStore : this.props.flux.createStore(AccountStore);
+        this.state = this.Store.getState();
+    }
+    componentWillMount() {
+        this.Store.listen(this.updateState);
+        this.Store.openAccountsSocket();
+    }
+    componentWillUnmount() {
+        this.Store.closeSocket();
+        this.Store.unlisten(this.updateState);
+    }
+    updateState = (state) => {
+        this.setState(state);
+    }
+    render() {
+        let self = this;
+        let html;
+        html = (<div className="launchpad-account-dashboard content-wrapper">
+                    <div className="flex">
+                      <AccountSidebar {...this.state} store={this.Store}/>
+                      <div>
+                        { this.props.children ? React.cloneElement(this.props.children, {store: self.Store, ...self.state}) : 'Edit or Create New Accounts'
+                        }
+                      </div>
+                    </div>
+              </div>);
+        return html;
+    }
+}
+AccountsDashboard.contextTypes = {
+    router: React.PropTypes.object
+};
+
+export default SkyquakeComponent(AccountsDashboard);
diff --git a/skyquake/plugins/accounts/src/account_sidebar/accountSidebar.jsx b/skyquake/plugins/accounts/src/account_sidebar/accountSidebar.jsx
new file mode 100644 (file)
index 0000000..ee86a7b
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './accountSidebar.scss';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import AccountStore from '../account/accountStore.js';
+import { Link } from 'react-router';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import Button from 'widgets/button/rw.button'
+class AccountSidebar extends React.Component{
+    constructor(props) {
+        super(props);
+        // this.props.store = this.props.flux.props.stores.hasOwnProperty('AccountStore') ? this.props.flux.props.stores.AccountStore : this.props.flux.createStore(AccountStore);
+        var self = this;
+        // this.props = this.props.store.getState();
+    }
+    listenerHandler = (state) => {
+        this.setState(state);
+    }
+    componentWillMount() {
+        // this.props.store.listen(this.listenerHandler);
+        // this.props.store.openAccountsSocket();
+    }
+    componentWillUnmount() {
+        // this.props.store.closeSocket();
+        // this.props.store.unlisten(this.listenerHandler);
+    }
+    render() {
+        let html;
+        let {store, ...props} = this.props;
+        //[this.props.cloud,this.props.sdn,this.props['config-agent']]
+        let AccountData = [
+            {
+                type: 'cloud',
+                data: this.props.cloud
+            },
+            {
+                type: 'sdn',
+                data: this.props.sdn
+            },
+            {
+                type: 'config',
+                data: this.props['config-agent']
+            }
+        ];
+        let refreshStatus = (<div>Check All Connectivity Status</div>)
+        let cloudAccounts = (this.props.cloud.length > 0) ? this.props.cloud.map(function(account, index) {
+            let status = null;
+            if (account) {
+                if (account['connection-status']) {
+                    status = account['connection-status'].status;
+                }
+                return (
+                    <DashboardCard  key={index} className='pool-card accountSidebarCard'>
+                    <header>
+                    <Link to={'accounts/cloud/' + account.name}>
+                            <div className="accountSidebarCard--content">
+                                <img className="accountSidebarCard--logo" src={store.getImage(account['account-type'])} />
+                                <h3 title="Edit Account">
+                                    {account.name}
+                                    <AccountConnectivityStatus status={status}/>
+                                </h3>
+                            </div>
+                    </Link>
+                    </header>
+                    </DashboardCard>
+                );
+            }
+        }) : null;
+        let sdnAccounts = (this.props.sdn && this.props.sdn.length > 0) ? this.props.sdn.map(function(account, index) {
+            let status = null;
+            if (account['connection-status']) {
+                status = account['connection-status'].status;
+            }
+            return (
+                <DashboardCard key={index} className='pool-card accountSidebarCard'>
+                     <header>
+                        <Link to={'accounts/sdn/' + account.name} title="Edit Account">
+                         <div className="accountSidebarCard--content">
+                            <h3>{account.name}<AccountConnectivityStatus status={status}/></h3>
+                        </div>
+                </Link>
+                    </header>
+                </DashboardCard>
+            )
+        }) : null;
+        let configAgentAccounts = (this.props['config-agent'].length > 0) ? this.props['config-agent'].map(function(account, index) {
+            let status = null;
+            if (account['connection-status']) {
+                status = account['connection-status'].status;
+            }
+            return (
+                <DashboardCard key={index} className='pool-card accountSidebarCard'>
+                <header>
+                    <Link to={'accounts/config-agent/' + account.name} title="Edit Account">
+                        <div className="accountSidebarCard--content">
+                            <img className="accountSidebarCard--logo" src={store.getImage(account['account-type'])} />
+                            <h3 title="Edit Account">
+                                {account.name}
+                                <AccountConnectivityStatus status={status}/>
+                            </h3>
+                        </div>
+                    </Link>
+                </header>
+                </DashboardCard>
+            )
+        }) : null;
+        html = (
+            <div className='accountSidebar'>
+                 <Button className="refreshList light" onClick={this.props.store.refreshAll.bind(this, AccountData)} label={this.props.refreshingAll ? 'Checking Connectivity Status...' : refreshStatus}></Button>
+                <h1>VIM Accounts</h1>
+                {cloudAccounts}
+                <DashboardCard className="accountSidebarCard">
+                        <Link
+                        to={{pathname: '/accounts/cloud/create'}}
+                        title="Create Cloud Account"
+                        className={'accountSidebarCard_create'}
+                    >
+                            Add VIM Account
+                            <img src={require("style/img/launchpad-add-fleet-icon.png")}/>
+                        </Link>
+                </DashboardCard>
+                <h1>SDN Accounts</h1>
+                {sdnAccounts}
+                <DashboardCard className="accountSidebarCard">
+                        <Link
+                        to={{pathname: '/accounts/sdn/create'}}
+                        title="Create Sdn Account"
+                        className={'accountSidebarCard_create'}
+                    >
+                            Add SDN Account
+                            <img src={require("style/img/launchpad-add-fleet-icon.png")}/>
+                        </Link>
+                </DashboardCard>
+                <h1>Config Agent Accounts</h1>
+                {configAgentAccounts}
+                <DashboardCard className="accountSidebarCard">
+                    <Link
+                        to={{pathname: '/accounts/config-agent/create'}}
+                        title="Create Config Agent Account"
+                        className={'accountSidebarCard_create'}
+                    >
+                            Add Config Agent Account
+                            <img src={require("style/img/launchpad-add-fleet-icon.png")}/>
+                        </Link>
+                </DashboardCard>
+            </div>
+                );
+        return html;
+    }
+}
+
+AccountSidebar.defaultProps = {
+    cloud: [],
+    sdn: [],
+    'config-agent': []
+}
+
+
+export class AccountConnectivityStatus extends React.Component {
+    render(){
+        return <span className={'connectivityStatus ' + 'connectivityStatus--' + this.props.status + ' ' + this.props.className} title={this.props.status}></span>
+    }
+}
+AccountConnectivityStatus.defaultProps = {
+    status: 'failed'
+}
+
+export default SkyquakeComponent(AccountSidebar);
diff --git a/skyquake/plugins/accounts/src/account_sidebar/accountSidebar.scss b/skyquake/plugins/accounts/src/account_sidebar/accountSidebar.scss
new file mode 100644 (file)
index 0000000..cf25899
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'style/_colors.scss';
+.accountSidebar {
+    -ms-flex:1 1 100%;
+        flex:1 1 100%;
+    max-width:300px;
+    h1 {
+      margin-left:1rem;
+    }
+    a {
+        text-decoration:none;
+                color:inherit;
+                width:100%;
+    }
+    .accountSidebarCard {
+        width:auto;
+        height:auto;
+        background:inherit;
+        header {
+            background:white;
+            padding-left:0.5rem;
+            display:-ms-flexbox;
+            display:flex;
+                -ms-flex-align:start;
+                    align-items:flex-start;
+            text-transform:uppercase;
+            h3 {
+                display:-ms-flexbox;
+                display:flex;
+                -ms-flex:1;
+                    flex:1;
+                -ms-flex-pack:justify;
+                    justify-content:space-between;
+                -ms-flex-align: center;
+                    align-items: center;
+                 padding-left:0.5rem;
+            }
+        }
+        &--content {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-pack:start;
+            justify-content:flex-start;
+            -ms-flex-align: center;
+                align-items: center;
+            height:70px;
+        }
+        &--logo{
+            max-width:50px;
+            max-height:50px;
+        }
+        .pool-card {
+            a:before {
+                text-align: center;
+                font-size: 0.575rem;
+                border: 1px solid black;
+                border-radius: 4px;
+                padding: 0.25rem 0.425rem 0.25rem 0.25rem;
+                height: 0.625rem;
+                width: 0.625rem;
+                margin-right: 0.25rem;
+            }
+            a:nth-child(even) {
+                background-color: $lightest-gray;
+            }
+            a.link-item {
+                background-color: $dark-gray;
+                display: -ms-flexbox;
+                display: flex;
+                -ms-flex-direction: row;
+                    flex-direction: row;
+                padding: 1rem;
+                -ms-flex-pack: start;
+                    justify-content: flex-start;
+                text-decoration: none;
+                color: black;
+            }
+            a.empty-pool {
+                margin-top:0.125rem;
+                display:-ms-flexbox;
+                display:flex;
+                -ms-flex-pack: justify;
+                    justify-content: space-between;
+                img {
+                    height:1rem;
+                }
+            }
+            a.vm:before {
+                content: 'VM';
+            }
+            a.network:before {
+                content: 'NT';
+            }
+            a.port:before {
+                content: 'PT';
+            }
+        }
+        h2.create-title {
+                font-size: 0.85rem;
+                text-transform:uppercase;
+                padding: 0px;
+                background-color:inherit
+        }
+        &_create {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-pack:justify;
+                justify-content:space-between;
+            padding:1rem;
+            font-size: 0.85rem;
+            text-transform:uppercase;
+            font-weight:bold;
+            background-color: $gray-light;
+            img {
+                height:1rem;
+            }
+        }
+    }
+    .connectivityStatus {
+        border:1px solid $lightest-gray;
+        border-radius:50%;
+        width:0.5rem;
+        height:0.5rem;
+        margin-right:1rem;
+        background:$lightest-gray;
+        &--success {
+            background:$brand-green;
+        }
+        &--failure {
+            background:$error-red;
+        }
+    }
+    .refreshList {
+        margin-left: 1rem;
+        margin-bottom:1rem;
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-align:center;
+        align-items:center;
+        padding: 0.5rem;
+        cursor: pointer;
+        text-transform:uppercase;
+    }
+}
diff --git a/skyquake/plugins/accounts/src/main.js b/skyquake/plugins/accounts/src/main.js
new file mode 100644 (file)
index 0000000..5dc626f
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+import "babel-polyfill";
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/accounts/webpack.production.config.js b/skyquake/plugins/accounts/webpack.production.config.js
new file mode 100644 (file)
index 0000000..3984a58
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+var CommonsPlugin = new require("webpack/lib/optimize/CommonsChunkPlugin")
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /react-treeview/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass?includePaths[]='+ path.resolve(frameworkPath)
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="app"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/composer/CMakeLists.txt b/skyquake/plugins/composer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9db080f
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  composer
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/composer/composer-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/composer/composer-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/composer/Gruntfile.js b/skyquake/plugins/composer/Gruntfile.js
new file mode 100644 (file)
index 0000000..a5a1736
--- /dev/null
@@ -0,0 +1,169 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+var mountFolder = function (connect, dir) {
+    return connect.static(require('path').resolve(dir));
+};
+
+var webpackDistConfig = require('./webpack.dist.config.js'),
+    webpackDevConfig = require('./webpack.config.js');
+
+module.exports = function (grunt) {
+    // Let *load-grunt-tasks* require everything
+    require('load-grunt-tasks')(grunt);
+
+    // Read configuration from package.json
+    var pkgConfig = grunt.file.readJSON('package.json');
+
+    grunt.initConfig({
+        pkg: pkgConfig,
+
+               version: {
+                       project: {
+                               src: ['package.json']
+                       },
+                       src: {
+                               options: {
+                                       prefix: 'semver '
+                               },
+                               src: ['src/**/*.js']
+                       }
+               },
+
+        webpack: {
+            options: webpackDistConfig,
+            dist: {
+                cache: false
+            }
+        },
+
+        'webpack-dev-server': {
+            options: {
+                hot: true,
+                port: 9000,
+                webpack: webpackDevConfig,
+                publicPath: '/assets/',
+                contentBase: './<%= pkg.src %>/'
+            },
+
+            start: {
+                keepAlive: true
+            }
+        },
+
+        connect: {
+            options: {
+                port: 9000
+            },
+
+            dist: {
+                options: {
+                    keepalive: true,
+                    middleware: function (connect) {
+                        return [
+                            mountFolder(connect, pkgConfig.dist)
+                        ];
+                    }
+                }
+            }
+        },
+
+        open: {
+            options: {
+                delay: 500
+            },
+            dev: {
+                path: 'http://localhost:<%= connect.options.port %>/webpack-dev-server/'
+            },
+            dist: {
+                path: 'http://localhost:<%= connect.options.port %>/'
+            }
+        },
+
+        karma: {
+            unit: {
+                configFile: 'karma.conf.js'
+            }
+        },
+
+        copy: {
+            dist: {
+                files: [
+                    // includes files within path
+                    {
+                        flatten: true,
+                        expand: true,
+                        src: ['<%= pkg.src %>/*'],
+                        dest: '<%= pkg.dist %>/',
+                        filter: 'isFile'
+                                       },
+                                       {
+                                               flatten: true,
+                                               expand: true,
+                                               src: ['<%= pkg.src %>/images/*'],
+                                               dest: '<%= pkg.dist %>/images/'
+                                       },
+                                       {
+                                               flatten: true,
+                                               expand: true,
+                                               src: ['<%= pkg.src %>/images/logos/*'],
+                                               dest: '<%= pkg.dist %>/images/logos/'
+                                       },
+                                       {
+                                               flatten: true,
+                                               expand: true,
+                                               src: ['<%= pkg.src %>/assets/*'],
+                                               dest: '<%= pkg.dist %>/assets/'
+                    }
+                ]
+            }
+        },
+
+        clean: {
+            dist: {
+                files: [{
+                    dot: true,
+                    src: [
+                        '<%= pkg.dist %>'
+                    ]
+                }]
+            }
+        }
+    });
+
+    grunt.registerTask('serve', function (target) {
+        if (target === 'dist') {
+            return grunt.task.run(['build', 'open:dist', 'connect:dist']);
+        }
+
+        grunt.task.run([
+            'open:dev',
+            'webpack-dev-server'
+        ]);
+    });
+
+       grunt.registerTask('patch', ['version:project:patch', 'version:src', 'build:dist']);
+
+    grunt.registerTask('test', ['karma']);
+
+    grunt.registerTask('build', ['clean', 'copy', 'webpack']);
+
+    grunt.registerTask('default', []);
+};
diff --git a/skyquake/plugins/composer/README.md b/skyquake/plugins/composer/README.md
new file mode 100644 (file)
index 0000000..94bbe81
--- /dev/null
@@ -0,0 +1,46 @@
+RIFT.io UI
+===
+Currently this repo only contains one module.
+
+# Development Setup
+
+## Requirements
+
+```
+npm install -g babel
+npm install -g grunt
+```
+
+## Helpful
+
+```
+npm install -g yo
+npm install -g generator-react-webpack # https://github.com/newtriks/generator-react-webpack
+```
+
+# Build Steps
+
+```
+npm install
+grunt build:dist # production build
+grunt build      # dev build
+grunt test          # run tests
+```
+
+# Development Steps
+
+```
+grunt serve      # start webpack dev server source-maps
+grunt serve:dist # start dev server with dist runtime
+```
+
+## Known Issues
+`grunt serve:dist` fails for unknown reason. workaround use python -m SimpleHTTPServer 8099
+
+# Useful Libs
+
+• [http://numeraljs.com/](http://numeraljs.com)
+
+• [http://momentjs.com/docs/](http://momentjs.com/docs/)
+
+# How the code works see ./src/README.md
diff --git a/skyquake/plugins/composer/api/composer.js b/skyquake/plugins/composer/api/composer.js
new file mode 100644 (file)
index 0000000..d9dc5e2
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var request = require('request');
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var constants = require('../../../framework/core/api_utils/constants.js');
+var _ = require('underscore');
+var APIVersion = '/v1';
+var Composer = {};
+
+var DataCenters = {};
+// Catalog module methods
+Composer.get = function(req) {
+    var api_server = req.query['api_server'];
+    var results = {}
+    return new Promise(function(resolve, reject) {
+        Promise.all([
+            rp({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            }),
+            rp({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd?deep',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            }),
+            rp({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata?deep',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            })
+            // Not enabled for now
+            // rp({
+            //   uri: utils.confdPort(api_server) + '/api/config/pnfd-catalog/pnfd?deep',
+            //   method: 'GET',
+            //   headers: _.extend({},
+            //     constants.HTTP_HEADERS.accept.collection,
+            //     {
+            //       'Authorization': req.get('Authorization')
+            //     }),
+            //   forever: constants.FOREVER_ON,
+            // rejectUnauthorized: false,
+            //   resolveWithFullResponse: true
+            // })
+        ]).then(function(result) {
+            var response = [{
+                "id": "GUID-1",
+                "name": "RIFT.ware™ NS Descriptors Catalog",
+                "short-name": "rift.ware-nsd-cat",
+                "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+                "vendor": "RIFT.io",
+                "version": "",
+                "created-on": "",
+                "type": "nsd",
+                "meta": {
+                    "icon-svg": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22iso-8859-1%22%3F%3E%0A%3C!--%20Generator%3A%20Adobe%20Illustrator%2018.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200)%20%20--%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22connection-icon-1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2050%2050%22%20style%3D%22enable-background%3Anew%200%200%2050%2050%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%09%3Cpath%20d%3D%22M15%2030c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2020c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2040c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M19.007%2025.885l12.88%206.44-.895%201.788-12.88-6.44z%22%2F%3E%3Cpath%20d%3D%22M30.993%2015.885l.894%201.79-12.88%206.438-.894-1.79z%22%2F%3E%3C%2Fsvg%3E"
+                },
+                "descriptors": []
+            }, {
+                "id": "GUID-2",
+                "name": "RIFT.ware™ VNF Descriptors Catalog",
+                "short-name": "rift.ware-vnfd-cat",
+                "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+                "vendor": "RIFT.io",
+                "version": "",
+                "created-on": "",
+                "type": "vnfd",
+                "meta": {
+                    "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_3\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <g> <path d=\"M58.852,62.447l-4.662-1.033c-0.047-3.138-0.719-6.168-1.996-9.007l3.606-2.92c0.858-0.695,0.99-1.954,0.296-2.813 l-4.521-5.584c-0.334-0.413-0.818-0.675-1.346-0.731c-0.525-0.057-1.056,0.102-1.468,0.435L45.25,43.64v0 c-2.486-1.907-5.277-3.259-8.297-4.019v-4.458c0-1.104-0.896-2-2-2H27.77c-1.104,0-2,0.896-2,2v4.461 c-3.08,0.777-5.922,2.171-8.447,4.144l-3.545-2.82c-0.415-0.33-0.94-0.479-1.472-0.422c-0.527,0.06-1.009,0.327-1.339,0.743 l-4.472,5.623c-0.688,0.864-0.544,2.123,0.32,2.81l3.642,2.896v0c-1.25,2.848-1.895,5.88-1.916,9.011l-4.666,1.078 c-1.076,0.249-1.747,1.322-1.499,2.398l1.616,7.001c0.249,1.077,1.325,1.747,2.399,1.499l4.813-1.111v0 c1.429,2.681,3.344,5.017,5.691,6.943l-2.17,4.55c-0.476,0.997-0.054,2.19,0.943,2.666l6.484,3.094 c0.271,0.129,0.566,0.195,0.861,0.195c0.226,0,0.451-0.038,0.668-0.115c0.5-0.177,0.909-0.545,1.138-1.024l2.198-4.611 c2.923,0.563,5.966,0.554,8.879-0.033l2.236,4.585c0.484,0.994,1.685,1.403,2.675,0.921l6.456-3.148 c0.992-0.484,1.405-1.682,0.921-2.674l-2.206-4.524c2.335-1.946,4.231-4.301,5.639-6.999l4.812,1.067 c1.076,0.237,2.146-0.441,2.385-1.52l1.556-7.014c0.115-0.518,0.02-1.06-0.266-1.508C59.82,62.878,59.369,62.562,58.852,62.447z M40.18,61.761c0,4.859-3.953,8.812-8.813,8.812c-4.858,0-8.811-3.953-8.811-8.812s3.952-8.812,8.811-8.812 C36.227,52.949,40.18,56.902,40.18,61.761z\"/> <path d=\"M64.268,45.324c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.826,0.353,3.736,0.345,5.551-0.021l1.07,2.195 c0.484,0.992,1.682,1.405,2.675,0.921l2.691-1.313c0.477-0.233,0.842-0.646,1.015-1.147c0.172-0.501,0.139-1.051-0.095-1.528 l-1.052-2.155c1.458-1.214,2.645-2.686,3.527-4.377l2.278,0.504c1.075,0.238,2.146-0.442,2.386-1.52l0.647-2.923 c0.238-1.078-0.442-2.146-1.521-2.385l-2.184-0.484c-0.028-1.962-0.449-3.857-1.248-5.632l1.673-1.355 c0.412-0.334,0.675-0.818,0.73-1.345s-0.102-1.056-0.436-1.468l-1.884-2.327c-0.697-0.859-1.957-0.99-2.813-0.295l-1.614,1.307 c-1.554-1.193-3.299-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.04 c-1.927,0.486-3.703,1.358-5.28,2.592l-1.634-1.298c-0.862-0.687-2.12-0.543-2.81,0.32l-1.864,2.344 c-0.33,0.416-0.481,0.945-0.422,1.472c0.061,0.527,0.327,1.009,0.743,1.339l1.69,1.345c-0.78,1.779-1.184,3.676-1.197,5.636 l-2.189,0.505c-0.517,0.119-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51l0.675,2.918 c0.249,1.076,1.323,1.747,2.398,1.498l2.28-0.527c0.892,1.676,2.089,3.137,3.559,4.343l-1.035,2.17 c-0.228,0.479-0.257,1.028-0.08,1.528c0.178,0.5,0.546,0.91,1.024,1.138l2.703,1.289C63.686,45.261,63.979,45.324,64.268,45.324z M64.334,27.961c0-3.039,2.473-5.51,5.512-5.51c3.038,0,5.51,2.472,5.51,5.51c0,3.039-2.472,5.511-5.51,5.511 C66.807,33.472,64.334,31,64.334,27.961z\"/> <path d=\"M96.107,66.441l-2.182-0.484c-0.028-1.961-0.449-3.856-1.25-5.632l1.675-1.355c0.412-0.334,0.675-0.818,0.73-1.346 c0.056-0.527-0.102-1.056-0.436-1.468l-1.885-2.327c-0.695-0.859-1.956-0.99-2.813-0.295l-1.614,1.307 c-1.555-1.193-3.3-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.041 c-1.929,0.486-3.706,1.358-5.282,2.592l-0.001,0l-1.631-1.298c-0.415-0.331-0.938-0.482-1.472-0.422 c-0.527,0.06-1.009,0.327-1.339,0.742l-1.863,2.343c-0.688,0.865-0.544,2.123,0.32,2.811l1.691,1.345 c-0.782,1.784-1.186,3.68-1.199,5.636l-2.188,0.505c-0.517,0.12-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51 l0.675,2.918c0.249,1.076,1.327,1.744,2.397,1.498l2.281-0.526c0.893,1.677,2.09,3.138,3.558,4.343h0.001l-1.035,2.168 c-0.229,0.479-0.258,1.029-0.081,1.529c0.178,0.5,0.546,0.909,1.024,1.138l2.702,1.289c0.278,0.132,0.571,0.195,0.86,0.195 c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.828,0.353,3.739,0.347,5.552-0.021l1.071,2.194 c0.484,0.992,1.682,1.405,2.675,0.921l2.69-1.312c0.477-0.233,0.842-0.645,1.014-1.147c0.173-0.501,0.14-1.051-0.093-1.528 l-1.052-2.155c1.459-1.215,2.645-2.688,3.525-4.377l2.278,0.505c0.52,0.116,1.061,0.02,1.508-0.266 c0.447-0.285,0.763-0.736,0.878-1.254l0.647-2.923C97.866,67.748,97.186,66.681,96.107,66.441z M85.162,66.174 c0,3.039-2.471,5.511-5.508,5.511c-3.039,0-5.512-2.472-5.512-5.511c0-3.039,2.473-5.511,5.512-5.511 C82.691,60.664,85.162,63.136,85.162,66.174z\"/> </g> </svg> "
+                },
+                "descriptors": []
+            }, {
+                "id": "GUID-3",
+                "name": "RIFT.ware™ PNF Descriptors Catalog",
+                "short-name": "rift.ware-pnfd-cat",
+                "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+                "vendor": "RIFT.io",
+                "version": "",
+                "created-on": "",
+                "type": "pnfd",
+                "meta": {
+                    "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_4\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <path d=\"M86.334,47.444V35.759H13.666v11.686h3.561v5.111h-3.561v11.686h72.668V52.556h-4.108v-5.111H86.334z M26.628,59.454h-5.051 v-4.941h5.051V59.454z M26.628,52.404h-5.051v-4.941h5.051V52.404z M26.628,45.486h-5.051v-4.941h5.051V45.486z M34.094,59.454 h-5.051v-4.941h5.051V59.454z M34.094,52.404h-5.051v-4.941h5.051V52.404z M34.094,45.486h-5.051v-4.941h5.051V45.486z M41.452,59.454h-5.051v-4.941h5.051V59.454z M41.452,52.404h-5.051v-4.941h5.051V52.404z M41.452,45.486h-5.051v-4.941h5.051 V45.486z M48.733,59.454h-5.051v-4.941h5.051V59.454z M48.733,52.404h-5.051v-4.941h5.051V52.404z M48.733,45.486h-5.051v-4.941 h5.051V45.486z M56.2,59.454h-5.051v-4.941H56.2V59.454z M56.2,52.404h-5.051v-4.941H56.2V52.404z M56.2,45.486h-5.051v-4.941H56.2 V45.486z M63.558,59.454h-5.05v-4.941h5.05V59.454z M63.558,52.404h-5.05v-4.941h5.05V52.404z M63.558,45.486h-5.05v-4.941h5.05 V45.486z M74.858,59.312h-6.521v-3.013h6.521V59.312z M71.572,50.854c-2.875,0-5.204-2.33-5.204-5.203s2.329-5.203,5.204-5.203 s5.204,2.33,5.204,5.203S74.446,50.854,71.572,50.854z M74.858,45.618c0,1.801-1.46,3.261-3.261,3.261 c-1.8,0-3.261-1.46-3.261-3.261s1.46-3.26,3.261-3.26C73.398,42.358,74.858,43.817,74.858,45.618z\"/> </svg>"
+                },
+                "descriptors": []
+            }];
+            if (result[0].body) {
+                response[0].descriptors = JSON.parse(result[0].body).collection['nsd:nsd'];
+                if (result[2].body) {
+                    var data = JSON.parse(result[2].body);
+                    if (data && data["nsr:ns-instance-opdata"] && data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"]) {
+                        var nsdRefCountCollection = data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"];
+                        response[0].descriptors.map(function(nsd) {
+                            if (!nsd["meta"]) {
+                                nsd["meta"] = {};
+                            }
+                            if (typeof nsd['meta'] == 'string') {
+                                nsd['meta'] = JSON.parse(nsd['meta']);
+                            }
+                            nsd["meta"]["instance-ref-count"] = _.findWhere(nsdRefCountCollection, {
+                                "nsd-id-ref": nsd.id
+                            })["instance-ref-count"];
+                        });
+                    }
+                }
+            };
+            if (result[1].body) {
+                response[1].descriptors = JSON.parse(result[1].body).collection['vnfd:vnfd'];
+            };
+            // if (result[2].body) {
+            //   response[2].descriptors = JSON.parse(result[2].body).collection['pnfd:pnfd'];
+            // };
+            resolve({
+                statusCode: response.statusCode || 200,
+                data: JSON.stringify(response)
+            });
+        }).catch(function(error) {
+            // Todo: Need better logic than all or nothing.
+            // Right now even if one of the southbound APIs fails - all fail
+            var res = {};
+            console.log('Problem with Composer.get', error);
+            res.statusCode = error.statusCode || 500;
+            res.errorMessage = {
+                error: 'Failed to get catalogs' + error
+            };
+            reject(res);
+        });
+    });
+};
+Composer.delete = function(req) {
+    var api_server = req.query['api_server'];
+    var catalogType = req.params.catalogType;
+    var id = req.params.id;
+    console.log('Deleting', catalogType, id, 'from', api_server);
+    return new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog/' + catalogType + '/' + id,
+            method: 'DELETE',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('Composer.delete', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+Composer.getVNFD = function(req) {
+    var api_server = req.query['api_server'];
+    var vnfdID = req.body.data;
+    var authorization = req.get('Authorization');
+    var VNFDs = [];
+    if (typeof(vnfdID) == "object" && vnfdID.constructor.name == "Array") {
+        vnfdID.map(function(id) {
+            VNFDs.push(requestVNFD(id));
+        });
+    } else {
+        VNFDs.push(requestVNFD(vnfdID));
+    }
+    return new Promise(function(resolve, reject) {
+        Promise.all(VNFDs).then(function(data) {
+            resolve(data)
+        }).catch(function(error) {
+            // Todo: Need better logic than all or nothing.
+            // Right now even if one of the southbound APIs fails - all fail
+            var res = {};
+            console.log('Problem with Composer.getVNFD', error);
+            res.statusCode = 404;
+            res.errorMessage = {
+                error: 'Failed to get VNFDs' + error
+            };
+            reject(res);
+        });
+    });
+
+    function requestVNFD(id) {
+        return new Promise(function(resolve, reject) {
+            var url = utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd' + (id ? '/' + id : '') + '?deep';
+            request({
+                uri: url,
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                    'Authorization': authorization
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+            }, function(error, response, body) {
+                if (utils.validateResponse('Composer.create', error, response, body, resolve, reject)) {
+                    var data;
+                    //Is this still needed?
+                    try {
+                        data = JSON.parse(response.body)
+                    } catch (e) {
+                        reject({
+                            statusCode: response ? response.statusCode : 400,
+                            errorMessage: 'Issue parsing VNFD ' + id + 'from ' + utils.confdPort(api_server) + '/api/config/vnfd-catalog/vnfd/' + id + '?deep'
+                        });
+                    }
+                    resolve(data);
+                }
+            });
+        });
+    }
+};
+Composer.create = function(req) {
+    var api_server = req.query['api_server'];
+    var catalogType = req.params.catalogType;
+    var data = req.body;
+    console.log('Creating', catalogType, 'on', api_server);
+    var jsonData = {};
+    jsonData[catalogType] = [];
+    jsonData[catalogType].push(data);
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + '/api/config/' + catalogType + '-catalog',
+            method: 'POST',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('Composer.create', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+Composer.update = function(req) {
+    var api_server = req.query['api_server'];
+    var catalogType = req.params.catalogType;
+    var id = req.params.id;
+    var data = req.body;
+    console.log('Updating', catalogType, 'id', id, 'on', api_server);
+    var jsonData = {};
+    jsonData[catalogType] = {};
+    jsonData[catalogType] = data;
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog' + '/' + catalogType + '/' + id,
+            method: 'PUT',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('Composer.update', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+module.exports = Composer;
diff --git a/skyquake/plugins/composer/codeStyleSettings.xml b/skyquake/plugins/composer/codeStyleSettings.xml
new file mode 100644 (file)
index 0000000..c8d955e
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectCodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value>
+        <option name="AUTODETECT_INDENTS" value="false" />
+        <option name="OTHER_INDENT_OPTIONS">
+          <value>
+            <option name="INDENT_SIZE" value="4" />
+            <option name="CONTINUATION_INDENT_SIZE" value="8" />
+            <option name="TAB_SIZE" value="4" />
+            <option name="USE_TAB_CHARACTER" value="true" />
+            <option name="SMART_TABS" value="false" />
+            <option name="LABEL_INDENT_SIZE" value="0" />
+            <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+            <option name="USE_RELATIVE_INDENTS" value="false" />
+          </value>
+        </option>
+        <XML>
+          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+        </XML>
+        <editorconfig>
+          <option name="ENABLED" value="false" />
+        </editorconfig>
+        <codeStyleSettings language="CSS">
+          <indentOptions>
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="CoffeeScript">
+          <indentOptions>
+            <option name="INDENT_SIZE" value="4" />
+            <option name="CONTINUATION_INDENT_SIZE" value="4" />
+            <option name="TAB_SIZE" value="4" />
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="HTML">
+          <indentOptions>
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="JSON">
+          <indentOptions>
+            <option name="INDENT_SIZE" value="4" />
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="JavaScript">
+          <indentOptions>
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="SASS">
+          <indentOptions>
+            <option name="INDENT_SIZE" value="4" />
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="SCSS">
+          <indentOptions>
+            <option name="INDENT_SIZE" value="4" />
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="TypeScript">
+          <indentOptions>
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+        <codeStyleSettings language="XML">
+          <indentOptions>
+            <option name="USE_TAB_CHARACTER" value="true" />
+          </indentOptions>
+        </codeStyleSettings>
+      </value>
+    </option>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/skyquake/plugins/composer/config.json b/skyquake/plugins/composer/config.json
new file mode 100644 (file)
index 0000000..2a8a516
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "root": "public",
+    "name": "Catalog",
+    "dashboard" : "./src/components/ComposerApp.js",
+    "order": 2,
+    "routes" : [{
+        "label": "Catalog",
+        "route": "/",
+        "component": "./src/components/ComposerApp.js",
+        "path": "",
+        "type": "internal"
+    }]
+}
diff --git a/skyquake/plugins/composer/karma.conf.js b/skyquake/plugins/composer/karma.conf.js
new file mode 100644 (file)
index 0000000..c69ade8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+var path = require('path');
+
+module.exports = function (config) {
+       config.set({
+               basePath: '',
+               frameworks: ['jasmine', 'es6-shim'],
+               files: [
+                       'test/spec/**/*.js'
+               ],
+               preprocessors: {
+                       'test/spec/**/*.js': ['webpack']
+               },
+               webpack: require('./webpack.config.js'),
+               webpackMiddleware: {
+                       noInfo: true,
+                       stats: {
+                               colors: true
+                       }
+               },
+               webpackServer: {
+                       noInfo: true //please don't spam the console when running in karma!
+               },
+               exclude: [],
+               port: 8080,
+               logLevel: config.LOG_INFO,
+               colors: true,
+               autoWatch: true,
+               browsers: ['Chrome'],
+               reporters: ['dots'],
+               captureTimeout: 60000,
+               singleRun: false,
+               plugins: [
+                       require('karma-webpack'),
+                       require('karma-jasmine'),
+                       require('karma-chrome-launcher'),
+                       require('karma-phantomjs-launcher'),
+                       require('karma-es6-shim')
+               ]
+       });
+};
diff --git a/skyquake/plugins/composer/license-flat-icon.pdf b/skyquake/plugins/composer/license-flat-icon.pdf
new file mode 100755 (executable)
index 0000000..4969d07
Binary files /dev/null and b/skyquake/plugins/composer/license-flat-icon.pdf differ
diff --git a/skyquake/plugins/composer/license-info.txt b/skyquake/plugins/composer/license-info.txt
new file mode 100644 (file)
index 0000000..7554df7
--- /dev/null
@@ -0,0 +1,2 @@
+
+flat-icon-license.pdf - license for the icons used in this project
diff --git a/skyquake/plugins/composer/main.js.map b/skyquake/plugins/composer/main.js.map
new file mode 100644 (file)
index 0000000..32c8755
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap a4e0cb00cc099a3c7d0d","webpack:///(webpack)/hot/only-dev-server.js","webpack:///(webpack)/hot/log-apply-result.js","webpack:///./src/components/ComposerApp.js","webpack:///(webpack)/buildin/module.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/index.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/makeMakeHot.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/makePatchReactClass.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/makeAssimilatePrototype.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/requestForceUpdateAll.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/deepForceUpdate.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/bindAutoBindMethods.js","webpack:///./~/react-hot-loader/~/react-hot-api/modules/traverseRenderedChildren.js","webpack:///./~/react-hot-loader/RootInstanceProvider.js","webpack:///./~/react-hot-loader/getRootInstancesFromReactMount.js","webpack:///./~/react/lib/ReactMount.js","webpack:///(webpack)/~/node-libs-browser/~/process/browser.js","webpack:///./~/react/lib/DOMProperty.js","webpack:///./~/react/~/fbjs/lib/invariant.js","webpack:///./~/react/lib/ReactBrowserEventEmitter.js","webpack:///./~/react/lib/EventConstants.js","webpack:///./~/react/~/fbjs/lib/keyMirror.js","webpack:///./~/react/lib/EventPluginHub.js","webpack:///./~/react/lib/EventPluginRegistry.js","webpack:///./~/react/lib/EventPluginUtils.js","webpack:///./~/react/lib/ReactErrorUtils.js","webpack:///./~/react/~/fbjs/lib/warning.js","webpack:///./~/react/~/fbjs/lib/emptyFunction.js","webpack:///./~/react/lib/accumulateInto.js","webpack:///./~/react/lib/forEachAccumulated.js","webpack:///./~/react/lib/ReactEventEmitterMixin.js","webpack:///./~/react/lib/ReactPerf.js","webpack:///./~/react/lib/ViewportMetrics.js","webpack:///./~/react/lib/Object.assign.js","webpack:///./~/react/lib/isEventSupported.js","webpack:///./~/react/~/fbjs/lib/ExecutionEnvironment.js","webpack:///./~/react/lib/ReactCurrentOwner.js","webpack:///./~/react/lib/ReactDOMFeatureFlags.js","webpack:///./~/react/lib/ReactElement.js","webpack:///./~/react/lib/canDefineProperty.js","webpack:///./~/react/lib/ReactEmptyComponentRegistry.js","webpack:///./~/react/lib/ReactInstanceHandles.js","webpack:///./~/react/lib/ReactRootIndex.js","webpack:///./~/react/lib/ReactInstanceMap.js","webpack:///./~/react/lib/ReactMarkupChecksum.js","webpack:///./~/react/lib/adler32.js","webpack:///./~/react/lib/ReactReconciler.js","webpack:///./~/react/lib/ReactRef.js","webpack:///./~/react/lib/ReactOwner.js","webpack:///./~/react/lib/ReactUpdateQueue.js","webpack:///./~/react/lib/ReactUpdates.js","webpack:///./~/react/lib/CallbackQueue.js","webpack:///./~/react/lib/PooledClass.js","webpack:///./~/react/lib/Transaction.js","webpack:///./~/react/~/fbjs/lib/emptyObject.js","webpack:///./~/react/~/fbjs/lib/containsNode.js","webpack:///./~/react/~/fbjs/lib/isTextNode.js","webpack:///./~/react/~/fbjs/lib/isNode.js","webpack:///./~/react/lib/instantiateReactComponent.js","webpack:///./~/react/lib/ReactCompositeComponent.js","webpack:///./~/react/lib/ReactComponentEnvironment.js","webpack:///./~/react/lib/ReactPropTypeLocations.js","webpack:///./~/react/lib/ReactPropTypeLocationNames.js","webpack:///./~/react/lib/shouldUpdateReactComponent.js","webpack:///./~/react/lib/ReactEmptyComponent.js","webpack:///./~/react/lib/ReactNativeComponent.js","webpack:///./~/react/lib/setInnerHTML.js","webpack:///./~/react/lib/validateDOMNesting.js","webpack:///./~/react/react.js","webpack:///./~/react/lib/React.js","webpack:///./~/react/lib/ReactDOM.js","webpack:///./~/react/lib/ReactDOMTextComponent.js","webpack:///./~/react/lib/DOMChildrenOperations.js","webpack:///./~/react/lib/Danger.js","webpack:///./~/react/~/fbjs/lib/createNodesFromMarkup.js","webpack:///./~/react/~/fbjs/lib/createArrayFromMixed.js","webpack:///./~/react/~/fbjs/lib/toArray.js","webpack:///./~/react/~/fbjs/lib/getMarkupWrap.js","webpack:///./~/react/lib/ReactMultiChildUpdateTypes.js","webpack:///./~/react/lib/setTextContent.js","webpack:///./~/react/lib/escapeTextContentForBrowser.js","webpack:///./~/react/lib/DOMPropertyOperations.js","webpack:///./~/react/lib/quoteAttributeValueForBrowser.js","webpack:///./~/react/lib/ReactComponentBrowserEnvironment.js","webpack:///./~/react/lib/ReactDOMIDOperations.js","webpack:///./~/react/lib/ReactDefaultInjection.js","webpack:///./~/react/lib/BeforeInputEventPlugin.js","webpack:///./~/react/lib/EventPropagators.js","webpack:///./~/react/lib/FallbackCompositionState.js","webpack:///./~/react/lib/getTextContentAccessor.js","webpack:///./~/react/lib/SyntheticCompositionEvent.js","webpack:///./~/react/lib/SyntheticEvent.js","webpack:///./~/react/lib/SyntheticInputEvent.js","webpack:///./~/react/~/fbjs/lib/keyOf.js","webpack:///./~/react/lib/ChangeEventPlugin.js","webpack:///./~/react/lib/getEventTarget.js","webpack:///./~/react/lib/isTextInputElement.js","webpack:///./~/react/lib/ClientReactRootIndex.js","webpack:///./~/react/lib/DefaultEventPluginOrder.js","webpack:///./~/react/lib/EnterLeaveEventPlugin.js","webpack:///./~/react/lib/SyntheticMouseEvent.js","webpack:///./~/react/lib/SyntheticUIEvent.js","webpack:///./~/react/lib/getEventModifierState.js","webpack:///./~/react/lib/HTMLDOMPropertyConfig.js","webpack:///./~/react/lib/ReactBrowserComponentMixin.js","webpack:///./~/react/lib/findDOMNode.js","webpack:///./~/react/lib/ReactDefaultBatchingStrategy.js","webpack:///./~/react/lib/ReactDOMComponent.js","webpack:///./~/react/lib/AutoFocusUtils.js","webpack:///./~/react/~/fbjs/lib/focusNode.js","webpack:///./~/react/lib/CSSPropertyOperations.js","webpack:///./~/react/lib/CSSProperty.js","webpack:///./~/react/~/fbjs/lib/camelizeStyleName.js","webpack:///./~/react/~/fbjs/lib/camelize.js","webpack:///./~/react/lib/dangerousStyleValue.js","webpack:///./~/react/~/fbjs/lib/hyphenateStyleName.js","webpack:///./~/react/~/fbjs/lib/hyphenate.js","webpack:///./~/react/~/fbjs/lib/memoizeStringOnly.js","webpack:///./~/react/lib/ReactDOMButton.js","webpack:///./~/react/lib/ReactDOMInput.js","webpack:///./~/react/lib/LinkedValueUtils.js","webpack:///./~/react/lib/ReactPropTypes.js","webpack:///./~/react/lib/getIteratorFn.js","webpack:///./~/react/lib/ReactDOMOption.js","webpack:///./~/react/lib/ReactChildren.js","webpack:///./~/react/lib/traverseAllChildren.js","webpack:///./~/react/lib/ReactDOMSelect.js","webpack:///./~/react/lib/ReactDOMTextarea.js","webpack:///./~/react/lib/ReactMultiChild.js","webpack:///./~/react/lib/ReactChildReconciler.js","webpack:///./~/react/lib/flattenChildren.js","webpack:///./~/react/~/fbjs/lib/shallowEqual.js","webpack:///./~/react/lib/ReactEventListener.js","webpack:///./~/react/~/fbjs/lib/EventListener.js","webpack:///./~/react/~/fbjs/lib/getUnboundedScrollPosition.js","webpack:///./~/react/lib/ReactInjection.js","webpack:///./~/react/lib/ReactClass.js","webpack:///./~/react/lib/ReactComponent.js","webpack:///./~/react/lib/ReactNoopUpdateQueue.js","webpack:///./~/react/lib/ReactReconcileTransaction.js","webpack:///./~/react/lib/ReactInputSelection.js","webpack:///./~/react/lib/ReactDOMSelection.js","webpack:///./~/react/lib/getNodeForCharacterOffset.js","webpack:///./~/react/~/fbjs/lib/getActiveElement.js","webpack:///./~/react/lib/SelectEventPlugin.js","webpack:///./~/react/lib/ServerReactRootIndex.js","webpack:///./~/react/lib/SimpleEventPlugin.js","webpack:///./~/react/lib/SyntheticClipboardEvent.js","webpack:///./~/react/lib/SyntheticFocusEvent.js","webpack:///./~/react/lib/SyntheticKeyboardEvent.js","webpack:///./~/react/lib/getEventCharCode.js","webpack:///./~/react/lib/getEventKey.js","webpack:///./~/react/lib/SyntheticDragEvent.js","webpack:///./~/react/lib/SyntheticTouchEvent.js","webpack:///./~/react/lib/SyntheticWheelEvent.js","webpack:///./~/react/lib/SVGDOMPropertyConfig.js","webpack:///./~/react/lib/ReactDefaultPerf.js","webpack:///./~/react/lib/ReactDefaultPerfAnalysis.js","webpack:///./~/react/~/fbjs/lib/performanceNow.js","webpack:///./~/react/~/fbjs/lib/performance.js","webpack:///./~/react/lib/ReactVersion.js","webpack:///./~/react/lib/renderSubtreeIntoContainer.js","webpack:///./~/react/lib/ReactDOMServer.js","webpack:///./~/react/lib/ReactServerRendering.js","webpack:///./~/react/lib/ReactServerBatchingStrategy.js","webpack:///./~/react/lib/ReactServerRenderingTransaction.js","webpack:///./~/react/lib/ReactIsomorphic.js","webpack:///./~/react/lib/ReactDOMFactories.js","webpack:///./~/react/lib/ReactElementValidator.js","webpack:///./~/react/~/fbjs/lib/mapObject.js","webpack:///./~/react/lib/onlyChild.js","webpack:///./~/react/lib/deprecated.js","webpack:///./~/es5-shim/es5-shim.js","webpack:///./~/babel-polyfill/lib/index.js","webpack:///./~/babel-polyfill/~/core-js/shim.js","webpack:///./~/babel-polyfill/~/core-js/modules/es5.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.export.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.global.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.core.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.hide.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.property-desc.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.descriptors.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.fails.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.redefine.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.uid.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.ctx.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.a-function.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.html.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.dom-create.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.is-object.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.has.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.cof.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.invoke.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.an-object.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.to-object.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.defined.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.to-iobject.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iobject.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.to-integer.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.to-index.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.to-length.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.array-methods.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.array-species-create.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.is-array.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.wks.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.shared.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.array-includes.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.symbol.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.set-to-string-tag.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.keyof.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.get-names.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.enum-keys.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.library.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.assign.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.object-assign.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.is.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.same-value.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.set-prototype-of.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.set-proto.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.to-string.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.classof.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.freeze.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.object-sap.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.seal.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.prevent-extensions.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.is-frozen.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.is-sealed.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.is-extensible.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.get-own-property-descriptor.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.get-prototype-of.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.keys.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.object.get-own-property-names.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.function.name.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.function.has-instance.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.constructor.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.to-primitive.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.string-trim.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.epsilon.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.is-finite.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.is-integer.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.is-integer.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.is-nan.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.is-safe-integer.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.max-safe-integer.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.min-safe-integer.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.parse-float.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.number.parse-int.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.acosh.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.math-log1p.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.asinh.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.atanh.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.cbrt.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.math-sign.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.clz32.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.cosh.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.expm1.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.math-expm1.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.fround.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.hypot.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.imul.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.log10.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.log1p.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.log2.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.sign.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.sinh.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.tanh.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.math.trunc.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.from-code-point.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.raw.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.trim.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.iterator.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.string-at.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iter-define.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iterators.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iter-create.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.code-point-at.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.ends-with.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.string-context.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.is-regexp.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.fails-is-regexp.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.includes.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.repeat.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.string-repeat.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.string.starts-with.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.from.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iter-call.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.is-array-iter.js","webpack:///./~/babel-polyfill/~/core-js/modules/core.get-iterator-method.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iter-detect.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.of.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.iterator.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.add-to-unscopables.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.iter-step.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.species.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.set-species.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.copy-within.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.array-copy-within.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.fill.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.array-fill.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.find.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.array.find-index.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.regexp.constructor.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.flags.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.regexp.flags.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.regexp.match.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.fix-re-wks.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.regexp.replace.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.regexp.search.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.regexp.split.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.promise.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.strict-new.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.for-of.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.species-constructor.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.microtask.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.task.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.redefine-all.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.map.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.collection-strong.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.collection.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.set.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.weak-map.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.collection-weak.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.weak-set.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.apply.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.construct.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.define-property.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.delete-property.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.enumerate.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.get.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.get-own-property-descriptor.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.get-prototype-of.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.has.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.is-extensible.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.own-keys.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.own-keys.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.prevent-extensions.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.set.js","webpack:///./~/babel-polyfill/~/core-js/modules/es6.reflect.set-prototype-of.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.array.includes.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.string.at.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.string.pad-left.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.string-pad.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.string.pad-right.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.string.trim-left.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.string.trim-right.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.regexp.escape.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.replacer.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.object.get-own-property-descriptors.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.object.values.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.object-to-array.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.object.entries.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.map.to-json.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.collection-to-json.js","webpack:///./~/babel-polyfill/~/core-js/modules/es7.set.to-json.js","webpack:///./~/babel-polyfill/~/core-js/modules/js.array.statics.js","webpack:///./~/babel-polyfill/~/core-js/modules/web.timers.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.partial.js","webpack:///./~/babel-polyfill/~/core-js/modules/$.path.js","webpack:///./~/babel-polyfill/~/core-js/modules/web.immediate.js","webpack:///./~/babel-polyfill/~/core-js/modules/web.dom.iterable.js","webpack:///./~/babel-polyfill/~/babel-regenerator-runtime/runtime.js","webpack:///./src/alt.js","webpack:///./~/alt/lib/index.js","webpack:///./~/alt/~/flux/index.js","webpack:///./~/alt/~/flux/lib/Dispatcher.js","webpack:///./~/alt/~/flux/lib/invariant.js","webpack:///./~/alt/lib/utils/StateFunctions.js","webpack:///./~/alt/utils/functions.js","webpack:///./~/alt/lib/store/index.js","webpack:///./~/alt/lib/utils/AltUtils.js","webpack:///./~/alt/lib/store/AltStore.js","webpack:///./~/alt/~/transmitter/dist/transmitter.js","webpack:///./~/alt/lib/store/StoreMixin.js","webpack:///./~/alt/lib/actions/index.js","webpack:///./~/react-hot-loader/makeExportsHot.js","webpack:///./~/react-hot-loader/isReactClassish.js","webpack:///./~/react-hot-loader/isReactElementish.js","webpack:///./src/libraries/UniqueId.js","webpack:///./~/d3/d3.js","webpack:///./src/libraries/guid.js","webpack:///./src/libraries/model/DescriptorModel.js","webpack:///./~/lodash/index.js","webpack:///./src/libraries/graph/Position.js","webpack:///./src/libraries/model/IconFactory.js","webpack:///./src/libraries/SelectionManager.js","webpack:///./src/libraries/graph/PathBuilder.js","webpack:///./src/libraries/model/DescriptorModelMetaFactory.js","webpack:///./src/libraries/utils.js","webpack:///./~/change-case/change-case.js","webpack:///./~/change-case/~/dot-case/dot-case.js","webpack:///./~/change-case/~/sentence-case/sentence-case.js","webpack:///./~/change-case/~/lower-case/lower-case.js","webpack:///./~/change-case/~/sentence-case/vendor/non-word-regexp.js","webpack:///./~/change-case/~/sentence-case/vendor/camel-case-regexp.js","webpack:///./~/change-case/~/sentence-case/vendor/trailing-digit-regexp.js","webpack:///./~/change-case/~/swap-case/swap-case.js","webpack:///./~/change-case/~/upper-case/upper-case.js","webpack:///./~/change-case/~/path-case/path-case.js","webpack:///./~/change-case/~/camel-case/camel-case.js","webpack:///./~/change-case/~/snake-case/snake-case.js","webpack:///./~/change-case/~/title-case/title-case.js","webpack:///./~/change-case/~/param-case/param-case.js","webpack:///./~/change-case/~/pascal-case/pascal-case.js","webpack:///./~/change-case/~/upper-case-first/upper-case-first.js","webpack:///./~/change-case/~/constant-case/constant-case.js","webpack:///./~/change-case/~/is-upper-case/is-upper-case.js","webpack:///./~/change-case/~/is-lower-case/is-lower-case.js","webpack:///./~/change-case/~/lower-case-first/lower-case-first.js","webpack:///./src/libraries/model/DescriptorModelMeta.json","webpack:///./src/libraries/model/DescriptorModelMetaProperty.js","webpack:///./src/libraries/InstanceCounter.js","webpack:///./src/libraries/model/DescriptorModelFields.js","webpack:///./src/libraries/model/DescriptorTemplateFactory.js","webpack:///./src/libraries/model/DescriptorTemplates.js","webpack:///./~/react-dom/index.js","webpack:///./~/react-crouton/index.js","webpack:///./~/classnames/index.js","webpack:///./~/react-tooltip/dist/react-tooltip.js","webpack:///./~/react-tooltip/~/classnames/index.js","webpack:///./~/react-tooltip/dist/style.js","webpack:///./~/react-addons-pure-render-mixin/index.js","webpack:///./~/react/lib/ReactComponentWithPureRenderMixin.js","webpack:///./~/react/lib/shallowCompare.js","webpack:///./src/libraries/DeletionManager.js","webpack:///./src/actions/CatalogItemsActions.js","webpack:///./src/libraries/model/DescriptorModelFactory.js","webpack:///./src/libraries/ColorGroups.js","webpack:///./src/assets/rift.ware-color-theme.json","webpack:///./src/libraries/model/descriptors/Classifier.js","webpack:///./src/libraries/model/descriptors/RspConnectionPointRef.js","webpack:///./src/libraries/model/descriptors/VnfdConnectionPointRef.js","webpack:///./src/libraries/model/descriptors/ClassifierMatchAttributes.js","webpack:///./src/libraries/model/descriptors/ConnectionPoint.js","webpack:///./src/libraries/model/descriptors/ConstituentVnfd.js","webpack:///./src/libraries/model/descriptors/ConstituentVnfdConnectionPoint.js","webpack:///./src/libraries/model/descriptors/ForwardingGraph.js","webpack:///./src/libraries/model/descriptors/RecordServicePath.js","webpack:///./src/libraries/model/descriptors/InternalConnectionPoint.js","webpack:///./src/libraries/model/descriptors/InternalVirtualLink.js","webpack:///./src/libraries/model/descriptors/NetworkService.js","webpack:///./src/libraries/model/descriptors/VirtualLink.js","webpack:///./src/libraries/model/descriptors/PhysicalNetworkFunction.js","webpack:///./src/libraries/model/descriptors/VirtualDeploymentUnit.js","webpack:///./src/libraries/model/descriptors/VirtualNetworkFunction.js","webpack:///./src/libraries/model/descriptors/VirtualNetworkFunctionReadOnlyWrapper.js","webpack:///./src/styles/Animations.scss?f880","webpack:///./src/styles/Animations.scss","webpack:///./~/css-loader/lib/css-base.js","webpack:///./~/style-loader/addStyles.js","webpack:///./src/libraries/ResizableManager.js","webpack:///./src/libraries/zoomFactor.js","webpack:///./src/styles/ResizableManager.scss?a761","webpack:///./src/styles/ResizableManager.scss","webpack:///./src/components/RiftHeader.js","webpack:///./src/actions/RiftHeaderActions.js","webpack:///./src/stores/RiftHeaderStore.js","webpack:///./src/sources/CatalogDataSource.js","webpack:///./~/jquery/dist/jquery.js","webpack:///./src/libraries/model/DescriptorConfDSerializer.js","webpack:///./src/actions/CatalogDataSourceActions.js","webpack:///./src/styles/RiftHeader.scss?fee1","webpack:///./src/styles/RiftHeader.scss","webpack:///./src/images/header-logo.png","webpack:///./src/components/CanvasPanel.js","webpack:///./src/components/messages.js","webpack:///./src/images/upload109.svg","webpack:///./src/components/CatalogItemCanvasEditor.js","webpack:///./src/libraries/graph/DescriptorGraph.js","webpack:///./src/libraries/graph/math.js","webpack:///./src/libraries/graph/DescriptorGraphSelection.js","webpack:///./src/actions/ComposerAppActions.js","webpack:///./src/libraries/graph/DescriptorGraphPathBuilder.js","webpack:///./src/libraries/graph/DescriptorGraphGrid.js","webpack:///./src/libraries/graph/GraphConnectionPointNumber.js","webpack:///./src/libraries/graph/layouts/RelationsAndNetworksLayout.js","webpack:///./src/libraries/graph/GraphVirtualLink.js","webpack:///./src/libraries/graph/GraphDescriptorModel.js","webpack:///./src/styles/GraphDescriptorModel.scss?9cdd","webpack:///./src/styles/GraphDescriptorModel.scss","webpack:///./src/styles/GraphVirtualLink.scss?d063","webpack:///./src/styles/GraphVirtualLink.scss","webpack:///./src/assets/Roboto-Thin-webfont.woff","webpack:///./src/assets/Roboto-ThinItalic-webfont.woff","webpack:///./src/assets/Roboto-Light-webfont.woff","webpack:///./src/assets/Roboto-LightItalic-webfont.woff","webpack:///./src/assets/Roboto-Regular-webfont.woff","webpack:///./src/assets/Roboto-Italic-webfont.woff","webpack:///./src/assets/Roboto-Medium-webfont.woff","webpack:///./src/assets/Roboto-MediumItalic-webfont.woff","webpack:///./src/assets/Roboto-Bold-webfont.woff","webpack:///./src/assets/Roboto-BoldItalic-webfont.woff","webpack:///./src/assets/Roboto-Black-webfont.woff","webpack:///./src/assets/Roboto-BlackItalic-webfont.woff","webpack:///./src/assets/RobotoCondensed-Light-webfont.woff","webpack:///./src/assets/RobotoCondensed-LightItalic-webfont.woff","webpack:///./src/assets/RobotoCondensed-Regular-webfont.woff","webpack:///./src/assets/RobotoCondensed-Italic-webfont.woff","webpack:///./src/assets/RobotoCondensed-Bold-webfont.woff","webpack:///./src/assets/RobotoCondensed-BoldItalic-webfont.woff","webpack:///./src/libraries/graph/GraphNetworkService.js","webpack:///./src/libraries/graph/GraphForwardingGraph.js","webpack:///./src/libraries/graph/GraphConstituentVnfd.js","webpack:///./src/libraries/graph/GraphVirtualNetworkFunction.js","webpack:///./src/libraries/graph/GraphVirtualDeploymentUnit.js","webpack:///./src/libraries/graph/GraphRecordServicePath.js","webpack:///./src/styles/GraphRecordServicePaths.scss?9a54","webpack:///./src/styles/GraphRecordServicePaths.scss","webpack:///./src/stores/ComposerAppStore.js","webpack:///./src/actions/PanelResizeAction.js","webpack:///./src/actions/CanvasEditorActions.js","webpack:///./src/actions/CatalogFilterActions.js","webpack:///./src/actions/CanvasPanelTrayActions.js","webpack:///./src/stores/CatalogDataStore.js","webpack:///./src/actions/CatalogPackageManagerActions.js","webpack:///./src/actions/ModalOverlayActions.js","webpack:///./src/styles/CatalogItemCanvasEditor.scss?df68","webpack:///./src/styles/CatalogItemCanvasEditor.scss","webpack:///./src/styles/DescriptorGraph.scss?90e9","webpack:///./src/styles/DescriptorGraph.scss","webpack:///./src/components/CanvasZoom.js","webpack:///./src/components/Range.js","webpack:///./~/numeral/numeral.js","webpack:///./src/styles/CanvasZoom.scss?057e","webpack:///./src/styles/CanvasZoom.scss","webpack:///./src/components/CanvasPanelTray.js","webpack:///./src/styles/CanvasPanelTray.scss?b636","webpack:///./src/styles/CanvasPanelTray.scss","webpack:///./src/components/ForwardingGraphPathsEditor.js","webpack:///./src/components/Button.js","webpack:///./src/styles/Button.scss?45b9","webpack:///./src/styles/Button.scss","webpack:///./src/components/LayoutRow.js","webpack:///./src/styles/LayoutRow.scss?1b8f","webpack:///./src/styles/LayoutRow.scss","webpack:///./src/components/ContentEditableDiv.js","webpack:///./src/styles/ForwardingGraphPathsEditor.scss?f432","webpack:///./src/styles/ForwardingGraphPathsEditor.scss","webpack:///./src/images/iconmonstr-network-6-icon.svg","webpack:///./src/images/iconmonstr-infinity-4-icon.svg","webpack:///./src/images/recycle69.svg","webpack:///./src/images/iconmonstr-plus-5-icon-256.png","webpack:///./src/images/connection.svg","webpack:///./src/images/iconmonstr-control-panel-4.svg","webpack:///./src/images/menu51.svg","webpack:///./src/styles/CanvasPanel.scss?58de","webpack:///./src/styles/CanvasPanel.scss","webpack:///./src/components/CatalogPanel.js","webpack:///./src/libraries/CatalogPackageManagerUploadDropZone.js","webpack:///./~/dropzone/dist/dropzone.js","webpack:///./src/components/DropTarget.js","webpack:///./src/components/DropZonePanel.js","webpack:///./src/styles/DropZonePanel.scss?946f","webpack:///./src/styles/DropZonePanel.scss","webpack:///./src/components/CatalogItems.js","webpack:///./src/styles/CatalogItems.scss?5b69","webpack:///./src/styles/CatalogItems.scss","webpack:///./src/images/vendor-riftio.png","webpack:///./src/components/CatalogFilter.js","webpack:///./src/styles/CatalogFilter.scss?b58c","webpack:///./src/styles/CatalogFilter.scss","webpack:///./src/components/CatalogPanelTray.js","webpack:///./src/actions/CatalogPanelTrayActions.js","webpack:///./src/styles/CatalogPanelTray.scss?5e85","webpack:///./src/styles/CatalogPanelTray.scss","webpack:///./src/components/CatalogPanelToolbar.js","webpack:///./src/styles/CatalogPanelToolbar.scss?6b23","webpack:///./src/styles/CatalogPanelToolbar.scss","webpack:///./src/images/add175.svg","webpack:///./src/images/copy30.svg","webpack:///./src/images/file91.svg","webpack:///./src/images/download158.svg","webpack:///./src/components/CatalogPackageManager.js","webpack:///./~/moment/moment.js","webpack:///./~/moment/locale ^\\.\\/.*$","webpack:///./~/moment/locale/af.js","webpack:///./~/moment/locale/ar.js","webpack:///./~/moment/locale/ar-ma.js","webpack:///./~/moment/locale/ar-sa.js","webpack:///./~/moment/locale/ar-tn.js","webpack:///./~/moment/locale/az.js","webpack:///./~/moment/locale/be.js","webpack:///./~/moment/locale/bg.js","webpack:///./~/moment/locale/bn.js","webpack:///./~/moment/locale/bo.js","webpack:///./~/moment/locale/br.js","webpack:///./~/moment/locale/bs.js","webpack:///./~/moment/locale/ca.js","webpack:///./~/moment/locale/cs.js","webpack:///./~/moment/locale/cv.js","webpack:///./~/moment/locale/cy.js","webpack:///./~/moment/locale/da.js","webpack:///./~/moment/locale/de.js","webpack:///./~/moment/locale/de-at.js","webpack:///./~/moment/locale/el.js","webpack:///./~/moment/locale/en-au.js","webpack:///./~/moment/locale/en-ca.js","webpack:///./~/moment/locale/en-gb.js","webpack:///./~/moment/locale/eo.js","webpack:///./~/moment/locale/es.js","webpack:///./~/moment/locale/et.js","webpack:///./~/moment/locale/eu.js","webpack:///./~/moment/locale/fa.js","webpack:///./~/moment/locale/fi.js","webpack:///./~/moment/locale/fo.js","webpack:///./~/moment/locale/fr.js","webpack:///./~/moment/locale/fr-ca.js","webpack:///./~/moment/locale/fy.js","webpack:///./~/moment/locale/gl.js","webpack:///./~/moment/locale/he.js","webpack:///./~/moment/locale/hi.js","webpack:///./~/moment/locale/hr.js","webpack:///./~/moment/locale/hu.js","webpack:///./~/moment/locale/hy-am.js","webpack:///./~/moment/locale/id.js","webpack:///./~/moment/locale/is.js","webpack:///./~/moment/locale/it.js","webpack:///./~/moment/locale/ja.js","webpack:///./~/moment/locale/jv.js","webpack:///./~/moment/locale/ka.js","webpack:///./~/moment/locale/km.js","webpack:///./~/moment/locale/ko.js","webpack:///./~/moment/locale/lb.js","webpack:///./~/moment/locale/lt.js","webpack:///./~/moment/locale/lv.js","webpack:///./~/moment/locale/me.js","webpack:///./~/moment/locale/mk.js","webpack:///./~/moment/locale/ml.js","webpack:///./~/moment/locale/mr.js","webpack:///./~/moment/locale/ms.js","webpack:///./~/moment/locale/ms-my.js","webpack:///./~/moment/locale/my.js","webpack:///./~/moment/locale/nb.js","webpack:///./~/moment/locale/ne.js","webpack:///./~/moment/locale/nl.js","webpack:///./~/moment/locale/nn.js","webpack:///./~/moment/locale/pl.js","webpack:///./~/moment/locale/pt.js","webpack:///./~/moment/locale/pt-br.js","webpack:///./~/moment/locale/ro.js","webpack:///./~/moment/locale/ru.js","webpack:///./~/moment/locale/si.js","webpack:///./~/moment/locale/sk.js","webpack:///./~/moment/locale/sl.js","webpack:///./~/moment/locale/sq.js","webpack:///./~/moment/locale/sr.js","webpack:///./~/moment/locale/sr-cyrl.js","webpack:///./~/moment/locale/sv.js","webpack:///./~/moment/locale/ta.js","webpack:///./~/moment/locale/th.js","webpack:///./~/moment/locale/tl-ph.js","webpack:///./~/moment/locale/tr.js","webpack:///./~/moment/locale/tzl.js","webpack:///./~/moment/locale/tzm.js","webpack:///./~/moment/locale/tzm-latn.js","webpack:///./~/moment/locale/uk.js","webpack:///./~/moment/locale/uz.js","webpack:///./~/moment/locale/vi.js","webpack:///./~/moment/locale/zh-cn.js","webpack:///./~/moment/locale/zh-tw.js","webpack:///./src/stores/CatalogPackageManagerStore.js","webpack:///./src/sources/CatalogPackageManagerSource.js","webpack:///./src/styles/CatalogPackageManager.scss?2868","webpack:///./src/styles/CatalogPackageManager.scss","webpack:///./src/images/video167.svg","webpack:///./src/images/zipped2.svg","webpack:///./src/images/file87.svg","webpack:///./src/images/cross95.svg","webpack:///./src/stores/CatalogPanelStore.js","webpack:///./src/components/LoadingIndicator.js","webpack:///./~/loaders.css/src/animations/line-scale-pulse-out-rapid.scss?b007","webpack:///./~/loaders.css/src/animations/line-scale-pulse-out-rapid.scss","webpack:///./src/styles/LoadingIndicator.scss?848c","webpack:///./src/styles/LoadingIndicator.scss","webpack:///./src/styles/CatalogPanel.scss?0dab","webpack:///./src/styles/CatalogPanel.scss","webpack:///./src/components/DetailsPanel.js","webpack:///./src/components/JSONViewer.js","webpack:///./~/prismjs/prism.js","webpack:///./src/styles/JSONViewer.scss?59c9","webpack:///./src/styles/JSONViewer.scss","webpack:///./src/components/PopupWindow.js","webpack:///./~/react-popout/dist/react-popout.min.js","webpack:///./src/components/CatalogItemDetailsEditor.js","webpack:///./src/libraries/model/DescriptorModelFormEditor.js","webpack:///./src/libraries/ToggleElementHandler.js","webpack:///./src/libraries/getEventPath.js","webpack:///./src/styles/ToggleElement.scss?80e5","webpack:///./src/styles/ToggleElement.scss","webpack:///./src/styles/CatalogItemDetailsEditor.scss?64fd","webpack:///./src/styles/CatalogItemDetailsEditor.scss","webpack:///./src/images/arrow614.svg","webpack:///./src/styles/DetailsPanel.scss?122d","webpack:///./src/styles/DetailsPanel.scss","webpack:///./src/components/ModalOverlay.js","webpack:///./src/stores/ModalOverlayStore.js","webpack:///./src/styles/ModalOverlay.scss?5be7","webpack:///./src/styles/ModalOverlay.scss","webpack:///./src/components/ComposerAppToolbar.js","webpack:///./src/styles/ComposerAppToolbar.scss?edf1","webpack:///./src/styles/ComposerAppToolbar.scss","webpack:///./src/images/floppy13.svg","webpack:///./src/images/cascade.svg","webpack:///./src/images/link56.svg","webpack:///./src/images/code41.svg","webpack:///./~/normalize.css/normalize.css?39c4","webpack:///./~/normalize.css/normalize.css","webpack:///./src/styles/AppRoot.scss?d0f0","webpack:///./src/styles/AppRoot.scss"],"names":[],"mappings":";AAAA;AACA,8FAAsF;AACtF;AACA;AACA;;AAEA,oDAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kDAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;AACA,aAAK;AACL;AACA;AACA,aAAK;AACL;AACA;AACA;AACA,cAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA,sDAA8C;AAC9C;AACA,qCAA6B;;AAE7B,+CAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAM;AACN,aAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAM;AACN;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;AACA;;AAEA,8CAAsC;AACtC;AACA;AACA,qCAA6B;AAC7B,qCAA6B;AAC7B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAAoB,gBAAgB;AACpC;AACA;AACA;AACA,aAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,4BAAoB,gBAAgB;AACpC;AACA,aAAK;AACL;AACA;AACA,aAAK;AACL;AACA;AACA,aAAK;AACL;AACA;AACA;AACA,aAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;AACA,aAAK;AACL;AACA;AACA;AACA,aAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,yBAAiB,8BAA8B;AAC/C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0BAAkB,qBAAqB;AACvC;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;;AAEA,4DAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAAmB,2BAA2B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,0BAAkB,cAAc;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,yBAAiB,4BAA4B;AAC7C;AACA;AACA;AACA;AACA;AACA,cAAM;AACN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,0BAAkB,4BAA4B;AAC9C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,0BAAkB,4BAA4B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAAmB,uCAAuC;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAAmB,uCAAuC;AAC1D;AACA;AACA;AACA;AACA;AACA,2BAAmB,sBAAsB;AACzC;AACA;AACA;AACA,eAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAiB,wCAAwC;AACzD;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;AACA;AACA,eAAO;AACP;AACA;AACA;AACA,cAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,8CAAsC,uBAAuB;;AAE7D;AACA;;;;;;;;;;;;;;;AC5hBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAI;AACJ,IAAG;AACH;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA,EAAC;AACD;AACA;;;;;;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA,IAAG;AACH;AACA;;;;;;;;;;;;;ACpBA,aAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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A;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,G;;;;;;ACjEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;AChCA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnCA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,G;;;;;;ACpEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,uC;;;;;;ACxCA;;AAEA;AACA;AACA;;AAEA,iD;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAY,OAAO;AACnB;AACA;AACA;AACA,kBAAiB,YAAY;AAC7B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,uBAAuB;AAClC;AACA,aAAY,GAAG;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA,YAAW,WAAW;AACtB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,8CAA8C;AACzD,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,WAAW;AACtB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,WAAW;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY,YAAY;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,eAAe;AAC1B,YAAW,OAAO;AAClB,YAAW,WAAW;AACtB,YAAW,0BAA0B;AACrC,YAAW,QAAQ;AACnB;AACA;AACA;AACA,wBAAuB;AACvB;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,eAAe;AAC1B,YAAW,OAAO;AAClB,YAAW,WAAW;AACtB,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,eAAe;AAC1B,YAAW,WAAW;AACtB;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ,kCAAkC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,SAAS;AACtB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,aAAa;AAC1B,cAAa,WAAW;AACxB,cAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,WAAW;AACxB,eAAc,OAAO;AACrB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,cAAa,aAAa;AAC1B,cAAa,WAAW;AACxB,cAAa,QAAQ;AACrB,eAAc,eAAe;AAC7B;AACA;AACA;AACA;AACA;AACA,qLAAoL;;AAEpL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,aAAa;AAC1B,cAAa,WAAW;AACxB,cAAa,UAAU;AACvB,eAAc,eAAe;AAC7B;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,aAAa;AAC1B,cAAa,WAAW;AACxB,cAAa,UAAU;AACvB,eAAc,eAAe;AAC7B;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oLAAmL;;AAEnL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,YAAY;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,WAAW;AACzB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,EAAE;AACf,eAAc;AACd;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,cAAa,eAAe;AAC5B,eAAc,OAAO;AACrB,eAAc,eAAe;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,2CAA0C;AAC1C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED,6B;;;;;;;ACj1BA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,wBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,4BAA2B;AAC3B;AACA;AACA;AACA,6BAA4B,UAAU;;;;;;;AC1FtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA4C;AAC5C,+BAA8B;AAC9B;AACA,iBAAgB;;AAEhB;AACA;AACA;AACA,aAAY;AACZ;AACA,sEAAqE;;AAErE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB,oDAAoD;AACvE;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA,8B;;;;;;;ACzOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,sDAAqD;AACrD,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA,2BAA0B;AAC1B;AACA;AACA;;AAEA,4B;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC;;AAExC;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAmB,yBAAyB;AAC5C;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;AACA;AACA;AACA,EAAC;;AAED,2C;;;;;;ACnUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,oCAAmC,gCAAgC;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA,iC;;;;;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,8BAA6B,sBAAsB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd,eAAc;AACd;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4B;;;;;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,uBAAsB;AACtB;AACA;AACA;AACA,oBAAmB;AACnB;AACA;AACA;AACA;AACA,yBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,gBAAe,MAAM;AACrB;AACA;AACA;;AAEA;AACA,gBAAe,OAAO;AACtB;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,UAAU;AACvB;AACA;AACA;;AAEA,yGAAwG;AACxG;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,UAAU;AACxB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA,iC;;;;;;;ACtRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+BAA8B;;AAE9B;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;AACA;AACA,mCAAkC;;AAElC;AACA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,sC;;;;;;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAW,eAAe;AAC1B,YAAW,QAAQ;AACnB,YAAW,SAAS;AACpB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,8BAA8B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,8BAA8B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY,EAAE;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,eAAe;AAC1B,aAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;;AAEH;AACA;;AAEA,mC;;;;;;;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,SAAS;AACpB,YAAW,EAAE;AACb,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kC;;;;;;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,uFAAsF,aAAa;AACnG;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAa;AACb;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA,0B;;;;;;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gC;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA,aAAY,WAAW;AACvB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,iC;;;;;;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,YAAW,MAAM;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA,qC;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA,yC;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,gBAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB,aAAY;AACZ;AACA;AACA;AACA;;AAEA,4B;;;;;;;AC/FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,kC;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,0BAAyB,8BAA8B;AACvD;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,yB;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,6CAA4C;AAC5C;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,mC;;;;;;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uC;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ;AACA;;AAEA;;AAEA,oC;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,uC;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,YAAW,EAAE;AACb,YAAW,cAAc;AACzB,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb;AACA,YAAW,EAAE;AACb,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,YAAW,QAAQ;AACnB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA,+B;;;;;;;ACtPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,6BAA4B,QAAQ,oBAAoB,EAAE;AAC1D;AACA,IAAG;AACH;AACA;AACA;;AAEA,oC;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,8C;;;;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,0BAA0B;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,gBAAgB;AACjC;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,QAAQ;AACnB,YAAW,SAAS;AACpB,YAAW,EAAE;AACb,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAc,OAAO;AACrB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,cAAa,EAAE;AACf,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,uC;;;;;;;AC7SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,cAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,iC;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA,mC;;;;;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,OAAO;AACpB,cAAa,WAAW;AACxB,gBAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,sC;;;;;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,2BAA2B;AACrC;AACA;AACA;AACA;AACA;AACA,SAAQ,OAAO;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA,0B;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,0DAA0D;AACvE,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,aAAa;AAC1B,cAAa,0BAA0B;AACvC,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,0BAA0B;AACvC;AACA;AACA;AACA;AACA;;AAEA;;AAEA,kC;;;;;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,2B;;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB,iBAAiB;AAC1C;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAa,QAAQ;AACrB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,WAAW;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,WAAW;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,6B;;;;;;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa,WAAW;AACxB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA,mC;;;;;;;AChQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,eAAe;AAC1B,YAAW,eAAe;AAC1B,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,sBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,2DAA0D;AAC1D;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,+B;;;;;;;AC9NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa,SAAS;AACtB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA,gC;;;;;;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,8B;;;;;;;ACtHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,4BAA4B;AACvC;AACA,aAAY,YAAY;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA,eAAc,0BAA0B;AACxC;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,SAAS;AACtB,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,cAAa,SAAS;AACtB,cAAa,SAAS;AACtB,cAAa,SAAS;AACtB,cAAa,SAAS;AACtB,cAAa,SAAS;AACtB;AACA,eAAc,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,6BAA4B,gCAAgC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,2DAA0D;AAC1D;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA4B,gCAAgC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,sDAAqD;AACrD;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,8B;;;;;;;ACtOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,8B;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB,aAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA,+B;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA,YAAW,EAAE;AACb,aAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA,6B;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,EAAE;AACb,aAAY,QAAQ;AACpB;AACA;;AAEA;AACA;AACA;;AAEA,yB;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,UAAU;AACrB,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,4C;;;;;;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;AACA,cAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,0DAA0D;AACvE,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,OAAO;AACpB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAsB;AACtB;AACA;AACA,IAAG;;AAEH;AACA;AACA,uEAAsE;AACtE;AACA;AACA,cAAa,OAAO;AACpB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gJAA+I;AAC/I;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,0BAA0B;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,0BAA0B;AACvC,cAAa,aAAa;AAC1B,cAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,8BAA6B;AAC7B,kCAAiC,kBAAkB;AACnD;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,aAAa;AAC1B,cAAa,OAAO;AACpB,cAAa,QAAQ;AACrB,cAAa,QAAQ;AACrB,cAAa,0BAA0B;AACvC,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,0BAA0B;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAAyD;AACzD;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,eAAc,eAAe;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA;;AAEA;;AAEA,0C;;;;;;;ACrrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,4C;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED,yC;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6C;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,QAAQ;AACnB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA,6C;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA,IAAG;AACH,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA,sC;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,aAAa;AACxB,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,aAAa;AACxB,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,UAAU;AACrB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAW,eAAe;AAC1B,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,uC;;;;;;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,WAAW;AACtB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,wBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA,+B;;;;;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,0DAAyD;AACzD;AACA;AACA,wCAAuC;AACvC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iCAAgC;AAChC,iBAAgB;;AAEhB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,kBAAiB,iBAAiB;AAClC;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qC;;;;;;;AC1WA;;AAEA;;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED;AACA;;AAEA,wB;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,+HAA8H;;AAE9H;AACA;AACA;;AAEA;AACA;;AAEA,oBAAmB,6BAA6B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wB;;;;;;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,cAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,0DAA0D;AACvE,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,UAAU;AACvB,cAAa,0BAA0B;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA,EAAC;;AAED,wC;;;;;;;AC9HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,WAAW;AACtB,YAAW,WAAW;AACtB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAa,cAAc;AAC3B,cAAa,cAAc;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA,sBAAqB,4BAA4B;AACjD;AACA;AACA;;AAEA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,EAAC;;AAED,wC;;;;;;;AChIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,cAAc;AAC3B,eAAc,kBAAkB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,uBAAuB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAqB,wBAAwB;AAC7C;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,yB;;;;;;;AChJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,UAAU;AACrB,aAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,wC;;;;;;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY;AACZ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;;AAEA,uC;;;;;;ACpFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,yBAAyB;AACpC,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,mBAAkB,aAAa;AAC/B;AACA;AACA;AACA;;AAEA,0B;;;;;;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA,gC;;;;;;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED,6C;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,WAAW;AACtB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iC;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,cAAa;AACb,aAAY;AACZ,aAAY;AACZ,eAAc;AACd,gBAAe;AACf;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA,8C;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,8CAA6C;AAC7C;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,EAAE;AACf,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,EAAE;AACf,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA,2CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED,wC;;;;;;;AChOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA,gD;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,mD;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,cAAc;AAC3B,cAAa,cAAc;AAC3B;AACA;AACA;AACA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED,uC;;;;;;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,G;;;;;;;AChGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,oCAAmC;AACnC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,uBAAsB,sBAAsB;AAC5C,wBAAuB,6BAA6B;AACpD,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA,uBAAsB,yBAAyB;AAC/C,wBAAuB,gCAAgC;AACvD,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA,uBAAsB,2BAA2B;AACjD,wBAAuB,kCAAkC;AACzD,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA,uBAAsB,4BAA4B;AAClD,wBAAuB,mCAAmC;AAC1D,MAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,eAAe;AAC1B,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,eAAe;AAC1B,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB,YAAW;AACX;AACA;AACA;AACA;AACA;;AAEA,yC;;;;;;ACpZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,eAAe;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,mC;;;;;;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,eAAe;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;;AAEA;AACA,kBAAiB,eAAe;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA,2C;;;;;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,yC;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,4C;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,eAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,QAAQ;AACnB;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,8BAA6B;AAC7B;;AAEA;AACA;;AAEA;;AAEA,iC;;;;;;;AChLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,sC;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C,gBAAgB;AAC9D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wB;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,uBAAsB,iBAAiB;AACvC,wBAAuB,wBAAwB;AAC/C,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB,YAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,MAAK;AACL;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,oC;;;;;;AChUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,eAAe;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iC;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,qC;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,uC;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC,6BAA6B,UAAU,0BAA0B,UAAU,uBAAuB,UAAU,8BAA8B,UAAU,0BAA0B,UAAU,0BAA0B,UAAU,+BAA+B;;AAEjS,0C;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,8BAA6B,qBAAqB;AAClD;AACA,IAAG;AACH;AACA,8BAA6B,qBAAqB;AAClD;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,wC;;;;;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,sC;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,mC;;;;;;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wC;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wC;;;;;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,eAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6C;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAW,0BAA0B;AACrC,aAAY,YAAY;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,8B;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA,+C;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,sBAAqB;;AAErB,uBAAsB,iBAAiB;AACvC,oBAAmB,cAAc;AACjC,mBAAkB,eAAe;;AAEjC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uHAAsH;AACtH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0HAAyH;AACzH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,yBAAyB;AACxC;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qNAAoN,YAAY;AAChO;AACA;AACA;AACA;AACA;AACA,qOAAoO,+BAA+B;AACnQ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,EAAC;;AAED;AACA;AACA;;AAEA,qDAAoD;AACpD;AACA,yBAAwB;;AAExB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,0DAA0D;AACvE,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC;AAClC;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,0DAA0D;AACvE,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,4DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,0DAA0D;AACvE,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,wBAAuB,wBAAwB;AAC/C;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,aAAa;AAC1B,cAAa,0DAA0D;AACvE,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,0BAA0B;AACvC,cAAa,aAAa;AAC1B,cAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,0BAA0B;AACvC,cAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,uCAAsC,KAAK;AAC3C;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAwD;AACxD,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,0BAA0B;AACvC,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB,sBAAsB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,EAAC;;AAED;;AAEA,oC;;;;;;;ACj8BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,iC;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,YAAW,WAAW;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA,4B;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,6CAA4C;;AAE5C;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAa,OAAO;AACpB,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iCAAgC,0BAA0B;AAC1D,qBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAqE;AACrE;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,EAAC;;AAED,wC;;;;;;;AC9KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,8B;;;;;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA,oC;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA,2B;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,EAAE;AACb,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAsB;AACtB;;AAEA;AACA;AACA;AACA;AACA;;AAEA,sC;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA,qC;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA,4B;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oC;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,iC;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,uCAAsC;AACtC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gCAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,kBAAkB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,gC;;;;;;;ACxJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA,mC;;;;;;;ACrIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR,4BAA2B;AAC3B,OAAM;AACN;AACA;AACA;AACA;AACA,8BAA6B,KAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,2BAA0B;AAC1B,MAAK;AACL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,sBAAsB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA,oBAAmB,2BAA2B;AAC9C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA,oBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iC;;;;;;ACnWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gC;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,wBAAwB;AAC/C;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA,2BAA0B;AAC1B,IAAG;;AAEH;AACA,+BAA8B,2CAA2C;;AAEzE;AACA,iBAAgB;AAChB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,iC;;;;;;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,UAAU;AACrB,YAAW,GAAG;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,GAAG;AACd,YAAW,iBAAiB;AAC5B,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,GAAG;AACd,YAAW,UAAU;AACrB,YAAW,GAAG;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,GAAG;AACd,YAAW,iBAAiB;AAC5B,YAAW,EAAE;AACb,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,GAAG;AACd,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gC;;;;;;ACrLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,EAAE;AACb,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAW,GAAG;AACd,YAAW,QAAQ;AACnB,YAAW,UAAU;AACrB,YAAW,GAAG;AACd;AACA,aAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAuB;AACvB;;AAEA;AACA,oBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2LAA2L,yCAAyC;AACpO;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,GAAG;AACd,YAAW,UAAU;AACrB,YAAW,GAAG;AACd,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,sC;;;;;;;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAiB,2BAA2B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA,YAAW,kBAAkB;AAC7B,YAAW,QAAQ;AACnB,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAe,sBAAsB;AACrC;AACA;AACA,gBAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAoB;AACpB;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,iCAAgC;AAChC;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,iC;;;;;;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uCAAsC;AACtC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gCAA+B;AAC/B;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,mC;;;;;;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,iBAAgB,MAAM;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,gBAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,gBAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,eAAe;AAC9B,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,eAAe;AAC9B,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,gBAAe,eAAe;AAC9B,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,gBAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,kC;;;;;;;AC/eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wKAAuK;AACvK;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,QAAQ;AACrB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,QAAQ;AACrB,cAAa,QAAQ;AACrB,cAAa,0BAA0B;AACvC,cAAa,OAAO;AACpB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uC;;;;;;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,YAAW,SAAS;AACpB,YAAW,gBAAgB;AAC3B,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,wKAAuK;AACvK;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kC;;;;;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB,kBAAkB;AACnC;AACA;AACA;AACA;;AAEA;AACA;;AAEA,+B;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,EAAE;AACb,aAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;;AAEA,+BAA8B;AAC9B;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAiB,kCAAkC;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA,qC;;;;;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA,gC;;;;;;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,qBAAqB;AAChC,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6C;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iC;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,yBAAwB,eAAe;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B,KAAK;AAClC;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,QAAQ;AACrB,cAAa,QAAQ;AACrB,eAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,QAAQ;AACrB,cAAa,QAAQ;AACrB,cAAa,0BAA0B;AACvC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,QAAQ;AACrB,cAAa,QAAQ;AACrB,cAAa,WAAW;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,0BAA0B;AACvC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,sBAAqB,mBAAmB;AACxC;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,8CAA6C;AAC7C,IAAG;AACH;AACA;AACA;AACA;AACA,yCAAwC;AACxC,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,sCAAqC;AACrC,IAAG;AACH;AACA;AACA,IAAG;AACH,2BAA0B;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA,6HAA4H;AAC5H;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+OAA8O;;AAE9O;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;AACA,+NAA8N;AAC9N;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yFAAwF,aAAa;AACrG;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;;AAEA,6B;;;;;;;AClwBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,gBAAgB;AAC3B;AACA,YAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,wIAAuI;AACvI;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iC;;;;;;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa,WAAW;AACxB,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,UAAU;AACvB;AACA;AACA,0DAAyD;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,WAAW;AACxB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uC;;;;;;;ACrHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,UAAU;AACxB;AACA;AACA;AACA,cAAa,UAAU;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAc,cAAc;AAC5B;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,eAAc,OAAO;AACrB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,4C;;;;;;ACtJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA,0BAAyB;AACzB,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA,sC;;;;;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,WAAW;AACtB,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,WAAW;AACtB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,uBAAuB;AAClC,YAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,uBAAuB;AAClC,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,cAAa,WAAW;AACxB;AACA;;AAEA;AACA,cAAa,uBAAuB;AACpC,cAAa,OAAO;AACpB;AACA;AACA;;AAEA,oC;;;;;;ACnNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,uBAAuB;AAClC,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,uBAAuB;AAClC,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,uBAAuB;AAClC,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,4C;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA,mC;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,uBAAsB,iBAAiB;AACvC,wBAAuB,wBAAwB;AAC/C,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B,iBAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,WAAW;AACtB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB,YAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA,oC;;;;;;ACxMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,uC;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,uBAAsB,gBAAgB;AACtC,wBAAuB,uBAAuB;AAC9C;AACA,IAAG;AACH;AACA;AACA,uBAAsB,eAAe;AACrC,wBAAuB,sBAAsB;AAC7C;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ACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,2BAA0B,gBAAgB;AAC1C;;AAEA;;AAEA;;AAEA;AACA,cAAa,OAAO;AACpB,cAAa,eAAe;AAC5B,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,eAAc,EAAE;AAChB,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,oC;;;;;;;AC1kBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,0C;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,sC;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,yC;;;;;;ACpFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,mC;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,8B;;;;;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,qC;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,sC;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA,sC;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,uC;;;;;;AC9HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;AACA,sEAAqE,aAAa;AAClF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB;AACvB,wBAAuB;AACvB,qBAAoB;AACpB,qBAAoB;AACpB,qBAAoB;AACpB,2BAA0B;AAC1B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA,mC;;;;;;AC5OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,yBAAyB;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP,MAAK;AACL,IAAG;AACH;AACA;;AAEA;AACA;AACA;;AAEA,kBAAiB,yBAAyB;AAC1C;AACA,2BAA0B;;AAE1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA,kBAAiB,yBAAyB;AAC1C;AACA,2BAA0B;AAC1B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAwB;;AAExB;AACA;AACA;AACA;AACA,oBAAmB,yBAAyB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,2C;;;;;;ACtMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,iC;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,oC;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,2B;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,wD;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,iC;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,YAAW,aAAa;AACxB,aAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,aAAa;AACxB,aAAY,OAAO;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,G;;;;;;;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,8C;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAc,MAAM;AACpB;AACA;AACA;AACA,IAAG;;AAEH;AACA,eAAc,OAAO;AACrB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,kD;;;;;;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,wB;;;;;;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED,oC;;;;;;;AChLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,aAAa;AACxB,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,aAAa;AACxB,YAAW,EAAE;AACb,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gGAA+F;AAC/F;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,UAAU;AACrB,YAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8IAA6I;AAC7I;AACA,QAAO;AACP;AACA;AACA,uIAAsI;AACtI;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,aAAa;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB,sBAAsB;AAC3C;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA,oBAAmB,sBAAsB;AACzC;AACA;AACA;AACA;AACA;;AAEA;;AAEA,wC;;;;;;;ACxRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,SAAS;AACpB,YAAW,EAAE;AACb,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4B;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,aAAY,eAAe;AAC3B;AACA;AACA;AACA;AACA;AACA;;AAEA,4B;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,EAAE;AACb,YAAW,SAAS;AACpB,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,6B;;;;;;;AC/CA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,gBAAe,oJAAoJ,MAAM,qBAAqB,aAAa,EAAE,YAAY,cAAc,EAAE,EAAE,yEAAyE,0CAA0C,mCAAmC,cAAc,EAAE,sBAAsB,iCAAiC,EAAE,sCAAsC,sDAAsD;AACtiB,aAAY,mIAAmI,MAAM,uBAAuB,aAAa,EAAE,YAAY,cAAc,EAAE,EAAE,iCAAiC,oCAAoC,iCAAiC,cAAc,EAAE,oFAAoF;AACna,cAAa,4IAA4I,MAAM,sBAAsB,aAAa,EAAE,YAAY,cAAc,EAAE,EAAE,kCAAkC,sCAAsC,iCAAiC,aAAa,EAAE,iCAAiC,cAAc,EAAE,wFAAwF;;AAEne;AACA;AACA;AACA;AACA;AACA,6CAA4C,gCAAgC;AAC5E,+BAA8B,cAAc;AAC5C;AACA,QAAO,YAAY;AACnB;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,kDAAiD,QAAQ;AACzD;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,IAAG;AACH;AACA,kDAAiD,QAAQ;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,kDAAiD,gBAAgB;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,yBAAwB;AACxB;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,wBAAuB,iBAAiB;AACxC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAkF,sCAAsC,EAAE;;AAE1H;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sDAAqD;AACrD,sEAAqE;AACrE;AACA;AACA,yDAAwD;AACxD,+EAA8E;AAC9E;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,2BAA0B,mBAAmB;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C,gCAAgC;AAC9E,UAAS;;AAET;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,wBAAuB,YAAY;AACnC;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,wBAAuB,YAAY;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,wBAAuB,YAAY;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,wBAAuB,YAAY;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,mGAAkG,aAAa,EAAE;AACjH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;;AAEA,eAAc,YAAY;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,6GAA4G,aAAa,EAAE;AAC3H;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAc,YAAY;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA,sCAAqC,WAAW;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,kBAAkB;AACzC;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,EAAC;AACD,mCAAkC,iBAAiB;;AAEnD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,yBAAwB,mBAAmB;AAC3C,qCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC,cAAc;AACtD;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,EAAC;AACD;AACA,sEAAqE,2CAA2C;AAChH;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B,mBAAmB;AAC9C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4BAA2B,qBAAqB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC;AACxC,2CAA0C,aAAa;AACvD,cAAa;AACb,MAAK;AACL;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,uCAAsC,wBAAwB;AAC9D;AACA;AACA;;AAEA;AACA;AACA,mBAAkB,EAAE,SAAS,EAAE;AAC/B;AACA,uBAAsB,EAAE;AACxB,uBAAsB,EAAE;AACxB;AACA,wBAAuB,EAAE;AACzB,wBAAuB,EAAE;AACzB;AACA,4BAA2B,EAAE;AAC7B,iCAAgC,GAAG;AACnC;AACA;AACA;AACA;AACA;AACA,2BAA0B,EAAE;AAC5B,4BAA2B,EAAE;AAC7B;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,6CAA4C;AAC5C;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAoC,mBAAmB;;AAEvD;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,+BAA8B;AAC9B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA,oCAAmC,uBAAuB;;AAE1D;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA4E;AAC5E;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C,0BAA0B;AACrE;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA,+DAA8D,WAAW;AACzE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;;;;;;ACpsDD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,8B;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2C;;;;;;ACvGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA4C,gBAAgB,UAAU,GAAG;AACzE,IAAG;AACH;AACA;AACA;AACA,MAAK,UAAU;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK,UAAU;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA,EAAC;;AAED;AACA;AACA,2BAA0B,SAAS;AACnC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,UAAU;AACnB;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA,8BAA6B,kCAAiC;;AAE9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,sCAAsC;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,WAAW;AACpB;AACA;AACA,EAAC;;AAED;AACA,6BAA4B,gBAAgB,kBAAkB,GAAG;;AAEjE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACnRD;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAqF,uBAAuB;AAC5G,oEAAmE;AACnE,iEAAgE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd,eAAc;AACd,eAAc;AACd,eAAc;AACd,gBAAe;AACf,gBAAe;AACf,0B;;;;;;ACxCA;AACA;AACA;AACA,wCAAuC,gC;;;;;;ACHvC,8BAA6B;AAC7B,sCAAqC,gC;;;;;;ACDrC;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA,G;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACPA;AACA;AACA,kCAAiC,QAAQ,gBAAgB,UAAU,GAAG;AACtE,EAAC,E;;;;;;ACHD;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,G;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,EAAC;AACD;AACA,EAAC,E;;;;;;AC1BD;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACnBA;AACA;AACA;AACA,G;;;;;;ACHA,gF;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACNA;AACA;AACA,G;;;;;;ACFA,wBAAuB;AACvB;AACA;AACA,G;;;;;;ACHA,kBAAiB;;AAEjB;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,G;;;;;;ACfA;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACLA;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACNA;AACA;AACA;AACA;AACA,4DAA2D;AAC3D,G;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,eAAe;AACxB;AACA;AACA;AACA,uCAAsC;AACtC;AACA,+BAA8B;AAC9B,8BAA6B;AAC7B,gCAA+B;AAC/B,oCAAmC;AACnC,UAAS,+BAA+B;AACxC;AACA;AACA;AACA;AACA,G;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,G;;;;;;ACfA;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACNA;AACA;AACA,oDAAmD;AACnD;AACA,wCAAuC;AACvC,G;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK,WAAW,eAAe;AAC/B;AACA,MAAK;AACL;AACA,G;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4BAA2B;AAC3B,qBAAoB,4BAA4B,SAAS,IAAI;AAC7D,IAAG;AACH,EAAC;AACD;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,+DAA8D;AAC9D;AACA,MAAK;AACL;AACA,uBAAsB,iCAAiC;AACvD,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAoD,KAAK,QAAQ,iCAAiC;AAClG,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH,yBAAwB,eAAe,EAAE;AACzC,yBAAwB,gBAAgB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA,iCAAgC,gBAAgB;;AAEhD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA,8EAA6E,sBAAsB;;AAEnG;AACA;AACA;AACA;AACA;AACA,2C;;;;;;AClOA;AACA;AACA;;AAEA;AACA,mEAAkE,+BAA+B;AACjG,G;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACTA;AACA;AACA;AACA,mBAAkB;;AAElB;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA,G;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACbA,wB;;;;;;ACAA;AACA;;AAEA,2CAA0C,iCAAqC,E;;;;;;ACH/E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC,UAAU,EAAE;AAC9C,cAAa,gCAAgC;AAC7C,EAAC,oCAAoC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,iB;;;;;;AChCD;AACA;AACA,+BAA8B,6BAA8B,E;;;;;;ACF5D;AACA;AACA;AACA,G;;;;;;ACHA;AACA;AACA,+BAA8B,6CAA6C,E;;;;;;ACF3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA,QAAO,UAAU,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,MAAK,GAAG;AACR;AACA,G;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,E;;;;;;ACTA;AACA;AACA;AACA;AACA,0BAAyB,kBAAkB,EAAE;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACfA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA,oDAAmD,OAAO,EAAE;AAC5D,G;;;;;;ACTA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;AACA,EAAC,E;;;;;;ACHD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACfD;AACA;AACA;AACA;AACA;AACA;AACA,6EAA4E;AAC5E;AACA;AACA;AACA;AACA;AACA,GAAE,E;;;;;;ACZF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAkD;AAClD,MAAK;AACL;AACA,wCAAuC,cAAc,OAAO;AAC5D,wCAAuC,cAAc,OAAO;AAC5D;AACA;AACA,oEAAmE,OAAO;AAC1E;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC,0BAA0B,EAAE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,E;;;;;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,2B;;;;;;AC5BA;AACA;;AAEA,+BAA8B,0BAA0B,E;;;;;;ACHxD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;;AAEA,+BAA8B,oCAAqC,E;;;;;;ACHnE;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACLA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACTD;AACA;;AAEA,+BAA8B,mCAAmC,E;;;;;;ACHjE;AACA;;AAEA,+BAA8B,oCAAoC,E;;;;;;ACHlE;AACA;;AAEA,+BAA8B,uBAAuB,E;;;;;;ACHrD;AACA;;AAEA,+BAA8B,mBAAmB,E;;;;;;ACHjD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACbD;AACA;AACA;AACA,G;;;;;;ACHA;AACA;;AAEA;AACA;AACA;;AAEA,6BAA4B,aAAa,E;;;;;;ACPzC;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;AACA;AACA,G;;;;;;ACHA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;;AAEA,6BAA4B,gCAAiC,E;;;;;;ACH7D;AACA;AACA;AACA,G;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACzBD;AACA;AACA;;AAEA;AACA,yCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,EAAC,E;;;;;;ACzBD;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;AChBD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA,6BAA4B,gCAAiC,E;;;;;;ACH7D;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;;AAEA,6BAA4B,+BAA+B,E;;;;;;ACH3D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACdD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACXD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,EAAC,E;;;;;;ACvBD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,EAAC,E;;;;;;AClBD;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACND;AACA;;AAEA;AACA;AACA,8BAA6B;AAC7B,eAAc;AACd;AACA,EAAC;AACD;AACA;AACA;AACA,gCAA+B;AAC/B;AACA;AACA,WAAU;AACV,EAAC,E;;;;;;AChBD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6BAA4B,aAAa;;AAEzC;AACA;AACA;AACA;AACA;AACA,yCAAwC,oCAAoC;AAC5E,6CAA4C,oCAAoC;AAChF,MAAK,2BAA2B,oCAAoC;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB,mBAAmB;AACrC;AACA;AACA,oCAAmC,2BAA2B;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,G;;;;;;ACjEA,qB;;;;;;ACAA;AACA;AACA;AACA;AACA;;AAEA;AACA,8FAAkF,aAAa,EAAE;;AAEjG;AACA,wDAAuD,0BAA0B;AACjF;AACA,G;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACpBD,uBAAsB;AACtB;AACA;;AAEA;AACA;AACA;AACA,G;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,MAAK,UAAU;AACf,IAAG;AACH,G;;;;;;ACXA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACXD;;AAEA;AACA;AACA;AACA,EAAC,E;;;;;;ACLD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO,MAAM;AACb;AACA,G;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;AClBD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA2E,kBAAkB,EAAE;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAoD,gCAAgC;AACpF;AACA;AACA,MAAK;AACL;AACA,kCAAiC,gBAAgB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;;;ACnCD;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,G;;;;;;ACXA;AACA;AACA;AACA;;AAEA;AACA;AACA,G;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACPA;AACA;;AAEA;AACA;AACA,gCAA+B,qBAAqB;AACpD,gCAA+B,SAAS,EAAE;AAC1C,EAAC,UAAU;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA,4BAA2B,aAAa;AACxC,gCAA+B,aAAa;AAC5C;AACA,IAAG,UAAU;AACb;AACA,G;;;;;;ACpBA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;AClBD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iCAAgC;AAChC,eAAc;AACd,kBAAiB;AACjB;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;;AAEA;AACA;AACA,6B;;;;;;ACjCA;AACA;AACA;AACA,6FAAuF;AACvF;AACA;AACA,G;;;;;;ACNA;AACA,WAAU;AACV,G;;;;;;ACFA,mC;;;;;;ACAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAoB,aAAa;AACjC,IAAG;AACH,G;;;;;;ACZA;AACA;;AAEA,8BAA6B,qCAA6C;;AAE1E,wC;;;;;;ACLA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,G;;;;;;AC1BA;AACA;;AAEA,8BAA6B,+BAAgC;;AAE7D,kC;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC,gBAAgB,EAAE;AACxD;AACA;AACA;AACA;AACA,EAAC;AACD,+B;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC,gBAAgB,EAAE;AACxD;AACA;AACA;AACA;AACA,EAAC;AACD,+B;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAsB,kBAAkB,EAAE;AAC1C,yBAAwB,gBAAgB;AACxC,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;;AAEA,oC;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACLD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACTD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,4BAA2B,UAAU;AACrC;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,+BAA8B,yCAAyC;AACvE;AACA;AACA,0BAAyB,oCAAoC;AAC7D;AACA;AACA,G;;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACXD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACTD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACXD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAA+B;AAC/B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,cAAc,WAAW;AACnE;AACA,yCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,6BAA4B;AAC5B,yBAAwB,2BAA2B;AACnD,QAAO;AACP;AACA;AACA,IAAG,UAAU,eAAe;AAC5B;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,YAAW;AACX,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA,4CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,oBAAmB,gCAAgC;AACnD,UAAS;AACT;AACA;AACA,QAAO;AACP,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA;AACA;AACA,wBAAuB,qBAAqB;AAC5C;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;AACH,mBAAkB,oBAAoB,KAAK;AAC3C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA,2DAA0D,WAAW;AACrE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA,oCAAmC;AACnC,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA,MAAK;AACL;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA,EAAC,E;;;;;;AChSD;AACA;AACA;AACA,G;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAgE,gBAAgB;AAChF;AACA,IAAG,2CAA2C,gCAAgC;AAC9E;AACA;AACA,G;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA,sCAAqC,oBAAoB,EAAE;AAC3D;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA,IAAG;AACH,G;;;;;;AC/DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AC1EA;AACA;AACA;AACA;AACA,G;;;;;;ACJA;AACA;;AAEA;AACA;AACA,yBAAwB,mEAAmE;AAC3F,EAAC;AACD;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,EAAC,gB;;;;;;AChBD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,uBAAsB,OAAO;AAC7B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gCAA+B;AAC/B,2BAA0B;AAC1B,2BAA0B;AAC1B,sBAAqB;AACrB;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,8DAA6D,OAAO;AACpE;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB,sBAAqB;AACrB,2BAA0B;AAC1B,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,G;;;;;;AC9JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO,kCAAkC,gCAAgC,aAAa;AACtF,8BAA6B,mCAAmC,aAAa;AAC7E;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,4DAA2D;AAC3D;AACA,iDAAgD,iBAAiB,EAAE;AACnE;AACA,2DAA0D,aAAa,EAAE;AACzE;AACA;AACA,2B;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,G;;;;;;AC9EA;AACA;;AAEA;AACA;AACA,yBAAwB,mEAAmE;AAC3F,EAAC;AACD;AACA;AACA;AACA;AACA,EAAC,U;;;;;;ACXD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6BAA4B,mEAAmE;AAC/F,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL,IAAG;AACH,E;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,2BAA0B;AAC1B;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA;AACA,MAAK;AACL,4CAA2C;AAC3C;AACA,MAAK;AACL,IAAG;AACH;AACA;AACA,G;;;;;;ACrFA;AACA;;AAEA;AACA;AACA,6BAA4B,mEAAmE;AAC/F,EAAC;AACD;AACA;AACA;AACA;AACA,EAAC,qB;;;;;;ACXD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,0CAAyC;AACzC,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACrCD;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAqC,MAAM,SAAS,OAAO,SAAS;AACpE,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,EAAC,E;;;;;;AClBD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACVD;AACA;AACA;AACA;AACA;AACA,gCAA+B;AAC/B,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC;AACtC,IAAG;AACH,WAAU;AACV,EAAC;;AAED;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACzBD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gCAA+B,SAAS,E;;;;;;ACnBxC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACTD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACTD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACPD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACVD;AACA;;AAEA,gCAA+B,kCAAiC,E;;;;;;ACHhE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACRA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,EAAC,E;;;;;;ACfD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gCAA+B,SAAS,E;;;;;;AC5BxC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,EAAC,E;;;;;;ACdD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED,sC;;;;;;ACXA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACTD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AChBA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACND;AACA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACND;AACA;AACA,0DAAwD;;AAExD,+BAA8B,4BAA4B,gBAAgB,GAAG;;;;;;;ACJ7E;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,G;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,EAAC,E;;;;;;ACtBD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,G;;;;;;ACfA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACRD;AACA;;AAEA,4BAA2B,wCAAiD,E;;;;;;ACH5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACVA;AACA;;AAEA,4BAA2B,wCAAiD,E;;;;;;ACH5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,sC;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACnBD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,WAAW;AAC9B;AACA;AACA;AACA,G;;;;;;ACvBA,2C;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA,EAAC,E;;;;;;ACLD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0E;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,iBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd,MAAK;AACL,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,WAAW;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,4BAA2B;AAC3B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;AACT;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;;AAEA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kCAAiC,kBAAkB;AACnD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,kBAAiB;;AAEjB;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yBAAwB,iBAAiB;AACzC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,aAAY;AACZ;AACA;;AAEA;AACA,aAAY;AACZ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+CAA8C,QAAQ;AACtD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa;AACb;AACA;;AAEA,YAAW;AACX;AACA;AACA;;AAEA,YAAW;AACX;AACA;AACA;;AAEA,YAAW;AACX;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,+CAA8C,QAAQ;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,MAAK;;AAEL;AACA,+CAA8C,QAAQ;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,+CAA8C,QAAQ;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACzoBA,aAAY,CAAC;;;;;AAEb,KAAI,GAAG,GAAG,mBAAO,CAAC,GAAK,CAAC,CAAC;AACzB,KAAI,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;;mBAEL,GAAG,C;;;;;;;;;ACZlB;AACA;;AAEA;AACA;AACA,EAAC;AACD;;AAEA,yCAAwC,mBAAmB,4BAA4B,kDAAkD,oCAAoC,gBAAgB,kDAAkD,8DAA8D,0BAA0B,4CAA4C,uBAAuB,kBAAkB,EAAE,OAAO,cAAc,gBAAgB,gBAAgB,eAAe,oBAAoB,EAAE,EAAE,4BAA4B,mBAAmB,EAAE,OAAO,uBAAuB,4BAA4B,kBAAkB,EAAE,8BAA8B,EAAE,EAAE;;AAE3pB,kCAAiC,2CAA2C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,uDAAuD,2DAA2D,EAAE,EAAE,yDAAyD,qEAAqE,6DAA6D,oBAAoB,GAAG,EAAE;;AAEljB,uCAAsC,uCAAuC,kBAAkB;;AAE/F,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q,mCAAkC,0BAA0B,0CAA0C,gBAAgB,uBAAuB,aAAa,EAAE,OAAO,wBAAwB,EAAE;;AAE7L,2CAA0C,+DAA+D,qGAAqG,EAAE,yEAAyE,eAAe,yEAAyE,EAAE,EAAE,uHAAuH;;AAE5e,kDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA,0EAAyE;;AAEzE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,QAAO;AACP;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA,yFAAwF,aAAa;AACrG;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA,6FAA4F,eAAe;AAC3G;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA,sBAAqB;;AAErB,gFAA+E,eAAe;AAC9F;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA,+EAA8E;;AAE9E;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,iFAAgF,eAAe;AAC/F;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,0FAAyF,eAAe;AACxG;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA,cAAa;;AAEb;AACA,YAAW;;AAEX,6GAA4G,eAAe;AAC3H;AACA;;AAEA;AACA,UAAS;AACT,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,IAAG;AACH;AACA;AACA,+EAA8E,eAAe;AAC7F;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH;AACA;AACA,+EAA8E,eAAe;AAC7F;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;AACA;AACA,6FAA4F,eAAe;AAC3G;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA,iGAAgG,iBAAiB;AACjH;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,2BAA0B,uBAAuB;AACjD;AACA;AACA;AACA,IAAG;;AAEH;AACA,EAAC;;AAED;AACA,qC;;;;;;AC3UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA,uBAAsB;AACtB;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,SAAS;AACtB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,cAAc;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;;;;;ACzPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sCAAqC;AACrC;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,2CAA0C,yBAAyB,EAAE;AACrE;AACA;;AAEA,2BAA0B;AAC1B;AACA;AACA;;AAEA;;;;;;;ACpDA;;AAEA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;;AAEA,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,UAAS;AACT;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG,IAAI;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG,IAAI;AACP,E;;;;;;ACvEA;;AAEA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;;AAEA;AACA,uFAAsF,aAAa;AACnG;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA,E;;;;;;AC1CA;;AAEA;AACA;AACA,EAAC;AACD;;AAEA,wCAAuC,mBAAmB,4BAA4B,iDAAiD,oCAAoC,gBAAgB,kDAAkD,8DAA8D,0BAA0B,4CAA4C,uBAAuB,kBAAkB,EAAE,OAAO,aAAa,gBAAgB,gBAAgB,eAAe,oBAAoB,EAAE,EAAE,4BAA4B,mBAAmB,EAAE,OAAO,uBAAuB,4BAA4B,kBAAkB,EAAE,8BAA8B,EAAE,EAAE;;AAExpB;AACA;AACA;AACA;;AAEA,uCAAsC,uCAAuC,kBAAkB;;AAE/F,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q,kDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ,2CAA0C,+DAA+D,qGAAqG,EAAE,yEAAyE,eAAe,yEAAyE,EAAE,EAAE,uHAAuH;;AAE5e;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,wBAAuB;AACvB,wBAAuB;AACvB,+BAA8B;AAC9B,sBAAqB;AACrB;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,4BAA2B;AAC3B;;AAEA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;;AAEA,sCAAqC;AACrC;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA,8HAA6H;AAC7H;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,yEAAwE,eAAe;AACvF;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH,6FAA4F,aAAa;AACzG;AACA;;AAEA;;AAEA;AACA;;AAEA,8LAA6L,mBAAmB;;AAEhN;AACA,E;;;;;;ACtLA;;AAEA;AACA;AACA,EAAC;;AAED,oDAAmD,gBAAgB,sBAAsB,OAAO,2BAA2B,0BAA0B,yDAAyD,2BAA2B,EAAE,EAAE,EAAE,eAAe;;AAE9P;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG,IAAI;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA,kFAAiF,aAAa;AAC9F;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAiB;;AAEjB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,wB;;;;;;AC3GA;;AAEA;AACA;AACA,EAAC;;AAED,kCAAiC,2CAA2C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,uDAAuD,2DAA2D,EAAE,EAAE,yDAAyD,qEAAqE,6DAA6D,oBAAoB,GAAG,EAAE;;AAEljB,uCAAsC,uCAAuC,kBAAkB;;AAE/F,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q,kDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb,YAAW;AACX,UAAS;AACT;AACA;AACA,YAAW;AACX;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,EAAC;;AAED;AACA,qC;;;;;;ACjJA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;;AAEA;AACA;AACA;AACA,MAAK;AACL;;AAEA,WAAU;AACV;;AAEA,8B;;;;;;AC3BA;;AAEA;AACA;AACA,EAAC;;AAED,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q,uCAAsC,uCAAuC,kBAAkB;;AAE/F;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA,uEAAsE,aAAa;AACnF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA,2EAA0E,eAAe;AACzF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,MAAK,IAAI;;AAET;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA,qC;;;;;;AC7MA;;AAEA;AACA;AACA,EAAC;;AAED,kCAAiC,2CAA2C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,uDAAuD,2DAA2D,EAAE,EAAE,yDAAyD,qEAAqE,6DAA6D,oBAAoB,GAAG,EAAE;;AAEljB;;AAEA,wCAAuC,6BAA6B,YAAY,EAAE,OAAO,iBAAiB,mBAAmB,uBAAuB,4EAA4E,EAAE,EAAE,yBAAyB,eAAe,EAAE;;AAE9Q,kDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,EAAC;;AAED;AACA;AACA;;AAEA,eAAc;;AAEd;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,oEAAmE,aAAa;AAChF;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qC;;;;;;AC5FA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACrDA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,kC;;;;;;AC5CA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oC;;;;;;;;;;;ACRA,aAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;KAIQ,GAAG;WAAH,GAAG;yBAAH,GAAG;;;eAAH,GAAG;;4BAMP;AACf,WAAO,qBAAM,CAAC;IACd;;;wBAEW,GAAG,EAAE;AAChB,QAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACvC,YAAO;KACP;AACD,QAAI,GAAG,qCAA2B,EAAE;;AAEnC,YAAO,GAAG,CAAC,GAAG,CAAC;KACf;AACD,QAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE;;AAEnC,QAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;KACtB,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE;;AAE5C,QAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;KACvB,MAAM,IAAI,GAAG,YAAY,OAAO,EAAE;AAClC,QAAG,GAAG,YAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;KACtC;AACD,QAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACvC,YAAO;KACP;AACD,QAAM,GAAG,GAAG,QAAO,GAAG,yCAAH,GAAG,OAAK,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,IAAK,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAE,GAAG,GAAG,CAAC;AAC9G,QAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC5B,YAAO,GAAG,CAAC;KACX;IACD;;;+BAEkB,GAAG,EAAE;AACvB,WAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB;;;kCAEqB,GAAG,EAAE;AAC1B,WAAO,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;IAC5C;;;uBAxCyB;AACzB,WAAO,MAAM,CAAC;IACd;;;SAJmB,GAAG;;;mBAAH,GAAG,C;;;;;;;;;ACPxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAsE;AACtE,MAAK;AACL,yFAAwF;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAmD;AACnD;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA8E,SAAS;AACvF,wDAAuD,SAAS;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA4E;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA,yEAAwE;AACxE,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAgD,OAAO;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAiD,OAAO;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAkD,EAAE;AACpD,uBAAsB;AACtB;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C;AACA;AACA,yCAAwC,SAAS;AACjD;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C,0DAAyD,SAAS;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAgD;AAChD;AACA;AACA;AACA,qEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB,SAAS;AAC7B;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,qBAAoB,SAAS;AAC7B;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,qBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA,QAAO;AACP,qBAAoB,UAAU;AAC9B;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,eAAc,MAAM;AACpB;AACA;AACA,eAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAoC,OAAO;AAC3C;AACA;AACA,wCAAuC,OAAO;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C,6EAA4E,UAAU;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,uCAAsC,OAAO;AAC7C,iEAAgE,OAAO;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAoC,OAAO;AAC3C,yDAAwD,OAAO;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C;AACA;AACA;AACA,yCAAwC,SAAS;AACjD;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,mEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA2D,OAAO;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,YAAW;AACX;AACA,YAAW;AACX,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA4E;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C,OAAO;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C,OAAO;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C,OAAO;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAAyD;AACzD;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAsD,wCAAwC;AAC9F;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,iFAAiF;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C;AAC3C;AACA,UAAS,gBAAgB;AACzB;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA,mBAAkB,UAAU;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,oCAAmC;AACnC;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA0E;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,iDAAgD;AAChD,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,6BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,qDAAoD;AACpD;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB,EAAE;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C;AAC3C,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,uEAAsE,6BAA6B;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAAyD,OAAO;AAChE;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,iEAAgE,QAAQ;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,8DAA6D,OAAO;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C,OAAO;AACrD,YAAW;AACX;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,4CAA2C,QAAQ;AACnD,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,wCAAuC,OAAO;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA4B;AAC5B,6BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,OAAO;AAC9B,qEAAoE,OAAO;AAC3E;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,6CAA4C;AAC5C;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,gCAA+B,iCAAiC;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA,iCAAgC,QAAQ;AACxC,0BAAyB,8BAA8B;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB,cAAc;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,YAAW;AACX;AACA;AACA,YAAW;AACX;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC;AAClC;AACA;AACA;AACA,QAAO;AACP,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,+BAA8B,8BAA8B;AAC5D;AACA,gDAA+C;AAC/C,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,wCAAuC;AACvC,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAuC;AACvC,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,gCAA+B,OAAO;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,iBAAiB,OAAO;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA2B;AAC3B,4BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAiD,OAAO;AACxD;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA,8BAA6B;AAC7B,QAAO;AACP;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,4BAA2B;AAC3B;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL,yBAAwB,OAAO;AAC/B;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,WAAU,OAAO;AACjB,WAAU,OAAO;AACjB;AACA,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAqD,8BAA8B;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAqD,8BAA8B;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,oCAAmC;AACnC;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA,yBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,QAAO;AACP;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAAyD,OAAO,2DAA2D,iBAAiB,OAAO;AACnJ;AACA,0DAAyD,OAAO,2DAA2D,iBAAiB,OAAO;AACnJ;AACA,oDAAmD,OAAO,mDAAmD,iBAAiB,OAAO;AACrI;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA;AACA,kBAAiB,OAAO;AACxB,2BAA0B,OAAO;AACjC;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,kBAAiB,OAAO;AACxB,4BAA2B,OAAO;AAClC,wDAAuD,OAAO;AAC9D,2EAA0E,OAAO;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA,MAAK;AACL;AACA;AACA,kBAAiB,OAAO;AACxB,2BAA0B,OAAO;AACjC,2BAA0B,OAAO,yBAAyB,iBAAiB,OAAO;AAClF;AACA,kBAAiB,OAAO;AACxB;AACA,MAAK;AACL;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,MAAM;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA,iCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC,oBAAoB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,kFAAiF;AACjF;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,+EAA8E,OAAO;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,+BAA8B,OAAO;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAA+B,gCAAgC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,MAAM,qBAAqB,OAAO;AAClD;AACA,UAAS;AACT;AACA,iBAAgB,QAAQ,sBAAsB,OAAO;AACrD;AACA,oBAAmB,cAAc;AACjC,+BAA8B,kBAAkB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,6DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C;AACA,0DAAyD,SAAS;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C;AACA,0DAAyD,SAAS;AAClE;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,SAAS;AAC9C,0DAAyD,SAAS;AAClE;AACA;AACA;AACA;AACA,gDAA+C,SAAS;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAoC,OAAO;AAC3C;AACA,yDAAwD,OAAO;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,qCAAoC,OAAO;AAC3C;AACA,yDAAwD,OAAO;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb,YAAW;AACX,UAAS;AACT;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,YAAW;AACX;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,uCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAmD,0BAA0B;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;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A;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4CAA2C;AAC3C;AACA,4DAA2D;;AAE3D;AACA,oDAAmD;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,2BAA0B,MAAM,aAAa,OAAO;;AAEpD;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAe;AACf,eAAc;AACd,eAAc;AACd,iBAAgB;AAChB,gBAAe;AACf,gBAAe;AACf;;AAEA;AACA;AACA,WAAU;AACV,UAAS;AACT,UAAS;AACT,YAAW;AACX,WAAU;AACV,WAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,EAAE;AACf,cAAa,EAAE;AACf,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB,cAAa,SAAS;AACtB,cAAa,QAAQ;AACrB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB,cAAa,EAAE;AACf,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,EAAE;AACf,gBAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,EAAE;AACf,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,UAAU;AACvB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB,cAAa,OAAO;AACpB,cAAa,QAAQ;AACrB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,EAAE;AACf,gBAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB,cAAa,EAAE;AACf,gBAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB,cAAa,SAAS;AACtB,gBAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,gBAAe,SAAS;AACxB;AACA;AACA,eAAc,2BAA2B;AACzC;AACA;AACA,oBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA,OAAM;AACN;AACA;AACA,kCAAiC,6BAA6B;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gEAA+D;AAC/D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB,gBAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW;AACX;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB;AACA;AACA;;AAEA,oBAAmB;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB;AACA,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB;AACA,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,gBAAe,kBAAkB;AACjC,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,gBAAe,OAAO,WAAW;AACjC,kBAAiB,OAAO;AACxB;AACA;AACA,6BAA4B;;AAE5B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA,+CAA8C;AAC9C;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,qCAAoC,6BAA6B,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,oBAAoB;AACrC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,oBAAoB;AACrC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB;AACA,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,QAAQ;AACvB,gBAAe,QAAQ;AACvB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB;AACA,gBAAe,SAAS;AACxB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,6BAA6B;AAC5C,gBAAe,UAAU;AACzB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA,2DAA0D,2BAA2B,EAAE;;AAEvF;AACA,gEAA+D,wBAAwB,EAAE;AACzF,iBAAgB;AAChB,QAAO;;AAEP;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,gBAAe,QAAQ;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,MAAM;AACrB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,YAAY;AAC3B,kBAAiB,YAAY;AAC7B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,YAAY;AAC7B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,gBAAgB;AAC/B,gBAAe,OAAO;AACtB,gBAAe,EAAE;AACjB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,gBAAe,EAAE;AACjB,gBAAe,MAAM;AACrB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,QAAQ;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,gBAAgB;AAC/B,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,QAAQ;AACvB,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,EAAE;AACnB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,MAAM;AACrB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2CAA0C;AAC1C,yCAAwC;AACxC,gEAA+D;AAC/D,kEAAiE;AACjE;AACA;AACA,eAAc;AACd;;AAEA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,QAAQ;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,aAAa;AAC5B,gBAAe,MAAM;AACrB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,oCAAoC;AAC9C,WAAU,qCAAqC;AAC/C,WAAU;AACV;AACA;AACA;AACA,yCAAwC,qCAAqC;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,qCAAqC;AAC/C,WAAU,qCAAqC;AAC/C,WAAU;AACV;AACA;AACA;AACA,oCAAmC,oCAAoC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,WAAU,qCAAqC;AAC/C,WAAU,qCAAqC;AAC/C,WAAU;AACV;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,4BAA2B,kCAAkC;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,WAAU,oCAAoC;AAC9C,WAAU,qCAAqC;AAC/C,WAAU;AACV;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,gCAA+B,mCAAmC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,QAAQ;AACvB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,eAAe;AAC9B;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,eAAe;AAC9B;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,KAAK;AACpB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,qBAAqB;AACpC;AACA,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU,yCAAyC;AACtE;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,wBAAuB,UAAU,GAAG,UAAU,IAAI,UAAU;AAC5D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,EAAE;AACjB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,oCAAoC;AAC9C,WAAU,qCAAqC;AAC/C,WAAU;AACV;AACA;AACA;AACA,yCAAwC,qCAAqC;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,qCAAqC;AAC/C,WAAU,oCAAoC;AAC9C,WAAU;AACV;AACA;AACA;AACA,oCAAmC,oCAAoC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,QAAQ;AACvB,gBAAe,uBAAuB;AACtC,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,iBAAgB,SAAS,GAAG,SAAS,GAAG,SAAS;AACjD,gBAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,KAAK;AACpB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,MAAM;AACrB,gBAAe,MAAM;AACrB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,eAAc;AACd;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,WAAU,+BAA+B;AACzC,WAAU,+BAA+B;AACzC,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,yDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,KAAK;AACpB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC,4DAA4D;AAC9F;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,qCAAqC;AACpD;AACA,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,oCAAoC;AAC9C,WAAU;AACV;AACA;AACA;AACA,wBAAuB,oCAAoC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,8CAA8C;AACxD,WAAU;AACV;AACA;AACA;AACA,iCAAgC,4BAA4B;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA,WAAU,+CAA+C;AACzD,WAAU,gDAAgD;AAC1D,WAAU;AACV;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,gCAA+B,2BAA2B;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,OAAO;AACtB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA,WAAU,8CAA8C;AACxD,WAAU;AACV;AACA;AACA,qCAAoC,4BAA4B;AAChE;AACA;AACA,qCAAoC,6BAA6B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,oBAAoB;AACrC;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,mBAAkB,iBAAiB;AACnC;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,oBAAoB;AACrC;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,EAAE;AACjB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,4BAA4B;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,WAAU,4BAA4B;AACtC,WAAU;AACV;AACA;AACA;AACA,eAAc,UAAU,4BAA4B,YAAY,8BAA8B;AAC9F;AACA;AACA;AACA,SAAQ;AACR,eAAc,OAAO,4BAA4B,QAAQ,8BAA8B;AACvF;AACA;AACA;AACA,SAAQ;AACR,eAAc,OAAO,4BAA4B,QAAQ,8BAA8B;AACvF;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,sBAAsB;AACrC;AACA,gBAAe,KAAK;AACpB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,iBAAiB;AAC/B;AACA;AACA;AACA,WAAU,mBAAmB;AAC7B,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,gDAAgD;AAC1D,WAAU,+CAA+C;AACzD,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC,4BAA4B;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK,cAAc,iBAAiB,EAAE;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,aAAa;AAC5B,kBAAiB,MAAM;AACvB;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,kBAAiB,iBAAiB;AAClC;AACA;AACA,SAAQ,IAAI;AACZ,eAAc,iBAAiB;AAC/B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,+CAA+C;AACzD,WAAU;AACV;AACA;AACA;AACA,iCAAgC,4BAA4B;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,mCAAmC;AAC7C,WAAU;AACV;AACA;AACA;AACA,uBAAsB,oCAAoC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,WAAU,iBAAiB;AAC3B,WAAU,oBAAoB;AAC9B,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAgB;AAChB,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,yDAAyD;AACxE;AACA,kBAAiB,MAAM;AACvB;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU,8BAA8B;AACxC,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,6BAA6B;AAC5C,gBAAe,UAAU;AACzB,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU,8BAA8B;AACxC,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA,WAAU,kEAAkE;AAC5E,WAAU;AACV;AACA;AACA,gCAA+B,6BAA6B;AAC5D;AACA;AACA,gCAA+B,mBAAmB;AAClD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,qBAAoB,iCAAiC;AACrD,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,KAAK;AACpB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,qBAAqB;AACpC;AACA,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,KAAK;AACpB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,QAAQ;AACvB;AACA,gBAAe,OAAO;AACtB;AACA,gBAAe,QAAQ;AACvB;AACA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,+BAA8B,kCAAkC;AAChE;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,KAAK;AACpB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,gBAAe,KAAK;AACpB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,YAAY;AAC3B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,YAAY;AAC3B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,qBAAoB;AACpB;AACA;AACA;AACA,eAAc;AACd;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,yBAAyB;AACxC;AACA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,KAAK;AACpB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,KAAK;AACpB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,qBAAqB;AACpC;AACA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,QAAQ;AACvB;AACA,gBAAe,QAAQ;AACvB;AACA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,oCAAmC,6DAA6D;AAChG;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,qCAAoC;AACpC;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,QAAQ;AACvB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA,WAAU,mBAAmB;AAC7B,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA,WAAU,mBAAmB;AAC7B,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA,kCAAiC,kBAAkB,EAAE;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,8BAA6B,kBAAkB,EAAE;AACjD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB,SAAS;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA,sBAAqB;AACrB,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA,sBAAqB;AACrB;AACA,2BAA0B,YAAY;AACtC;AACA;AACA,2BAA0B,YAAY;AACtC;AACA;AACA;AACA,sBAAqB;AACrB,sBAAqB;AACrB;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,SAAS;AAC1B,eAAc;AACd;AACA,kBAAiB,SAAS;AAC1B,eAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,oBAAmB,mBAAmB,GAAG,iBAAiB;AAC1D;AACA;AACA;AACA,oBAAmB,YAAY,GAAG,YAAY;AAC9C;AACA;AACA;AACA,eAAc,WAAW,8BAA8B,GAAG,4BAA4B;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA,kBAAiB,mBAAmB,GAAG,YAAY,GAAG,iBAAiB;AACvE,eAAc;AACd;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA,kBAAiB,mBAAmB,GAAG,YAAY,GAAG,iBAAiB;AACvE,eAAc;AACd;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB,kBAAiB,OAAO;AACxB;AACA;AACA,oBAAmB,mBAAmB,GAAG,YAAY,GAAG,iBAAiB;AACzE,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB,kBAAiB,OAAO;AACxB;AACA;AACA,wBAAuB,UAAU,mBAAmB,EAAE,GAAG,UAAU,4BAA4B,EAAE;AACjG,eAAc,UAAU,8BAA8B;AACtD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,iBAAiB;AAClC;AACA;AACA;AACA,sBAAqB,4BAA4B;AACjD,sBAAqB,6BAA6B;AAClD,sBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,0BAAyB,2BAA2B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,iBAAiB;AAClC;AACA;AACA;AACA,sBAAqB,4BAA4B;AACjD,sBAAqB,6BAA6B;AAClD,sBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,8BAA6B,4BAA4B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,aAAa;AAC5B,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA,sBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,aAAa;AAC5B,kBAAiB,QAAQ;AACzB;AACA;AACA,sBAAqB,OAAO,OAAO,SAAS,EAAE;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,QAAQ;AACvB,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA,sBAAqB;AACrB;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,sCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA,mBAAkB,iBAAiB;AACnC;AACA,SAAQ;AACR,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,uBAAuB;AACtC;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA,qBAAoB,iBAAiB;AACrC;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA,sBAAqB,+BAA+B;AACpD,sBAAqB;AACrB;AACA;AACA;AACA;AACA,eAAc,2BAA2B;AACzC;AACA;;AAEA;AACA,iCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,8BAA8B;AAC7C;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA,sBAAqB;AACrB;AACA;AACA,eAAc;AACd;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA,iBAAgB,2BAA2B;AAC3C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,8BAA8B;AAC7C;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA,sBAAqB;AACrB;AACA;AACA,eAAc;AACd;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,aAAa;AAC5B,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA,sBAAqB,QAAQ,OAAO,+BAA+B,EAAE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,aAAa;AAC5B,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA,sBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,qBAAoB,iBAAiB;AACrC;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,QAAQ;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA,kCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wCAAuC,QAAQ;AAC/C;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,kBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,kBAAiB,sBAAsB;AACvC,sBAAqB,UAAU;AAC/B;AACA;AACA,uEAAsE,2BAA2B,EAAE;AACnG,kBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA,6DAA4D;AAC5D,kBAAiB,mBAAmB;AACpC;AACA;AACA;AACA,2CAA0C,OAAO;AACjD,kBAAiB,oBAAoB;AACrC;AACA;AACA;AACA,4CAA2C,YAAY;AACvD,2CAA0C,QAAQ;AAClD,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA,sDAAqD,2BAA2B,EAAE;AAClF,yCAAwC,aAAa,eAAe,EAAE;AACtE,kBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA,yDAAwD,qCAAqC;AAC7F;AACA;AACA;AACA;AACA,2DAA0D,qBAAqB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yCAAwC;;AAExC,6CAA4C;AAC5C;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,wBAAwB;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;;AAEP,oBAAmB;;AAEnB;AACA;AACA;AACA;AACA,+BAA8B,mBAAmB;AACjD;AACA;AACA;AACA;AACA,6CAA4C;;AAE5C;AACA,wDAAuD;AACvD;AACA;AACA,8BAA6B,EAAE;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C;AAC1C,gCAA+B,iCAAiC;AAChE,eAAc;AACd;AACA;AACA,uBAAsB;;AAEtB;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,cAAc;AAC7B,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,cAAc;AAC7B,iBAAgB,OAAO;AACvB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAiC;AACjC,cAAa,QAAQ,QAAQ,UAAU,SAAS,aAAa;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA,uCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,cAAc;AAC7B,iBAAgB,OAAO;AACvB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,gBAAe,EAAE;AACjB,iBAAgB,OAAO;AACvB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,gBAAe,4BAA4B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,WAAU,8CAA8C;AACxD,WAAU;AACV;AACA;AACA,mCAAkC,6BAA6B;AAC/D,gBAAe,6CAA6C;AAC5D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,gBAAe,EAAE;AACjB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,WAAU,mBAAmB;AAC7B,WAAU;AACV;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,gBAAe,KAAK;AACpB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,WAAU,OAAO,OAAO,qBAAqB,EAAE,EAAE;AACjD,WAAU,OAAO,OAAO,qBAAqB,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,mCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,KAAK;AACpB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,gBAAgB;AAC/B,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,QAAQ;AACvB;AACA,kBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,iBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,mBAAmB,GAAG,iBAAiB;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA8B,qDAAqD;AACnF;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,aAAa;AAC5B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,WAAU,OAAO,OAAO,SAAS,EAAE,EAAE;AACrC,WAAU,OAAO,OAAO,SAAS,EAAE;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,SAAS;AACxB,gBAAe,EAAE;AACjB,kBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC,gBAAe,EAAE;AACjB,kBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,8BAA8B;AACxC,WAAU;AACV;AACA;AACA;AACA;AACA,SAAQ;AACR,eAAc;AACd;AACA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,OAAO;AACtB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,gBAAe,uBAAuB;AACtC,gBAAe,EAAE;AACjB,kBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,eAAc,iBAAiB;AAC/B;AACA;AACA;AACA,WAAU,SAAS;AACnB,WAAU;AACV;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT,kCAAiC,sEAAsE;AACvG;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAmC,8DAA8D;AACjG;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB,4DAA4D;AAClF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAoB,yCAAyC;AAC7D;AACA,MAAK;;AAEL,uEAAsE,uCAAuC;;AAE7G;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,M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;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;;AAEA;;AAEA;AACA,kDAAiD,qBAAqB;AACtE;;AAEA;AACA;;;;;;;ACrDA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;;AAEA,kBAAiB,gBAAgB;AACjC;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;;AAEA;;AAEA;AACA,kDAAiD,qBAAqB;AACtE;;AAEA;AACA;;;;;;;ACjDA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACXA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;;;;;;;ACtBA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACXA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA,IAAG;AACH;;;;;;;ACdA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACXA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACZA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;;;;AChBA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACZA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACXA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;;;;;;;ACXA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;;;;;;;;;;;;AC9pGA,aAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBASE;AACd,QAAM,oBAAgB;OAAf,QAAQ,yDAAG,EAAE;;AACnB,UAAO,cAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;KAAC;GACzC;AACD,SAAO,qBAAgB;OAAf,QAAQ,yDAAG,EAAE;;;;;;AAKpB,OAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;AAC/D,OAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC7C,OAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACpC,UAAO,GAAG,KAAK,GAAG,IAAI,QAAQ,CAAC,GAAG,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CA;AACA,QAAO;AACP;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb,YAAW;AACX;AACA;AACA;AACA;AACA,EAAC;;;;;;;ACtLD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,iBAAgB;;AAEhB;AACA;;AAEA,kBAAiB,sBAAsB;AACvC;AACA;;AAEA;;AAEA;AACA;AACA,KAAI;AACJ;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;AACA;AACA,EAAC;;;;;;;AC/CD;;AAEA;;AAEA,kCAAiC,2CAA2C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,uDAAuD,2DAA2D,EAAE,EAAE,yDAAyD,qEAAqE,6DAA6D,oBAAoB,GAAG,EAAE;;AAEljB,uCAAsC,uCAAuC,kBAAkB;;AAE/F,kDAAiD,0CAA0C,0DAA0D,EAAE;;AAEvJ,2CAA0C,+DAA+D,qGAAqG,EAAE,yEAAyE,eAAe,yEAAyE,EAAE,EAAE,uHAAuH;;AAE5e;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,wEAAuE,aAAa;AACpF;AACA;;AAEA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA,oBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA,oBAAmB,wBAAwB;AAC3C;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,YAAW,kCAAkC;AAC7C;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qJAAoJ;AACpJ;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAO;AACP,MAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,QAAO;AACP;AACA;AACA,UAAS;AACT;AACA,QAAO;AACP;AACA;AACA,UAAS;AACT;AACA,QAAO;AACP;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,8EAA6E,0BAA0B,GAAG,0CAA0C,GAAG,gDAAgD,GAAG,4CAA4C,GAAG,8CAA8C,GAAG,0CAA0C,GAAG,gDAAgD,GAAG,gDAAgD,GAAG,4CAA4C,GAAG,0CAA0C,GAAG,4CAA4C;;AAErkB;AACA,uDAAsD,6FAA6F,sBAAsB,EAAE;AAC3K,MAAK;AACL;AACA;AACA;AACA,UAAS,mEAAmE;AAC5E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,mBAAmB;AACtC;AACA;AACA;AACA;AACA;AACA,oCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA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AAmF;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;;;AAGA;AACA,8CAA6C,sCAAsC,8BAA8B,sCAAsC,8BAA8B,GAAG,0BAA0B,gDAAgD,wCAAwC,oBAAoB,GAAG,4CAA4C,QAAQ,iBAAiB,gCAAgC,KAAK,SAAS,mBAAmB,iCAAiC,KAAK,UAAU,iBAAiB,iCAAiC,KAAK,GAAG,oCAAoC,QAAQ,iBAAiB,gCAAgC,KAAK,SAAS,mBAAmB,iCAAiC,KAAK,UAAU,iBAAiB,iCAAiC,KAAK,GAAG;;AAEzxB;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAgB,iBAAiB;AACjC;AACA;AACA,yCAAwC,gBAAgB;AACxD,KAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,aAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACjDA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,sBAAsB;AACtC;AACA;AACA,mBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,kBAAiB,2BAA2B;AAC5C;AACA;AACA,SAAQ,uBAAuB;AAC/B;AACA;AACA,IAAG;AACH;AACA,kBAAiB,uBAAuB;AACxC;AACA;AACA,4BAA2B;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA,iCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,wDAAuD;AACvD;;AAEA,8BAA6B,mBAAmB;;AAEhD;;AAEA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;AChPA,aAAY,CAAC;;;;;;;;;;;;;;;;;;AAKb,KAAM,cAAc,GAAG;AACtB,MAAI,EAAE,OAAO;AACb,OAAK,EAAE,MAAM;AACb,KAAG,EAAE,QAAQ;AACb,QAAM,EAAE,KAAK;EACb,CAAC;;AAEF,UAAS,QAAQ,CAAC,KAAK,EAAE;AACxB,SAAO,KAAK,CAAC,IAAI,CAAC,UAAC,CAAC,EAAE,CAAC,EAAK;AAC3B,OAAI,CAAC,CAAC,EAAE;AACP,WAAO,CAAC,CAAC;IACT;AACD,OAAI,CAAC,CAAC,EAAE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C,CAAC;OACH;MACD,CAAC,CAAC;KACH;AACD,WAAO,EAAE,mCAAyB,sBAAsB;AACxD,SAAK,EAAE,mCAAyB,oBAAoB;IACpD,CAAC;GACF;EACD,CAAC;;mBAEa,iBAAiB,C;;;;;;;;;AC7IhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,SAAQ,YAAY;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,OAAM;AACN;AACA;;AAEA;AACA;;AAEA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF,qBAAoB;;AAEpB;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,4CAA2C;AAC3C;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF,iCAAgC;AAChC;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,YAAY;AACvB;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;AACH;AACA,YAAW,YAAY;AACvB;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA,UAAS,SAAS;AAClB;AACA;;AAEA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS,YAAY;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAU,YAAY;AACtB;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,EAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,SAAS;AAClB;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA,iBAAgB,IAAI;;AAEpB;AACA;;AAEA;AACA;;AAEA;AACA,yCAAwC,IAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD,UAAS;;AAET;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;;AAEA;AACA,KAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,cAAa,yBAAyB;AACtC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,QAAQ;AACnB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;;AAEA;AACA;AACA,YAAW,gBAAgB;AAC3B,cAAa,uBAAuB;AACpC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,YAAW,eAAe;AAC1B,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,eAAe;AAC1B,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,YAAW,cAAc;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,iCAAgC,MAAM;AACtC;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,gBAAe;;AAEf,UAAS;;AAET;AACA,SAAQ,iCAAiC;AACzC,SAAQ,oBAAoB;AAC5B,SAAQ,sCAAsC;AAC9C,SAAQ;AACR,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA,iBAAgB,aAAa,EAAE;AAC/B;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,iEAAgE;AAChE;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,QAAO,yEAAyE;AAChF;;AAEA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,oDAAmD;AACnD;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,kEAAiE,UAAU;AAC3E,uCAAsC,2BAA2B;AACjE;AACA,iCAAgC,MAAM;AACtC;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA,WAAU,YAAY;AACtB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,WAAU,YAAY;AACtB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,WAAU,UAAU;AACpB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,WAAU,cAAc;AACxB;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,aAAY,uEAAuE;AACnF;AACA;AACA,aAAY,4BAA4B;AACxC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAQ,SAAS;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,4DAA2D;AAC3D;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;;AAEA,oCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA,SAAQ,SAAS;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAQ,SAAS;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH,SAAQ,SAAS;AACjB;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAuC,iDAAiD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,kDAAiD;AACjD,WAAU,wCAAwC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,gBAAgB;AAC3B;AACA,YAAW,QAAQ;AACnB,YAAW,MAAM;AACjB,YAAW,MAAM;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;;AAEA,EAAC;;;;AAID;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;AACF;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAgB,SAAS;AACzB;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA,eAAc,SAAS;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;AAGD;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,KAAI;AACJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAQ;AACR;AACA;AACA;AACA;;AAEA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;;AAEA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA,UAAS,GAAG;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAU,OAAO;AACjB;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS,OAAO;AAChB,wBAAuB,wBAAwB;AAC/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA,iDAAgD;AAChD,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;AACA,EAAC;AACD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;AACD;;;;AAIA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB;;AAEnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU,oCAAoC;AAC9C;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA,QAAO;AACP,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,SAAQ;AACR,QAAO;AACP;AACA,OAAM;AACN,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,+CAA8C;AAC9C,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA,KAAI;;AAEJ;;AAEA,6CAA4C;AAC5C;AACA;AACA;AACA;AACA,WAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;;AAGD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;AACF;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,WAAU,SAAS;AACnB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,wCAAuC;AACvC;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,sBAAqB;AACrB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,mCAAkC;AAClC;;AAEA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wBAAuB,aAAa;AACpC,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAoB,SAAS;AAC7B;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;;AAGD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ,IAAG;AACH;AACA,EAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ,GAAE;AACF;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;;;;AAIA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE,gBAAgB;AAClB;;AAEA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,4CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,uCAAsC;AACtC;AACA;AACA;;AAEA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,+CAA8C;AAC9C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,4CAA2C;AAC3C;;AAEA;AACA;AACA;AACA;AACA,WAAU,KAAK;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,mDAAkD;AAClD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sDAAqD;AACrD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,0BAAyB;AACzB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,+DAA8D;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,WAAU,cAAc;;AAExB;AACA;AACA;AACA,kBAAiB,mBAAmB;AACpC;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB,+BAA+B;AACxD;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAsB,wDAAwD;AAC9E;;AAEA;AACA,GAAE;;AAEF;AACA;;AAEA,cAAa;;AAEb;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,uCAAsC,cAAc;AACpD;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,sCAAqC;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,uCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,eAAc,qCAAqC;;AAEnD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;AACL;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;AAGD;AACA;AACA;AACA,oBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,SAAQ,OAAO;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,4CAA2C,OAAO;AAClD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+BAA8B;;AAE9B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wCAAuC,OAAO;AAC9C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,yCAAwC,OAAO;AAC/C;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS,OAAO;AAChB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA,UAAS,mCAAmC;AAC5C;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;;AAEA,UAAS,2BAA2B;AACpC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA,UAAS,0BAA0B;AACnC;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA,8BAA6B;AAC7B;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,aAAY,OAAO;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,kBAAiB,gBAAgB;AACjC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS,WAAW;AACpB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;;AAGD;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;AAIA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,mBAAkB;AAClB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,sCAAqC,QAAQ,SAAS,MAAM,aAAa,eAAe;AACxF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC,2BAA2B;AAC7D,2BAA0B,cAAc,cAAc,OAAO;AAC7D,gBAAe,YAAY,UAAU;AACrC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,8BAA6B,SAAS,QAAQ,QAAQ;AACtD;AACA;AACA;AACA,sCAAqC,4BAA4B;AACjE,8BAA6B,cAAc,SAAS,SAAS;AAC7D;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA,EAAC;;;AAGD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,aAAY,+DAA+D;AAC3E;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,SAAQ,OAAO;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,SAAQ,gBAAgB;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA,+BAA8B,4BAA4B;AAC1D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA,kBAAiB;;AAEjB;AACA;;AAEA,WAAU,OAAO;AACjB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA,aAAY;AACZ;;AAEA;AACA;AACA;;AAEA,YAAW,SAAS;AACpB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,IAAG;AACH;AACA,EAAC;;;AAGD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA,SAAQ,QAAQ;AAChB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAQ,gBAAgB;AACxB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,mDAAkD;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAU,iBAAiB;AAC3B;AACA;;AAEA;;AAEA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,4BAA2B;AAC3B,gCAA+B,kBAAkB,EAAE;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,iBAAiB;AAC5B;AACA;;AAEA,8CAA6C;AAC7C;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;;AAEA,SAAQ,iBAAiB;AACzB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;;AAEA,UAAS,iBAAiB;AAC1B;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,EAAC;;AAED;AACA,kEAAiE;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,oBAAmB,cAAc;AACjC,GAAE;AACF;AACA;AACA;AACA;AACA;AACA,kDAAiD;;AAEjD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA,gCAA+B,SAAS;AACxC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,gCAA+B,SAAS;AACxC;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAmB,gBAAgB;AACnC;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,WAAU,kBAAkB;AAC5B,YAAW,kBAAkB;AAC7B,eAAc;AACd,EAAC;AACD;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA;;AAEA,SAAQ,mBAAmB;AAC3B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;AAGD;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA,KAAI;AACJ;AACA;AACA;;AAEA,IAAG;AACH;;AAEA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;AAKD;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;AAKD;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA,WAAU,SAAS;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA,WAAU,SAAS;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA,UAAS,OAAO;AAChB;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAC;;;;;AAKD;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAI;AACJ;AACA;;AAEA,kCAAiC;AACjC;AACA;;AAEA,KAAI;AACJ;;AAEA,KAAI;AACJ;AACA;AACA,MAAK;AACL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,SAAS;AACpB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;AAKD;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA,EAAC;;;AAGD;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;;AAEhB;AACA;AACA;AACA;AACA;AACA,iBAAgB;;AAEhB,iDAAgD;AAChD;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,oBAAmB;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wDAAuD;AACvD;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,KAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA,QAAO;AACP,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;AACT;;AAEA;;AAEA;AACA;;AAEA;AACA,kBAAiB;AACjB,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAkC;AAClC;AACA,uBAAsB;AACtB,4BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oFAAmF;AACnF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,eAAc,oCAAoC;AAClD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;;AAEA;AACA;AACA,IAAG;AACH,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAI;AACJ;AACA;AACA;AACA,IAAG;;AAEH,GAAE;AACF;AACA;AACA;AACA;;AAEA,GAAE;AACF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAc;AACd,OAAM;AACN,OAAM;AACN,IAAG;AACH;AACA,EAAC;;;AAGD;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA,mBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAQ;AACR;AACA,mDAAkD;AAClD;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;AAKD;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;AAKD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,EAAC;;;;;AAKD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;AACH;AACA,IAAG;AACH;;AAEA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA,EAAC;;;;;AAKD;AACA;AACA;AACA,GAAE;AACF;;;;;AAKA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA,WAAU,kBAAkB;AAC5B;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB;;AAEnB,6DAA4D,eAAe;AAC3E;AACA;AACA;;AAEA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAG;AACH;AACA,EAAC;;AAED;AACA,eAAc,sDAAsD;AACpE;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,KAAI;AACJ;AACA;AACA,IAAG;AACH;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,6CAA4C,oBAAoB;AAChE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,wCAAuC;AACvC;AACA,UAAS,qCAAqC;AAC9C;AACA,UAAS,qCAAqC;AAC9C;AACA,UAAS,OAAO;AAChB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAA+B,0BAA0B;AACzD;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA,gCAA+B,0BAA0B;AACzD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA,cAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,sDAAqD,EAAE;AACvD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,4BAA2B,gBAAgB;AAC3C;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,M;;;AAGA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,qF;AACA,oC;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,wF;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,8D;AACA;AACA,UAAS;;AAET;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,EAAC;;;;;;;ACtqBD;;AAEA;AACA;AACA;AACA;AACA,kDAAmF;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;;;AAGA;AACA,gFAA+E,mCAAmC,uBAAuB,iBAAiB,eAAe,kBAAkB,GAAG,uBAAuB,kBAAkB,2BAA2B,GAAG,sBAAsB,0BAA0B,wCAAwC,qBAAqB,iBAAiB,sBAAsB,GAAG,uBAAuB,eAAe,GAAG;;AAErc;;;;;;;;;;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,CAAC,CAAC;GAC5D;;eAJmB,mCAAmC;;sBAUpD,SAAS,EAAE,aAAa,EAAE;AAC5B,QAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAC3C;;;uBANoB;AACpB,WAAO,OAAO,CAAC;IACf;;;SARmB,mCAAmC;;;mBAAnC,mCAAmC,C;;;;;;;;;;AC5FxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mBAAkB;AAClB,0CAAyC,0BAA0B,2DAA2D,EAAE,kBAAkB,0BAA0B,EAAE,mCAAmC,8BAA8B,oCAAoC,cAAc;;AAEjS;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C,WAAW;AACxD;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAA+C,WAAW;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,8CAA6C,EAAE;AAC/C;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,UAAU,sBAAsB,aAAa;AACvF;AACA,mDAAkD,YAAY;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,yCAAwC,WAAW;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,WAAW;AACrD;AACA;AACA;AACA;AACA,6CAA4C,YAAY;AACxD;AACA;AACA;AACA;AACA,2GAA0G;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB,gBAAe;AACf;AACA;AACA;AACA,oBAAmB;AACnB,kBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,6CAA4C,YAAY;AACxD;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,2CAA0C,WAAW;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,WAAW;AACrD;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,WAAW;AACrD;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0CAAyC,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA8B,qEAAqE;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAiD,WAAW;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC,WAAW;AACnD;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,6CAA4C,WAAW;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C,WAAW;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C,WAAW;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf,cAAa;AACb;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA,4DAA2D,UAAU,0DAA0D,aAAa;AAC5I,QAAO;AACP;AACA,QAAO;AACP,2DAA0D,UAAU;AACpE;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA,QAAO;AACP;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC,WAAW;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,iDAAgD,WAAW;AAC3D;AACA;AACA;AACA;AACA,kDAAiD,YAAY;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA4C,YAAY;AACxD;AACA,gHAA+G,YAAY;AAC3H;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,+CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,+CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA4C,YAAY;AACxD;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC,YAAY;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA0C,YAAY;AACtD;AACA;AACA;AACA;AACA;AACA,+CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA,iDAAgD,wCAAwC;AACxF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,6CAA4C,WAAW;AACvD;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAAyC,WAAW;AACpD;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,yCAAwC,WAAW;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qCAAoC,WAAW;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wCAAuC,WAAW;AAClD;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,wCAAuC,YAAY;AACnD;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C,WAAW;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;A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AEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,YAAY;AACzB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iCAAgC;AAChC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,2KAA0K,IAAI;;AAE9K,sEAAqE,IAAI;;AAEzE;;AAEA;;AAEA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,2CAA0C,YAAY;AACtD;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,wBAAuB,YAAY;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,+BAA8B;AAC9B,iCAAgC;AAChC,8BAA6B,EAAE,EAAE;AACjC,8BAA6B,EAAE,EAAE;AACjC,mCAAkC,EAAE,EAAE;AACtC,kCAAiC;AACjC,8BAA6B,IAAI,EAAE;AACnC,8BAA6B,IAAI,EAAE;AACnC,mCAAkC,IAAI,EAAE;;AAExC,gCAA+B;AAC/B,qCAAoC;;AAEpC,+CAA8C;;AAE9C,yCAAwC,IAAI,IAAI;;AAEhD;AACA,iIAAgI,IAAI;;AAEpI;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS,+BAA+B;AACxC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,kBAAkB;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,gDAA+C,EAAE,IAAI,EAAE;;AAEvD;AACA,kCAAiC,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/C,4BAA2B,EAAE,IAAI,EAAE,IAAI,EAAE;AACzC,8BAA6B,EAAE,KAAK,EAAE;AACtC,4BAA2B,EAAE,KAAK,EAAE;AACpC,0BAAyB,EAAE,IAAI,EAAE;AACjC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA4C,OAAO;AACnD;AACA;AACA;AACA;AACA;AACA,6CAA4C,OAAO;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB,+BAA+B;AAClD;AACA;;AAEA;AACA,eAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,oBAAmB,mBAAmB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,sBAAsB;AACzC;AACA,uCAAsC;AACtC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,0CAAyC,gBAAgB;AACzD;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sEAAqE,EAAE;;AAEvE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,6BAA6B;AACtC;AACA,UAAS;AACT;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAmB;;AAEnB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA0B,cAAc;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wCAAuC,qBAAqB;AAC5D;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wCAAuC,qBAAqB;AAC5D;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,yBAAwB;AACxB;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,yBAAwB,mBAAmB;AAC3C;AACA;;AAEA;AACA;AACA;;AAEA,sBAAqB,mBAAmB;AACxC;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,mCAAkC,IAAI;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,uFAAsF,IAAI;AAC1F;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB,WAAW;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;;AAGA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC,G;;;;;;;AC1nGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC,uDAAuD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACvLA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA,6FAA4F;AAC5F,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACtID;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzDD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACrGD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvDD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA,gCAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACtGD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACjJD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC/GD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC5GD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzGD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3ID;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7ED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,4BAA2B,IAAI;AAC/B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3JD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAmC;AACnC,kBAAiB;AACjB;AACA;AACA,cAAa;AACb;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7ED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1DD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1ED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA,yEAAwE;AACxE;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,kCAAiC;AACjC,iCAAgC;AAChC,iCAAgC;AAChC,gCAA+B;AAC/B;AACA;AACA;AACA,0DAAyD;AACzD;AACA,2DAA0D;AAC1D;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC;AACrC,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC5FD;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AChED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACjED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,4BAA2B,IAAI;AAC/B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7ED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC9ED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC9DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvGD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzGD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC5DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxDD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACrED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,4BAA2B,IAAI;AAC/B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AChFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzHD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1ID;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3GD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,2BAA0B,IAAI,IAAI,IAAI;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7GD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACjFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7HD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,4BAA2B,IAAI;AAC/B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACpED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC/DD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACjFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,qCAAoC,IAAI,IAAI,IAAI;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACrGD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxDD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,4BAA2B,IAAI;AAC/B;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AClED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAsB;AACtB,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACpID;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3HD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC9FD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3GD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACrED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvHD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AChFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AChFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3FD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC3DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACzHD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACrED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvGD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA4C;AAC5C,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC9DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA4C;AAC5C,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1DD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AClKD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC/DD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC5JD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC9JD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACnED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1GD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA,iBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC1GD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACjED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,cAAa;AACb,iCAAgC;AAChC,cAAa;AACb,gCAA+B;AAC/B,cAAa;AACb,mCAAkC;AAClC,cAAa;AACb,mCAAkC;AAClC,cAAa;AACb,gCAA+B;AAC/B,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7FD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC/DD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC5DD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA,gCAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;;AAI3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC,G;;;;;;ACnFD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxDD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxDD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACvJD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACxDD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AChED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;AC7HD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC,wBAAwB,EAAE;AAClE;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF,aAAY;;AAEZ;AACA;;AAEA,yBAAwB,yBAAyB;AACjD;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,mBAAkB,qBAAqB;AACvC;AACA;AACA;AACA;AACA;;AAEA;;AAEA,kBAAiB,iBAAiB,OAAO;;AAEzC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;AACA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA,2BAA0B,2BAA2B;AACrD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;AACF,wBAAuB,KAAK;AAC5B;;AAEA;AACA;;AAEA;AACA,uDAAsD;AACtD;AACA,EAAC;;AAED;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA,0BAAyB,SAAS;AAClC;AACA;AACA;AACA;AACA,GAAE;AACF;AACA,mBAAkB,EAAE,OAAO,GAAG,WAAW;AACzC;AACA;AACA;AACA;AACA,wBAAuB;AACvB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA,qBAAoB,IAAI;AACxB;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA,+DAA8D,IAAI,kBAAkB;AACpF;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA,mBAAkB,GAAG,IAAI;AACzB;AACA;AACA,sBAAqB,GAAG;AACxB;AACA,OAAM;AACN;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gCAA+B;AAC/B;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;;AAEA;;AAEA;;AAEA,EAAC;;;;;;;;ACnsBD;;AAEA;AACA;AACA;AACA;AACA,kDAAmF;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;;;AAGA;AACA,wCAAuC,yFAAyF,gGAAgG,oBAAoB,+CAA+C,uBAAuB,gDAAgD,GAAG,wDAAwD,kBAAkB,GAAG,oHAAoH,qBAAqB,GAAG,oCAAoC,gBAAgB,GAAG,4BAA4B,gBAAgB,GAAG,0MAA0M,gBAAgB,GAAG,iLAAiL,mBAAmB,GAAG,mKAAmK,mBAAmB,yCAAyC,GAAG,4FAA4F,gBAAgB,GAAG,iCAAiC,mBAAmB,GAAG,2FAA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","file":"main.js","sourcesContent":[" \tvar parentHotUpdateCallback = this[\"webpackHotUpdate\"];\n \tthis[\"webpackHotUpdate\"] = function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars\n \t\thotAddUpdateChunk(chunkId, moreModules);\n \t\tif(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules);\n \t}\n\n \tfunction hotDownloadUpdateChunk(chunkId) { // eslint-disable-line no-unused-vars\n \t\tvar head = document.getElementsByTagName(\"head\")[0];\n \t\tvar script = document.createElement(\"script\");\n \t\tscript.type = \"text/javascript\";\n \t\tscript.charset = \"utf-8\";\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".\" + hotCurrentHash + \".hot-update.js\";\n \t\thead.appendChild(script);\n \t}\n\n \tfunction hotDownloadManifest(callback) { // eslint-disable-line no-unused-vars\n \t\tif(typeof XMLHttpRequest === \"undefined\")\n \t\t\treturn callback(new Error(\"No browser support\"));\n \t\ttry {\n \t\t\tvar request = new XMLHttpRequest();\n \t\t\tvar requestPath = __webpack_require__.p + \"\" + hotCurrentHash + \".hot-update.json\";\n \t\t\trequest.open(\"GET\", requestPath, true);\n \t\t\trequest.timeout = 10000;\n \t\t\trequest.send(null);\n \t\t} catch(err) {\n \t\t\treturn callback(err);\n \t\t}\n \t\trequest.onreadystatechange = function() {\n \t\t\tif(request.readyState !== 4) return;\n \t\t\tif(request.status === 0) {\n \t\t\t\t// timeout\n \t\t\t\tcallback(new Error(\"Manifest request to \" + requestPath + \" timed out.\"));\n \t\t\t} else if(request.status === 404) {\n \t\t\t\t// no update available\n \t\t\t\tcallback();\n \t\t\t} else if(request.status !== 200 && request.status !== 304) {\n \t\t\t\t// other failure\n \t\t\t\tcallback(new Error(\"Manifest request to \" + requestPath + \" failed.\"));\n \t\t\t} else {\n \t\t\t\t// success\n \t\t\t\ttry {\n \t\t\t\t\tvar update = JSON.parse(request.responseText);\n \t\t\t\t} catch(e) {\n \t\t\t\t\tcallback(e);\n \t\t\t\t\treturn;\n \t\t\t\t}\n \t\t\t\tcallback(null, update);\n \t\t\t}\n \t\t};\n \t}\n\n\n \tvar hotApplyOnUpdate = true;\n \tvar hotCurrentHash = \"a4e0cb00cc099a3c7d0d\"; // eslint-disable-line no-unused-vars\n \tvar hotCurrentModuleData = {};\n \tvar hotCurrentParents = []; // eslint-disable-line no-unused-vars\n\n \tfunction hotCreateRequire(moduleId) { // eslint-disable-line no-unused-vars\n \t\tvar me = installedModules[moduleId];\n \t\tif(!me) return __webpack_require__;\n \t\tvar fn = function(request) {\n \t\t\tif(me.hot.active) {\n \t\t\t\tif(installedModules[request]) {\n \t\t\t\t\tif(installedModules[request].parents.indexOf(moduleId) < 0)\n \t\t\t\t\t\tinstalledModules[request].parents.push(moduleId);\n \t\t\t\t\tif(me.children.indexOf(request) < 0)\n \t\t\t\t\t\tme.children.push(request);\n \t\t\t\t} else hotCurrentParents = [moduleId];\n \t\t\t} else {\n \t\t\t\tconsole.warn(\"[HMR] unexpected require(\" + request + \") from disposed module \" + moduleId);\n \t\t\t\thotCurrentParents = [];\n \t\t\t}\n \t\t\treturn __webpack_require__(request);\n \t\t};\n \t\tfor(var name in __webpack_require__) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(__webpack_require__, name)) {\n \t\t\t\tfn[name] = __webpack_require__[name];\n \t\t\t}\n \t\t}\n \t\tfn.e = function(chunkId, callback) {\n \t\t\tif(hotStatus === \"ready\")\n \t\t\t\thotSetStatus(\"prepare\");\n \t\t\thotChunksLoading++;\n \t\t\t__webpack_require__.e(chunkId, function() {\n \t\t\t\ttry {\n \t\t\t\t\tcallback.call(null, fn);\n \t\t\t\t} finally {\n \t\t\t\t\tfinishChunkLoading();\n \t\t\t\t}\n\n \t\t\t\tfunction finishChunkLoading() {\n \t\t\t\t\thotChunksLoading--;\n \t\t\t\t\tif(hotStatus === \"prepare\") {\n \t\t\t\t\t\tif(!hotWaitingFilesMap[chunkId]) {\n \t\t\t\t\t\t\thotEnsureUpdateChunk(chunkId);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tif(hotChunksLoading === 0 && hotWaitingFiles === 0) {\n \t\t\t\t\t\t\thotUpdateDownloaded();\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t});\n \t\t};\n \t\treturn fn;\n \t}\n\n \tfunction hotCreateModule(moduleId) { // eslint-disable-line no-unused-vars\n \t\tvar hot = {\n \t\t\t// private stuff\n \t\t\t_acceptedDependencies: {},\n \t\t\t_declinedDependencies: {},\n \t\t\t_selfAccepted: false,\n \t\t\t_selfDeclined: false,\n \t\t\t_disposeHandlers: [],\n\n \t\t\t// Module API\n \t\t\tactive: true,\n \t\t\taccept: function(dep, callback) {\n \t\t\t\tif(typeof dep === \"undefined\")\n \t\t\t\t\thot._selfAccepted = true;\n \t\t\t\telse if(typeof dep === \"function\")\n \t\t\t\t\thot._selfAccepted = dep;\n \t\t\t\telse if(typeof dep === \"object\")\n \t\t\t\t\tfor(var i = 0; i < dep.length; i++)\n \t\t\t\t\t\thot._acceptedDependencies[dep[i]] = callback;\n \t\t\t\telse\n \t\t\t\t\thot._acceptedDependencies[dep] = callback;\n \t\t\t},\n \t\t\tdecline: function(dep) {\n \t\t\t\tif(typeof dep === \"undefined\")\n \t\t\t\t\thot._selfDeclined = true;\n \t\t\t\telse if(typeof dep === \"number\")\n \t\t\t\t\thot._declinedDependencies[dep] = true;\n \t\t\t\telse\n \t\t\t\t\tfor(var i = 0; i < dep.length; i++)\n \t\t\t\t\t\thot._declinedDependencies[dep[i]] = true;\n \t\t\t},\n \t\t\tdispose: function(callback) {\n \t\t\t\thot._disposeHandlers.push(callback);\n \t\t\t},\n \t\t\taddDisposeHandler: function(callback) {\n \t\t\t\thot._disposeHandlers.push(callback);\n \t\t\t},\n \t\t\tremoveDisposeHandler: function(callback) {\n \t\t\t\tvar idx = hot._disposeHandlers.indexOf(callback);\n \t\t\t\tif(idx >= 0) hot._disposeHandlers.splice(idx, 1);\n \t\t\t},\n\n \t\t\t// Management API\n \t\t\tcheck: hotCheck,\n \t\t\tapply: hotApply,\n \t\t\tstatus: function(l) {\n \t\t\t\tif(!l) return hotStatus;\n \t\t\t\thotStatusHandlers.push(l);\n \t\t\t},\n \t\t\taddStatusHandler: function(l) {\n \t\t\t\thotStatusHandlers.push(l);\n \t\t\t},\n \t\t\tremoveStatusHandler: function(l) {\n \t\t\t\tvar idx = hotStatusHandlers.indexOf(l);\n \t\t\t\tif(idx >= 0) hotStatusHandlers.splice(idx, 1);\n \t\t\t},\n\n \t\t\t//inherit from previous dispose call\n \t\t\tdata: hotCurrentModuleData[moduleId]\n \t\t};\n \t\treturn hot;\n \t}\n\n \tvar hotStatusHandlers = [];\n \tvar hotStatus = \"idle\";\n\n \tfunction hotSetStatus(newStatus) {\n \t\thotStatus = newStatus;\n \t\tfor(var i = 0; i < hotStatusHandlers.length; i++)\n \t\t\thotStatusHandlers[i].call(null, newStatus);\n \t}\n\n \t// while downloading\n \tvar hotWaitingFiles = 0;\n \tvar hotChunksLoading = 0;\n \tvar hotWaitingFilesMap = {};\n \tvar hotRequestedFilesMap = {};\n \tvar hotAvailibleFilesMap = {};\n \tvar hotCallback;\n\n \t// The update info\n \tvar hotUpdate, hotUpdateNewHash;\n\n \tfunction toModuleId(id) {\n \t\tvar isNumber = (+id) + \"\" === id;\n \t\treturn isNumber ? +id : id;\n \t}\n\n \tfunction hotCheck(apply, callback) {\n \t\tif(hotStatus !== \"idle\") throw new Error(\"check() is only allowed in idle status\");\n \t\tif(typeof apply === \"function\") {\n \t\t\thotApplyOnUpdate = false;\n \t\t\tcallback = apply;\n \t\t} else {\n \t\t\thotApplyOnUpdate = apply;\n \t\t\tcallback = callback || function(err) {\n \t\t\t\tif(err) throw err;\n \t\t\t};\n \t\t}\n \t\thotSetStatus(\"check\");\n \t\thotDownloadManifest(function(err, update) {\n \t\t\tif(err) return callback(err);\n \t\t\tif(!update) {\n \t\t\t\thotSetStatus(\"idle\");\n \t\t\t\tcallback(null, null);\n \t\t\t\treturn;\n \t\t\t}\n\n \t\t\thotRequestedFilesMap = {};\n \t\t\thotAvailibleFilesMap = {};\n \t\t\thotWaitingFilesMap = {};\n \t\t\tfor(var i = 0; i < update.c.length; i++)\n \t\t\t\thotAvailibleFilesMap[update.c[i]] = true;\n \t\t\thotUpdateNewHash = update.h;\n\n \t\t\thotSetStatus(\"prepare\");\n \t\t\thotCallback = callback;\n \t\t\thotUpdate = {};\n \t\t\tvar chunkId = 0;\n \t\t\t{ // eslint-disable-line no-lone-blocks\n \t\t\t\t/*globals chunkId */\n \t\t\t\thotEnsureUpdateChunk(chunkId);\n \t\t\t}\n \t\t\tif(hotStatus === \"prepare\" && hotChunksLoading === 0 && hotWaitingFiles === 0) {\n \t\t\t\thotUpdateDownloaded();\n \t\t\t}\n \t\t});\n \t}\n\n \tfunction hotAddUpdateChunk(chunkId, moreModules) { // eslint-disable-line no-unused-vars\n \t\tif(!hotAvailibleFilesMap[chunkId] || !hotRequestedFilesMap[chunkId])\n \t\t\treturn;\n \t\thotRequestedFilesMap[chunkId] = false;\n \t\tfor(var moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\thotUpdate[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(--hotWaitingFiles === 0 && hotChunksLoading === 0) {\n \t\t\thotUpdateDownloaded();\n \t\t}\n \t}\n\n \tfunction hotEnsureUpdateChunk(chunkId) {\n \t\tif(!hotAvailibleFilesMap[chunkId]) {\n \t\t\thotWaitingFilesMap[chunkId] = true;\n \t\t} else {\n \t\t\thotRequestedFilesMap[chunkId] = true;\n \t\t\thotWaitingFiles++;\n \t\t\thotDownloadUpdateChunk(chunkId);\n \t\t}\n \t}\n\n \tfunction hotUpdateDownloaded() {\n \t\thotSetStatus(\"ready\");\n \t\tvar callback = hotCallback;\n \t\thotCallback = null;\n \t\tif(!callback) return;\n \t\tif(hotApplyOnUpdate) {\n \t\t\thotApply(hotApplyOnUpdate, callback);\n \t\t} else {\n \t\t\tvar outdatedModules = [];\n \t\t\tfor(var id in hotUpdate) {\n \t\t\t\tif(Object.prototype.hasOwnProperty.call(hotUpdate, id)) {\n \t\t\t\t\toutdatedModules.push(toModuleId(id));\n \t\t\t\t}\n \t\t\t}\n \t\t\tcallback(null, outdatedModules);\n \t\t}\n \t}\n\n \tfunction hotApply(options, callback) {\n \t\tif(hotStatus !== \"ready\") throw new Error(\"apply() is only allowed in ready status\");\n \t\tif(typeof options === \"function\") {\n \t\t\tcallback = options;\n \t\t\toptions = {};\n \t\t} else if(options && typeof options === \"object\") {\n \t\t\tcallback = callback || function(err) {\n \t\t\t\tif(err) throw err;\n \t\t\t};\n \t\t} else {\n \t\t\toptions = {};\n \t\t\tcallback = callback || function(err) {\n \t\t\t\tif(err) throw err;\n \t\t\t};\n \t\t}\n\n \t\tfunction getAffectedStuff(module) {\n \t\t\tvar outdatedModules = [module];\n \t\t\tvar outdatedDependencies = {};\n\n \t\t\tvar queue = outdatedModules.slice();\n \t\t\twhile(queue.length > 0) {\n \t\t\t\tvar moduleId = queue.pop();\n \t\t\t\tvar module = installedModules[moduleId];\n \t\t\t\tif(!module || module.hot._selfAccepted)\n \t\t\t\t\tcontinue;\n \t\t\t\tif(module.hot._selfDeclined) {\n \t\t\t\t\treturn new Error(\"Aborted because of self decline: \" + moduleId);\n \t\t\t\t}\n \t\t\t\tif(moduleId === 0) {\n \t\t\t\t\treturn;\n \t\t\t\t}\n \t\t\t\tfor(var i = 0; i < module.parents.length; i++) {\n \t\t\t\t\tvar parentId = module.parents[i];\n \t\t\t\t\tvar parent = installedModules[parentId];\n \t\t\t\t\tif(parent.hot._declinedDependencies[moduleId]) {\n \t\t\t\t\t\treturn new Error(\"Aborted because of declined dependency: \" + moduleId + \" in \" + parentId);\n \t\t\t\t\t}\n \t\t\t\t\tif(outdatedModules.indexOf(parentId) >= 0) continue;\n \t\t\t\t\tif(parent.hot._acceptedDependencies[moduleId]) {\n \t\t\t\t\t\tif(!outdatedDependencies[parentId])\n \t\t\t\t\t\t\toutdatedDependencies[parentId] = [];\n \t\t\t\t\t\taddAllToSet(outdatedDependencies[parentId], [moduleId]);\n \t\t\t\t\t\tcontinue;\n \t\t\t\t\t}\n \t\t\t\t\tdelete outdatedDependencies[parentId];\n \t\t\t\t\toutdatedModules.push(parentId);\n \t\t\t\t\tqueue.push(parentId);\n \t\t\t\t}\n \t\t\t}\n\n \t\t\treturn [outdatedModules, outdatedDependencies];\n \t\t}\n\n \t\tfunction addAllToSet(a, b) {\n \t\t\tfor(var i = 0; i < b.length; i++) {\n \t\t\t\tvar item = b[i];\n \t\t\t\tif(a.indexOf(item) < 0)\n \t\t\t\t\ta.push(item);\n \t\t\t}\n \t\t}\n\n \t\t// at begin all updates modules are outdated\n \t\t// the \"outdated\" status can propagate to parents if they don't accept the children\n \t\tvar outdatedDependencies = {};\n \t\tvar outdatedModules = [];\n \t\tvar appliedUpdate = {};\n \t\tfor(var id in hotUpdate) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(hotUpdate, id)) {\n \t\t\t\tvar moduleId = toModuleId(id);\n \t\t\t\tvar result = getAffectedStuff(moduleId);\n \t\t\t\tif(!result) {\n \t\t\t\t\tif(options.ignoreUnaccepted)\n \t\t\t\t\t\tcontinue;\n \t\t\t\t\thotSetStatus(\"abort\");\n \t\t\t\t\treturn callback(new Error(\"Aborted because \" + moduleId + \" is not accepted\"));\n \t\t\t\t}\n \t\t\t\tif(result instanceof Error) {\n \t\t\t\t\thotSetStatus(\"abort\");\n \t\t\t\t\treturn callback(result);\n \t\t\t\t}\n \t\t\t\tappliedUpdate[moduleId] = hotUpdate[moduleId];\n \t\t\t\taddAllToSet(outdatedModules, result[0]);\n \t\t\t\tfor(var moduleId in result[1]) {\n \t\t\t\t\tif(Object.prototype.hasOwnProperty.call(result[1], moduleId)) {\n \t\t\t\t\t\tif(!outdatedDependencies[moduleId])\n \t\t\t\t\t\t\toutdatedDependencies[moduleId] = [];\n \t\t\t\t\t\taddAllToSet(outdatedDependencies[moduleId], result[1][moduleId]);\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// Store self accepted outdated modules to require them later by the module system\n \t\tvar outdatedSelfAcceptedModules = [];\n \t\tfor(var i = 0; i < outdatedModules.length; i++) {\n \t\t\tvar moduleId = outdatedModules[i];\n \t\t\tif(installedModules[moduleId] && installedModules[moduleId].hot._selfAccepted)\n \t\t\t\toutdatedSelfAcceptedModules.push({\n \t\t\t\t\tmodule: moduleId,\n \t\t\t\t\terrorHandler: installedModules[moduleId].hot._selfAccepted\n \t\t\t\t});\n \t\t}\n\n \t\t// Now in \"dispose\" phase\n \t\thotSetStatus(\"dispose\");\n \t\tvar queue = outdatedModules.slice();\n \t\twhile(queue.length > 0) {\n \t\t\tvar moduleId = queue.pop();\n \t\t\tvar module = installedModules[moduleId];\n \t\t\tif(!module) continue;\n\n \t\t\tvar data = {};\n\n \t\t\t// Call dispose handlers\n \t\t\tvar disposeHandlers = module.hot._disposeHandlers;\n \t\t\tfor(var j = 0; j < disposeHandlers.length; j++) {\n \t\t\t\tvar cb = disposeHandlers[j];\n \t\t\t\tcb(data);\n \t\t\t}\n \t\t\thotCurrentModuleData[moduleId] = data;\n\n \t\t\t// disable module (this disables requires from this module)\n \t\t\tmodule.hot.active = false;\n\n \t\t\t// remove module from cache\n \t\t\tdelete installedModules[moduleId];\n\n \t\t\t// remove \"parents\" references from all children\n \t\t\tfor(var j = 0; j < module.children.length; j++) {\n \t\t\t\tvar child = installedModules[module.children[j]];\n \t\t\t\tif(!child) continue;\n \t\t\t\tvar idx = child.parents.indexOf(moduleId);\n \t\t\t\tif(idx >= 0) {\n \t\t\t\t\tchild.parents.splice(idx, 1);\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// remove outdated dependency from module children\n \t\tfor(var moduleId in outdatedDependencies) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) {\n \t\t\t\tvar module = installedModules[moduleId];\n \t\t\t\tvar moduleOutdatedDependencies = outdatedDependencies[moduleId];\n \t\t\t\tfor(var j = 0; j < moduleOutdatedDependencies.length; j++) {\n \t\t\t\t\tvar dependency = moduleOutdatedDependencies[j];\n \t\t\t\t\tvar idx = module.children.indexOf(dependency);\n \t\t\t\t\tif(idx >= 0) module.children.splice(idx, 1);\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// Not in \"apply\" phase\n \t\thotSetStatus(\"apply\");\n\n \t\thotCurrentHash = hotUpdateNewHash;\n\n \t\t// insert new code\n \t\tfor(var moduleId in appliedUpdate) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(appliedUpdate, moduleId)) {\n \t\t\t\tmodules[moduleId] = appliedUpdate[moduleId];\n \t\t\t}\n \t\t}\n\n \t\t// call accept handlers\n \t\tvar error = null;\n \t\tfor(var moduleId in outdatedDependencies) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) {\n \t\t\t\tvar module = installedModules[moduleId];\n \t\t\t\tvar moduleOutdatedDependencies = outdatedDependencies[moduleId];\n \t\t\t\tvar callbacks = [];\n \t\t\t\tfor(var i = 0; i < moduleOutdatedDependencies.length; i++) {\n \t\t\t\t\tvar dependency = moduleOutdatedDependencies[i];\n \t\t\t\t\tvar cb = module.hot._acceptedDependencies[dependency];\n \t\t\t\t\tif(callbacks.indexOf(cb) >= 0) continue;\n \t\t\t\t\tcallbacks.push(cb);\n \t\t\t\t}\n \t\t\t\tfor(var i = 0; i < callbacks.length; i++) {\n \t\t\t\t\tvar cb = callbacks[i];\n \t\t\t\t\ttry {\n \t\t\t\t\t\tcb(outdatedDependencies);\n \t\t\t\t\t} catch(err) {\n \t\t\t\t\t\tif(!error)\n \t\t\t\t\t\t\terror = err;\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t}\n \t\t}\n\n \t\t// Load self accepted modules\n \t\tfor(var i = 0; i < outdatedSelfAcceptedModules.length; i++) {\n \t\t\tvar item = outdatedSelfAcceptedModules[i];\n \t\t\tvar moduleId = item.module;\n \t\t\thotCurrentParents = [moduleId];\n \t\t\ttry {\n \t\t\t\t__webpack_require__(moduleId);\n \t\t\t} catch(err) {\n \t\t\t\tif(typeof item.errorHandler === \"function\") {\n \t\t\t\t\ttry {\n \t\t\t\t\t\titem.errorHandler(err);\n \t\t\t\t\t} catch(err) {\n \t\t\t\t\t\tif(!error)\n \t\t\t\t\t\t\terror = err;\n \t\t\t\t\t}\n \t\t\t\t} else if(!error)\n \t\t\t\t\terror = err;\n \t\t\t}\n \t\t}\n\n \t\t// handle errors in accept handlers and self accepted module load\n \t\tif(error) {\n \t\t\thotSetStatus(\"fail\");\n \t\t\treturn callback(error);\n \t\t}\n\n \t\thotSetStatus(\"idle\");\n \t\tcallback(null, outdatedModules);\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false,\n \t\t\thot: hotCreateModule(moduleId),\n \t\t\tparents: hotCurrentParents,\n \t\t\tchildren: []\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/assets/\";\n\n \t// __webpack_hash__\n \t__webpack_require__.h = function() { return hotCurrentHash; };\n\n \t// Load entry module and return exports\n \treturn hotCreateRequire(0)(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap a4e0cb00cc099a3c7d0d\n **/","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n/*globals window __webpack_hash__ */\nif(module.hot) {\n\tvar lastData;\n\tvar upToDate = function upToDate() {\n\t\treturn lastData.indexOf(__webpack_hash__) >= 0;\n\t};\n\tvar check = function check() {\n\t\tmodule.hot.check(function(err, updatedModules) {\n\t\t\tif(err) {\n\t\t\t\tif(module.hot.status() in {\n\t\t\t\t\t\tabort: 1,\n\t\t\t\t\t\tfail: 1\n\t\t\t\t\t}) {\n\t\t\t\t\tconsole.warn(\"[HMR] Cannot check for update. Need to do a full reload!\");\n\t\t\t\t\tconsole.warn(\"[HMR] \" + err.stack || err.message);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"[HMR] Update check failed: \" + err.stack || err.message);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif(!updatedModules) {\n\t\t\t\tconsole.warn(\"[HMR] Cannot find update. Need to do a full reload!\");\n\t\t\t\tconsole.warn(\"[HMR] (Probably because of restarting the webpack-dev-server)\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodule.hot.apply({\n\t\t\t\tignoreUnaccepted: true\n\t\t\t}, function(err, renewedModules) {\n\t\t\t\tif(err) {\n\t\t\t\t\tif(module.hot.status() in {\n\t\t\t\t\t\t\tabort: 1,\n\t\t\t\t\t\t\tfail: 1\n\t\t\t\t\t\t}) {\n\t\t\t\t\t\tconsole.warn(\"[HMR] Cannot apply update. Need to do a full reload!\");\n\t\t\t\t\t\tconsole.warn(\"[HMR] \" + err.stack || err.message);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(\"[HMR] Update failed: \" + err.stack || err.message);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif(!upToDate()) {\n\t\t\t\t\tcheck();\n\t\t\t\t}\n\n\t\t\t\trequire(\"./log-apply-result\")(updatedModules, renewedModules);\n\n\t\t\t\tif(upToDate()) {\n\t\t\t\t\tconsole.log(\"[HMR] App is up to date.\");\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t};\n\tvar addEventListener = window.addEventListener ? function(eventName, listener) {\n\t\twindow.addEventListener(eventName, listener, false);\n\t} : function(eventName, listener) {\n\t\twindow.attachEvent(\"on\" + eventName, listener);\n\t};\n\taddEventListener(\"message\", function(event) {\n\t\tif(typeof event.data === \"string\" && event.data.indexOf(\"webpackHotUpdate\") === 0) {\n\t\t\tlastData = event.data;\n\t\t\tif(!upToDate() && module.hot.status() === \"idle\") {\n\t\t\t\tconsole.log(\"[HMR] Checking for updates on the server...\");\n\t\t\t\tcheck();\n\t\t\t}\n\t\t}\n\t});\n\tconsole.log(\"[HMR] Waiting for update signal from WDS...\");\n} else {\n\tthrow new Error(\"[HMR] Hot Module Replacement is disabled.\");\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/hot/only-dev-server.js\n ** module id = 1\n ** module chunks = 0\n **/","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nmodule.exports = function(updatedModules, renewedModules) {\n\tvar unacceptedModules = updatedModules.filter(function(moduleId) {\n\t\treturn renewedModules && renewedModules.indexOf(moduleId) < 0;\n\t});\n\n\tif(unacceptedModules.length > 0) {\n\t\tconsole.warn(\"[HMR] The following modules couldn't be hot updated: (They would need a full reload!)\");\n\t\tunacceptedModules.forEach(function(moduleId) {\n\t\t\tconsole.warn(\"[HMR]  - \" + moduleId);\n\t\t});\n\t}\n\n\tif(!renewedModules || renewedModules.length === 0) {\n\t\tconsole.log(\"[HMR] Nothing hot updated.\");\n\t} else {\n\t\tconsole.log(\"[HMR] Updated modules:\");\n\t\trenewedModules.forEach(function(moduleId) {\n\t\t\tconsole.log(\"[HMR]  - \" + moduleId);\n\t\t});\n\t}\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/hot/log-apply-result.js\n ** module id = 2\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport 'es5-shim'\nimport 'babel-polyfill'\nimport alt from '../alt'\nimport UID from '../libraries/UniqueId'\nimport utils from '../libraries/utils'\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport Crouton from 'react-crouton'\nimport ClassNames from 'classnames'\nimport ReactTooltip from 'react-tooltip'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport DeletionManager from '../libraries/DeletionManager'\nimport SelectionManager from '../libraries/SelectionManager'\nimport ResizableManager from '../libraries/ResizableManager'\nimport DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'\nimport RiftHeader from './RiftHeader'\nimport CanvasPanel from './CanvasPanel'\nimport CatalogPanel from './CatalogPanel'\nimport DetailsPanel from './DetailsPanel'\nimport ModalOverlay from './ModalOverlay'\nimport ComposerAppToolbar from './ComposerAppToolbar'\nimport PanelResizeAction from '../actions/PanelResizeAction'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport ComposerAppStore from '../stores/ComposerAppStore'\nimport CatalogDataStore from '../stores/CatalogDataStore'\n\nimport 'normalize.css'\nimport '../styles/AppRoot.scss'\n\nconst resizeManager = new ResizableManager(window);\n\nconst clearLocalStorage = utils.getSearchParams(window.location).hasOwnProperty('clearLocalStorage');\n\nconst preventDefault = e => e.preventDefault();\nconst clearDragState = () => ComposerAppActions.setDragState(null);\n\nconst ComposerApp = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn ComposerAppStore.getState();\n\t},\n\tgetDefaultProps() {\n\t\treturn {};\n\t},\n\tcomponentWillMount() {\n\t\tif (clearLocalStorage) {\n\t\t\twindow.localStorage.clear();\n\t\t}\n\t\tthis.state.isLoading = CatalogDataStore.getState().isLoading;\n\t\tComposerAppStore.listen(this.onChange);\n\t\tCatalogDataStore.listen(this.onCatalogDataChanged);\n\t\twindow.addEventListener('resize', this.resize);\n\t\twindow.onbeforeunload = this.onBeforeUnload;\n\t\t// prevent browser from downloading any drop outside of our specific drop zones\n\t\twindow.addEventListener('dragover', preventDefault);\n\t\twindow.addEventListener('drop', preventDefault);\n\t\t// ensure drags initiated in the app clear the state on drop\n\t\twindow.addEventListener('drop', clearDragState);\n\t\tDeletionManager.addEventListeners();\n\t},\n\tcomponentWillUnmount() {\n\t\twindow.removeEventListener('resize', this.resize);\n\t\twindow.removeEventListener('dragover', preventDefault);\n\t\twindow.removeEventListener('drop', preventDefault);\n\t\twindow.removeEventListener('drop', clearDragState);\n\t\t// resizeManager automatically registered its event handlers\n\t\tresizeManager.removeAllEventListeners();\n\t\tComposerAppStore.unlisten(this.onChange);\n\t\tCatalogDataStore.unlisten(this.onCatalogDataChanged);\n\t\tDeletionManager.removeEventListeners();\n\t\tSelectionManager.removeEventListeners();\n\t},\n\tcomponentDidMount() {\n\t\tresizeManager.addAllEventListeners();\n\t\tconst snapshot = window.localStorage.getItem('composer');\n\t\tif (snapshot) {\n\t\t\talt.bootstrap(snapshot);\n\t\t}\n\t\tdocument.body.addEventListener('keydown', (event) => {\n\t\t\t// prevent details editor form from blowing up the app\n\t\t\tconst ENTER_KEY = 13;\n\t\t\tif (event.which === ENTER_KEY) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t},\n\tresize(e) {\n\t\tPanelResizeAction.resize(e);\n\t},\n\trender() {\n\t\tlet cpNumber = 0;\n\t\tconst classNames = ClassNames('ComposerApp');\n\t\tconst isNew = this.state.item && this.state.item.meta.isNew;\n\t\tconst hasItem = this.state.item && this.state.item.meta;\n\t\tconst isModified = this.state.item && this.state.item.meta.modified;\n\t\tconst isEditingNSD = this.state.item && this.state.item.meta && /nsd/.test(this.state.item.meta.type);\n\t\tconst isEditingVNFD = this.state.item && this.state.item.meta && /vnfd/.test(this.state.item.meta.type);\n\t\tconst containers = [this.state.item].reduce(DescriptorModelFactory.buildCatalogItemFactory(CatalogDataStore.getState().catalogs), []);\n\t\tcontainers.filter(d => DescriptorModelFactory.isConnectionPoint(d)).forEach(d => {\n\t\t\td.cpNumber = ++cpNumber;\n\t\t\tcontainers.filter(d => DescriptorModelFactory.isVnfdConnectionPointRef(d)).filter(ref => ref.key === d.key).forEach(ref => ref.cpNumber = d.cpNumber);\n\t\t});\n\t\tconst canvasTitle = containers.length ? containers[0].model.name : '';\n\t\tconst hasNoCatalogs = CatalogDataStore.getState().catalogs.length === 0;\n\t\tconst isLoading = this.state.isLoading;\n\t\treturn (\n\t\t\t<div className=\"AppRoot\">\n\t\t\t\t<i className=\"corner-accent top left\" />\n\t\t\t\t<i className=\"corner-accent top right\" />\n\t\t\t\t<i className=\"corner-accent bottom left\" />\n\t\t\t\t<i className=\"corner-accent bottom right\" />\n\t\t\t\t<div className=\"AppHeader\">\n\t\t\t\t\t<RiftHeader />\n\t\t\t\t</div>\n\t\t\t\t<Crouton id={Date.now()} type={this.state.messageType} message={this.state.message} onDismiss={ComposerAppActions.clearError} />\n\t\t\t\t<div className=\"AppBody\">\n\t\t\t\t\t<div className={classNames}>\n\t\t\t\t\t\t<CatalogPanel layout={this.state.layout} isLoading={isLoading} hasNoCatalogs={hasNoCatalogs} filterByType={this.state.filterCatalogByTypeValue} />\n\t\t\t\t\t\t<CanvasPanel ref=\"canvasPanel\" layout={this.state.layout} hasNoCatalogs={hasNoCatalogs} showMore={this.state.showMore} containers={containers} title={canvasTitle} zoom={this.state.zoom} />\n\t\t\t\t\t\t<DetailsPanel layout={this.state.layout} hasNoCatalogs={hasNoCatalogs} showMore={this.state.showMore} containers={containers} showJSONViewer={this.state.showJSONViewer} />\n\t\t\t\t\t\t<ComposerAppToolbar layout={this.state.layout} showMore={this.state.showMore} isEditingNSD={isEditingNSD} isEditingVNFD={isEditingVNFD} isModified={isModified} isNew={isNew} disabled={!hasItem} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<ModalOverlay />\n\t\t\t\t<ReactTooltip effect=\"solid\" html={true} />\n\t\t\t</div>\n\t\t);\n\t},\n\tonChange(state) {\n\t\tthis.setState(state);\n\t},\n\tonCatalogDataChanged(catalogDataState) {\n\t\tconst catalogs = catalogDataState.catalogs;\n\t\tconst unsavedChanges = catalogs.reduce((result, catalog) => {\n\t\t\tif (result) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn catalog.descriptors.reduce((result, descriptor) => {\n\t\t\t\tif (result) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\treturn descriptor.meta.modified;\n\t\t\t}, false);\n\t\t}, false);\n\t\tthis.setState({\n\t\t\tunsavedChanges: unsavedChanges,\n\t\t\tisLoading: catalogDataState.isLoading\n\t\t});\n\t},\n\tonBeforeUnload() {\n\t\t// https://trello.com/c/c8v321Xx/160-prompt-user-to-save-changes\n\t\t//const snapshot = alt.takeSnapshot();\n\t\t//window.localStorage.setItem('composer', snapshot);\n\t\tif (this.state.unsavedChanges) {\n\t\t\treturn 'You have unsaved changes. If you do not onboard (or update) your changes they will be lost.';\n\t\t}\n\t}\n});\n\nReactDOM.render(<ComposerApp />, document.getElementById('content'));\n\nexport default ComposerApp;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/ComposerApp.js\n **/","module.exports = function(module) {\n\tif(!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tmodule.children = [];\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/module.js\n ** module id = 4\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = require('./makeMakeHot');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/index.js\n ** module id = 5\n ** module chunks = 0\n **/","'use strict';\n\nvar makePatchReactClass = require('./makePatchReactClass');\n\n/**\n * Returns a function that, when invoked, patches a React class with a new\n * version of itself. To patch different classes, pass different IDs.\n */\nmodule.exports = function makeMakeHot(getRootInstances, React) {\n  if (typeof getRootInstances !== 'function') {\n    throw new Error('Expected getRootInstances to be a function.');\n  }\n\n  var patchers = {};\n\n  return function makeHot(NextClass, persistentId) {\n    persistentId = persistentId || NextClass.displayName || NextClass.name;\n\n    if (!persistentId) {\n      console.error(\n        'Hot reload is disabled for one of your types. To enable it, pass a ' +\n        'string uniquely identifying this class within this current module ' +\n        'as a second parameter to makeHot.'\n      );\n      return NextClass;\n    }\n\n    if (!patchers[persistentId]) {\n      patchers[persistentId] = makePatchReactClass(getRootInstances, React);\n    }\n\n    var patchReactClass = patchers[persistentId];\n    return patchReactClass(NextClass);\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/makeMakeHot.js\n ** module id = 6\n ** module chunks = 0\n **/","'use strict';\n\nvar makeAssimilatePrototype = require('./makeAssimilatePrototype'),\n    requestForceUpdateAll = require('./requestForceUpdateAll');\n\nfunction hasNonStubTypeProperty(ReactClass) {\n  if (!ReactClass.hasOwnProperty('type')) {\n    return false;\n  }\n\n  var descriptor = Object.getOwnPropertyDescriptor(ReactClass, 'type');\n  if (typeof descriptor.get === 'function') {\n    return false;\n  }\n\n  return true;\n}\n\nfunction getPrototype(ReactClass) {\n  var prototype = ReactClass.prototype,\n      seemsLegit = prototype && typeof prototype.render === 'function';\n\n  if (!seemsLegit && hasNonStubTypeProperty(ReactClass)) {\n    prototype = ReactClass.type.prototype;\n  }\n\n  return prototype;\n}\n\n/**\n * Returns a function that will patch React class with new versions of itself\n * on subsequent invocations. Both legacy and ES6 style classes are supported.\n */\nmodule.exports = function makePatchReactClass(getRootInstances, React) {\n  var assimilatePrototype = makeAssimilatePrototype(),\n      FirstClass = null;\n\n  return function patchReactClass(NextClass) {\n    var nextPrototype = getPrototype(NextClass);\n    assimilatePrototype(nextPrototype);\n\n    if (FirstClass) {\n      requestForceUpdateAll(getRootInstances, React);\n    }\n\n    return FirstClass || (FirstClass = NextClass);\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/makePatchReactClass.js\n ** module id = 7\n ** module chunks = 0\n **/","'use strict';\n\n/**\n * Returns a function that establishes the first prototype passed to it\n * as the \"source of truth\" and patches its methods on subsequent invocations,\n * also patching current and previous prototypes to forward calls to it.\n */\nmodule.exports = function makeAssimilatePrototype() {\n  var storedPrototype,\n      knownPrototypes = [];\n\n  function wrapMethod(key) {\n    return function () {\n      if (storedPrototype[key]) {\n        return storedPrototype[key].apply(this, arguments);\n      }\n    };\n  }\n\n  function patchProperty(proto, key) {\n    proto[key] = storedPrototype[key];\n\n    if (typeof proto[key] !== 'function' ||\n      key === 'type' ||\n      key === 'constructor') {\n      return;\n    }\n\n    proto[key] = wrapMethod(key);\n\n    if (storedPrototype[key].isReactClassApproved) {\n      proto[key].isReactClassApproved = storedPrototype[key].isReactClassApproved;\n    }\n\n    if (proto.__reactAutoBindMap && proto.__reactAutoBindMap[key]) {\n      proto.__reactAutoBindMap[key] = proto[key];\n    }\n  }\n\n  function updateStoredPrototype(freshPrototype) {\n    storedPrototype = {};\n\n    Object.getOwnPropertyNames(freshPrototype).forEach(function (key) {\n      storedPrototype[key] = freshPrototype[key];\n    });\n  }\n\n  function reconcileWithStoredPrototypes(freshPrototype) {\n    knownPrototypes.push(freshPrototype);\n    knownPrototypes.forEach(function (proto) {\n      Object.getOwnPropertyNames(storedPrototype).forEach(function (key) {\n        patchProperty(proto, key);\n      });\n    });\n  }\n\n  return function assimilatePrototype(freshPrototype) {\n    if (Object.prototype.hasOwnProperty.call(freshPrototype, '__isAssimilatedByReactHotAPI')) {\n      return;\n    }\n\n    updateStoredPrototype(freshPrototype);\n    reconcileWithStoredPrototypes(freshPrototype);\n    freshPrototype.__isAssimilatedByReactHotAPI = true;\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/makeAssimilatePrototype.js\n ** module id = 8\n ** module chunks = 0\n **/","var deepForceUpdate = require('./deepForceUpdate');\n\nvar isRequestPending = false;\n\nmodule.exports = function requestForceUpdateAll(getRootInstances, React) {\n  if (isRequestPending) {\n    return;\n  }\n\n  /**\n   * Forces deep re-render of all mounted React components.\n   * Hats off to Omar Skalli (@Chetane) for suggesting this approach:\n   * https://gist.github.com/Chetane/9a230a9fdcdca21a4e29\n   */\n  function forceUpdateAll() {\n    isRequestPending = false;\n\n    var rootInstances = getRootInstances(),\n        rootInstance;\n\n    for (var key in rootInstances) {\n      if (rootInstances.hasOwnProperty(key)) {\n        rootInstance = rootInstances[key];\n\n        // `|| rootInstance` for React 0.12 and earlier\n        rootInstance = rootInstance._reactInternalInstance || rootInstance;\n        deepForceUpdate(rootInstance, React);\n      }\n    }\n  }\n\n  setTimeout(forceUpdateAll);\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/requestForceUpdateAll.js\n ** module id = 9\n ** module chunks = 0\n **/","'use strict';\n\nvar bindAutoBindMethods = require('./bindAutoBindMethods');\nvar traverseRenderedChildren = require('./traverseRenderedChildren');\n\nfunction setPendingForceUpdate(internalInstance) {\n  if (internalInstance._pendingForceUpdate === false) {\n    internalInstance._pendingForceUpdate = true;\n  }\n}\n\nfunction forceUpdateIfPending(internalInstance, React) {\n  if (internalInstance._pendingForceUpdate === true) {\n    // `|| internalInstance` for React 0.12 and earlier\n    var instance = internalInstance._instance || internalInstance;\n\n    if (instance.forceUpdate) {\n      instance.forceUpdate();\n    } else if (React && React.Component) {\n      React.Component.prototype.forceUpdate.call(instance);\n    }\n  }\n}\n\n/**\n * Updates a React component recursively, so even if children define funky\n * `shouldComponentUpdate`, they are forced to re-render.\n * Makes sure that any newly added methods are properly auto-bound.\n */\nfunction deepForceUpdate(internalInstance, React) {\n  traverseRenderedChildren(internalInstance, bindAutoBindMethods);\n  traverseRenderedChildren(internalInstance, setPendingForceUpdate);\n  traverseRenderedChildren(internalInstance, forceUpdateIfPending, React);\n}\n\nmodule.exports = deepForceUpdate;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/deepForceUpdate.js\n ** module id = 10\n ** module chunks = 0\n **/","'use strict';\n\nfunction bindAutoBindMethod(component, method) {\n  var boundMethod = method.bind(component);\n\n  boundMethod.__reactBoundContext = component;\n  boundMethod.__reactBoundMethod = method;\n  boundMethod.__reactBoundArguments = null;\n\n  var componentName = component.constructor.displayName,\n      _bind = boundMethod.bind;\n\n  boundMethod.bind = function (newThis) {\n    var args = Array.prototype.slice.call(arguments, 1);\n    if (newThis !== component && newThis !== null) {\n      console.warn(\n        'bind(): React component methods may only be bound to the ' +\n        'component instance. See ' + componentName\n      );\n    } else if (!args.length) {\n      console.warn(\n        'bind(): You are binding a component method to the component. ' +\n        'React does this for you automatically in a high-performance ' +\n        'way, so you can safely remove this call. See ' + componentName\n      );\n      return boundMethod;\n    }\n\n    var reboundMethod = _bind.apply(boundMethod, arguments);\n    reboundMethod.__reactBoundContext = component;\n    reboundMethod.__reactBoundMethod = method;\n    reboundMethod.__reactBoundArguments = args;\n\n    return reboundMethod;\n  };\n\n  return boundMethod;\n}\n\n/**\n * Performs auto-binding similar to how React does it.\n * Skips already auto-bound methods.\n * Based on https://github.com/facebook/react/blob/b264372e2b3ad0b0c0c0cc95a2f383e4a1325c3d/src/classic/class/ReactClass.js#L639-L705\n */\nmodule.exports = function bindAutoBindMethods(internalInstance) {\n  var component = typeof internalInstance.getPublicInstance === 'function' ?\n    internalInstance.getPublicInstance() :\n    internalInstance;\n\n  if (!component) {\n    // React 0.14 stateless component has no instance\n    return;\n  }\n\n  for (var autoBindKey in component.__reactAutoBindMap) {\n    if (!component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {\n      continue;\n    }\n\n    // Skip already bound methods\n    if (component.hasOwnProperty(autoBindKey) &&\n        component[autoBindKey].__reactBoundContext === component) {\n      continue;\n    }\n\n    var method = component.__reactAutoBindMap[autoBindKey];\n    component[autoBindKey] = bindAutoBindMethod(component, method);\n  }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/bindAutoBindMethods.js\n ** module id = 11\n ** module chunks = 0\n **/","'use strict';\n\nfunction traverseRenderedChildren(internalInstance, callback, argument) {\n  callback(internalInstance, argument);\n\n  if (internalInstance._renderedComponent) {\n    traverseRenderedChildren(\n      internalInstance._renderedComponent,\n      callback,\n      argument\n    );\n  } else {\n    for (var key in internalInstance._renderedChildren) {\n      traverseRenderedChildren(\n        internalInstance._renderedChildren[key],\n        callback,\n        argument\n      );\n    }\n  }\n}\n\nmodule.exports = traverseRenderedChildren;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/~/react-hot-api/modules/traverseRenderedChildren.js\n ** module id = 12\n ** module chunks = 0\n **/","'use strict';\n\nvar getRootInstancesFromReactMount = require('./getRootInstancesFromReactMount');\n\nvar injectedProvider = null,\n    didWarn = false;\n\nfunction warnOnce() {\n  if (!didWarn) {\n    console.warn(\n      'It appears that React Hot Loader isn\\'t configured correctly. ' +\n      'If you\\'re using NPM, make sure your dependencies don\\'t drag duplicate React distributions into their node_modules and that require(\"react\") corresponds to the React instance you render your app with.',\n      'If you\\'re using a precompiled version of React, see https://github.com/gaearon/react-hot-loader/tree/master/docs#usage-with-external-react for integration instructions.'\n    );\n  }\n\n  didWarn = true;\n}\n\nvar RootInstanceProvider = {\n  injection: {\n    injectProvider: function (provider) {\n      injectedProvider = provider;\n    }\n  },\n\n  getRootInstances: function (ReactMount) {\n    if (injectedProvider) {\n      return injectedProvider.getRootInstances();\n    }\n\n    var instances = ReactMount && getRootInstancesFromReactMount(ReactMount) || [];\n    if (!Object.keys(instances).length) {\n      warnOnce();\n    }\n\n    return instances;\n  }\n};\n\nmodule.exports = RootInstanceProvider;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/RootInstanceProvider.js\n ** module id = 13\n ** module chunks = 0\n **/","'use strict';\n\nfunction getRootInstancesFromReactMount(ReactMount) {\n  return ReactMount._instancesByReactRootID || ReactMount._instancesByContainerID || [];\n}\n\nmodule.exports = getRootInstancesFromReactMount;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/getRootInstancesFromReactMount.js\n ** module id = 14\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactMount\n */\n\n'use strict';\n\nvar DOMProperty = require('./DOMProperty');\nvar ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags');\nvar ReactElement = require('./ReactElement');\nvar ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry');\nvar ReactInstanceHandles = require('./ReactInstanceHandles');\nvar ReactInstanceMap = require('./ReactInstanceMap');\nvar ReactMarkupChecksum = require('./ReactMarkupChecksum');\nvar ReactPerf = require('./ReactPerf');\nvar ReactReconciler = require('./ReactReconciler');\nvar ReactUpdateQueue = require('./ReactUpdateQueue');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar assign = require('./Object.assign');\nvar emptyObject = require('fbjs/lib/emptyObject');\nvar containsNode = require('fbjs/lib/containsNode');\nvar instantiateReactComponent = require('./instantiateReactComponent');\nvar invariant = require('fbjs/lib/invariant');\nvar setInnerHTML = require('./setInnerHTML');\nvar shouldUpdateReactComponent = require('./shouldUpdateReactComponent');\nvar validateDOMNesting = require('./validateDOMNesting');\nvar warning = require('fbjs/lib/warning');\n\nvar ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;\nvar nodeCache = {};\n\nvar ELEMENT_NODE_TYPE = 1;\nvar DOC_NODE_TYPE = 9;\nvar DOCUMENT_FRAGMENT_NODE_TYPE = 11;\n\nvar ownerDocumentContextKey = '__ReactMount_ownerDocument$' + Math.random().toString(36).slice(2);\n\n/** Mapping from reactRootID to React component instance. */\nvar instancesByReactRootID = {};\n\n/** Mapping from reactRootID to `container` nodes. */\nvar containersByReactRootID = {};\n\nif (process.env.NODE_ENV !== 'production') {\n  /** __DEV__-only mapping from reactRootID to root elements. */\n  var rootElementsByReactRootID = {};\n}\n\n// Used to store breadth-first search state in findComponentRoot.\nvar findComponentRootReusableArray = [];\n\n/**\n * Finds the index of the first character\n * that's not common between the two given strings.\n *\n * @return {number} the index of the character where the strings diverge\n */\nfunction firstDifferenceIndex(string1, string2) {\n  var minLen = Math.min(string1.length, string2.length);\n  for (var i = 0; i < minLen; i++) {\n    if (string1.charAt(i) !== string2.charAt(i)) {\n      return i;\n    }\n  }\n  return string1.length === string2.length ? -1 : minLen;\n}\n\n/**\n * @param {DOMElement|DOMDocument} container DOM element that may contain\n * a React component\n * @return {?*} DOM element that may have the reactRoot ID, or null.\n */\nfunction getReactRootElementInContainer(container) {\n  if (!container) {\n    return null;\n  }\n\n  if (container.nodeType === DOC_NODE_TYPE) {\n    return container.documentElement;\n  } else {\n    return container.firstChild;\n  }\n}\n\n/**\n * @param {DOMElement} container DOM element that may contain a React component.\n * @return {?string} A \"reactRoot\" ID, if a React component is rendered.\n */\nfunction getReactRootID(container) {\n  var rootElement = getReactRootElementInContainer(container);\n  return rootElement && ReactMount.getID(rootElement);\n}\n\n/**\n * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form\n * element can return its control whose name or ID equals ATTR_NAME. All\n * DOM nodes support `getAttributeNode` but this can also get called on\n * other objects so just return '' if we're given something other than a\n * DOM node (such as window).\n *\n * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.\n * @return {string} ID of the supplied `domNode`.\n */\nfunction getID(node) {\n  var id = internalGetID(node);\n  if (id) {\n    if (nodeCache.hasOwnProperty(id)) {\n      var cached = nodeCache[id];\n      if (cached !== node) {\n        !!isValid(cached, id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', ATTR_NAME, id) : invariant(false) : undefined;\n\n        nodeCache[id] = node;\n      }\n    } else {\n      nodeCache[id] = node;\n    }\n  }\n\n  return id;\n}\n\nfunction internalGetID(node) {\n  // If node is something like a window, document, or text node, none of\n  // which support attributes or a .getAttribute method, gracefully return\n  // the empty string, as if the attribute were missing.\n  return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';\n}\n\n/**\n * Sets the React-specific ID of the given node.\n *\n * @param {DOMElement} node The DOM node whose ID will be set.\n * @param {string} id The value of the ID attribute.\n */\nfunction setID(node, id) {\n  var oldID = internalGetID(node);\n  if (oldID !== id) {\n    delete nodeCache[oldID];\n  }\n  node.setAttribute(ATTR_NAME, id);\n  nodeCache[id] = node;\n}\n\n/**\n * Finds the node with the supplied React-generated DOM ID.\n *\n * @param {string} id A React-generated DOM ID.\n * @return {DOMElement} DOM node with the suppled `id`.\n * @internal\n */\nfunction getNode(id) {\n  if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {\n    nodeCache[id] = ReactMount.findReactNodeByID(id);\n  }\n  return nodeCache[id];\n}\n\n/**\n * Finds the node with the supplied public React instance.\n *\n * @param {*} instance A public React instance.\n * @return {?DOMElement} DOM node with the suppled `id`.\n * @internal\n */\nfunction getNodeFromInstance(instance) {\n  var id = ReactInstanceMap.get(instance)._rootNodeID;\n  if (ReactEmptyComponentRegistry.isNullComponentID(id)) {\n    return null;\n  }\n  if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {\n    nodeCache[id] = ReactMount.findReactNodeByID(id);\n  }\n  return nodeCache[id];\n}\n\n/**\n * A node is \"valid\" if it is contained by a currently mounted container.\n *\n * This means that the node does not have to be contained by a document in\n * order to be considered valid.\n *\n * @param {?DOMElement} node The candidate DOM node.\n * @param {string} id The expected ID of the node.\n * @return {boolean} Whether the node is contained by a mounted container.\n */\nfunction isValid(node, id) {\n  if (node) {\n    !(internalGetID(node) === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactMount: Unexpected modification of `%s`', ATTR_NAME) : invariant(false) : undefined;\n\n    var container = ReactMount.findReactContainerForID(id);\n    if (container && containsNode(container, node)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Causes the cache to forget about one React-specific ID.\n *\n * @param {string} id The ID to forget.\n */\nfunction purgeID(id) {\n  delete nodeCache[id];\n}\n\nvar deepestNodeSoFar = null;\nfunction findDeepestCachedAncestorImpl(ancestorID) {\n  var ancestor = nodeCache[ancestorID];\n  if (ancestor && isValid(ancestor, ancestorID)) {\n    deepestNodeSoFar = ancestor;\n  } else {\n    // This node isn't populated in the cache, so presumably none of its\n    // descendants are. Break out of the loop.\n    return false;\n  }\n}\n\n/**\n * Return the deepest cached node whose ID is a prefix of `targetID`.\n */\nfunction findDeepestCachedAncestor(targetID) {\n  deepestNodeSoFar = null;\n  ReactInstanceHandles.traverseAncestors(targetID, findDeepestCachedAncestorImpl);\n\n  var foundNode = deepestNodeSoFar;\n  deepestNodeSoFar = null;\n  return foundNode;\n}\n\n/**\n * Mounts this component and inserts it into the DOM.\n *\n * @param {ReactComponent} componentInstance The instance to mount.\n * @param {string} rootID DOM ID of the root node.\n * @param {DOMElement} container DOM element to mount into.\n * @param {ReactReconcileTransaction} transaction\n * @param {boolean} shouldReuseMarkup If true, do not insert markup\n */\nfunction mountComponentIntoNode(componentInstance, rootID, container, transaction, shouldReuseMarkup, context) {\n  if (ReactDOMFeatureFlags.useCreateElement) {\n    context = assign({}, context);\n    if (container.nodeType === DOC_NODE_TYPE) {\n      context[ownerDocumentContextKey] = container;\n    } else {\n      context[ownerDocumentContextKey] = container.ownerDocument;\n    }\n  }\n  if (process.env.NODE_ENV !== 'production') {\n    if (context === emptyObject) {\n      context = {};\n    }\n    var tag = container.nodeName.toLowerCase();\n    context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(null, tag, null);\n  }\n  var markup = ReactReconciler.mountComponent(componentInstance, rootID, transaction, context);\n  componentInstance._renderedComponent._topLevelWrapper = componentInstance;\n  ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup, transaction);\n}\n\n/**\n * Batched mount.\n *\n * @param {ReactComponent} componentInstance The instance to mount.\n * @param {string} rootID DOM ID of the root node.\n * @param {DOMElement} container DOM element to mount into.\n * @param {boolean} shouldReuseMarkup If true, do not insert markup\n */\nfunction batchedMountComponentIntoNode(componentInstance, rootID, container, shouldReuseMarkup, context) {\n  var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(\n  /* forceHTML */shouldReuseMarkup);\n  transaction.perform(mountComponentIntoNode, null, componentInstance, rootID, container, transaction, shouldReuseMarkup, context);\n  ReactUpdates.ReactReconcileTransaction.release(transaction);\n}\n\n/**\n * Unmounts a component and removes it from the DOM.\n *\n * @param {ReactComponent} instance React component instance.\n * @param {DOMElement} container DOM element to unmount from.\n * @final\n * @internal\n * @see {ReactMount.unmountComponentAtNode}\n */\nfunction unmountComponentFromNode(instance, container) {\n  ReactReconciler.unmountComponent(instance);\n\n  if (container.nodeType === DOC_NODE_TYPE) {\n    container = container.documentElement;\n  }\n\n  // http://jsperf.com/emptying-a-node\n  while (container.lastChild) {\n    container.removeChild(container.lastChild);\n  }\n}\n\n/**\n * True if the supplied DOM node has a direct React-rendered child that is\n * not a React root element. Useful for warning in `render`,\n * `unmountComponentAtNode`, etc.\n *\n * @param {?DOMElement} node The candidate DOM node.\n * @return {boolean} True if the DOM element contains a direct child that was\n * rendered by React but is not a root element.\n * @internal\n */\nfunction hasNonRootReactChild(node) {\n  var reactRootID = getReactRootID(node);\n  return reactRootID ? reactRootID !== ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID) : false;\n}\n\n/**\n * Returns the first (deepest) ancestor of a node which is rendered by this copy\n * of React.\n */\nfunction findFirstReactDOMImpl(node) {\n  // This node might be from another React instance, so we make sure not to\n  // examine the node cache here\n  for (; node && node.parentNode !== node; node = node.parentNode) {\n    if (node.nodeType !== 1) {\n      // Not a DOMElement, therefore not a React component\n      continue;\n    }\n    var nodeID = internalGetID(node);\n    if (!nodeID) {\n      continue;\n    }\n    var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);\n\n    // If containersByReactRootID contains the container we find by crawling up\n    // the tree, we know that this instance of React rendered the node.\n    // nb. isValid's strategy (with containsNode) does not work because render\n    // trees may be nested and we don't want a false positive in that case.\n    var current = node;\n    var lastID;\n    do {\n      lastID = internalGetID(current);\n      current = current.parentNode;\n      if (current == null) {\n        // The passed-in node has been detached from the container it was\n        // originally rendered into.\n        return null;\n      }\n    } while (lastID !== reactRootID);\n\n    if (current === containersByReactRootID[reactRootID]) {\n      return node;\n    }\n  }\n  return null;\n}\n\n/**\n * Temporary (?) hack so that we can store all top-level pending updates on\n * composites instead of having to worry about different types of components\n * here.\n */\nvar TopLevelWrapper = function () {};\nTopLevelWrapper.prototype.isReactComponent = {};\nif (process.env.NODE_ENV !== 'production') {\n  TopLevelWrapper.displayName = 'TopLevelWrapper';\n}\nTopLevelWrapper.prototype.render = function () {\n  // this.props is actually a ReactElement\n  return this.props;\n};\n\n/**\n * Mounting is the process of initializing a React component by creating its\n * representative DOM elements and inserting them into a supplied `container`.\n * Any prior content inside `container` is destroyed in the process.\n *\n *   ReactMount.render(\n *     component,\n *     document.getElementById('container')\n *   );\n *\n *   <div id=\"container\">                   <-- Supplied `container`.\n *     <div data-reactid=\".3\">              <-- Rendered reactRoot of React\n *       // ...                                 component.\n *     </div>\n *   </div>\n *\n * Inside of `container`, the first element rendered is the \"reactRoot\".\n */\nvar ReactMount = {\n\n  TopLevelWrapper: TopLevelWrapper,\n\n  /** Exposed for debugging purposes **/\n  _instancesByReactRootID: instancesByReactRootID,\n\n  /**\n   * This is a hook provided to support rendering React components while\n   * ensuring that the apparent scroll position of its `container` does not\n   * change.\n   *\n   * @param {DOMElement} container The `container` being rendered into.\n   * @param {function} renderCallback This must be called once to do the render.\n   */\n  scrollMonitor: function (container, renderCallback) {\n    renderCallback();\n  },\n\n  /**\n   * Take a component that's already mounted into the DOM and replace its props\n   * @param {ReactComponent} prevComponent component instance already in the DOM\n   * @param {ReactElement} nextElement component instance to render\n   * @param {DOMElement} container container to render into\n   * @param {?function} callback function triggered on completion\n   */\n  _updateRootComponent: function (prevComponent, nextElement, container, callback) {\n    ReactMount.scrollMonitor(container, function () {\n      ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement);\n      if (callback) {\n        ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);\n      }\n    });\n\n    if (process.env.NODE_ENV !== 'production') {\n      // Record the root element in case it later gets transplanted.\n      rootElementsByReactRootID[getReactRootID(container)] = getReactRootElementInContainer(container);\n    }\n\n    return prevComponent;\n  },\n\n  /**\n   * Register a component into the instance map and starts scroll value\n   * monitoring\n   * @param {ReactComponent} nextComponent component instance to render\n   * @param {DOMElement} container container to render into\n   * @return {string} reactRoot ID prefix\n   */\n  _registerComponent: function (nextComponent, container) {\n    !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : invariant(false) : undefined;\n\n    ReactBrowserEventEmitter.ensureScrollValueMonitoring();\n\n    var reactRootID = ReactMount.registerContainer(container);\n    instancesByReactRootID[reactRootID] = nextComponent;\n    return reactRootID;\n  },\n\n  /**\n   * Render a new component into the DOM.\n   * @param {ReactElement} nextElement element to render\n   * @param {DOMElement} container container to render into\n   * @param {boolean} shouldReuseMarkup if we should skip the markup insertion\n   * @return {ReactComponent} nextComponent\n   */\n  _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) {\n    // Various parts of our code (such as ReactCompositeComponent's\n    // _renderValidatedComponent) assume that calls to render aren't nested;\n    // verify that that's the case.\n    process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : undefined;\n\n    var componentInstance = instantiateReactComponent(nextElement, null);\n    var reactRootID = ReactMount._registerComponent(componentInstance, container);\n\n    // The initial render is synchronous but any updates that happen during\n    // rendering, in componentWillMount or componentDidMount, will be batched\n    // according to the current batching strategy.\n\n    ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, reactRootID, container, shouldReuseMarkup, context);\n\n    if (process.env.NODE_ENV !== 'production') {\n      // Record the root element in case it later gets transplanted.\n      rootElementsByReactRootID[reactRootID] = getReactRootElementInContainer(container);\n    }\n\n    return componentInstance;\n  },\n\n  /**\n   * Renders a React component into the DOM in the supplied `container`.\n   *\n   * If the React component was previously rendered into `container`, this will\n   * perform an update on it and only mutate the DOM as necessary to reflect the\n   * latest React component.\n   *\n   * @param {ReactComponent} parentComponent The conceptual parent of this render tree.\n   * @param {ReactElement} nextElement Component element to render.\n   * @param {DOMElement} container DOM element to render into.\n   * @param {?function} callback function triggered on completion\n   * @return {ReactComponent} Component instance rendered in `container`.\n   */\n  renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {\n    !(parentComponent != null && parentComponent._reactInternalInstance != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : invariant(false) : undefined;\n    return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback);\n  },\n\n  _renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {\n    !ReactElement.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing an element string, make sure to instantiate ' + 'it by passing it to React.createElement.' : typeof nextElement === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' :\n    // Check if it quacks like an element\n    nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : invariant(false) : undefined;\n\n    process.env.NODE_ENV !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : undefined;\n\n    var nextWrappedElement = new ReactElement(TopLevelWrapper, null, null, null, null, null, nextElement);\n\n    var prevComponent = instancesByReactRootID[getReactRootID(container)];\n\n    if (prevComponent) {\n      var prevWrappedElement = prevComponent._currentElement;\n      var prevElement = prevWrappedElement.props;\n      if (shouldUpdateReactComponent(prevElement, nextElement)) {\n        var publicInst = prevComponent._renderedComponent.getPublicInstance();\n        var updatedCallback = callback && function () {\n          callback.call(publicInst);\n        };\n        ReactMount._updateRootComponent(prevComponent, nextWrappedElement, container, updatedCallback);\n        return publicInst;\n      } else {\n        ReactMount.unmountComponentAtNode(container);\n      }\n    }\n\n    var reactRootElement = getReactRootElementInContainer(container);\n    var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement);\n    var containerHasNonRootReactChild = hasNonRootReactChild(container);\n\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : undefined;\n\n      if (!containerHasReactMarkup || reactRootElement.nextSibling) {\n        var rootElementSibling = reactRootElement;\n        while (rootElementSibling) {\n          if (internalGetID(rootElementSibling)) {\n            process.env.NODE_ENV !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : undefined;\n            break;\n          }\n          rootElementSibling = rootElementSibling.nextSibling;\n        }\n      }\n    }\n\n    var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild;\n    var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, parentComponent != null ? parentComponent._reactInternalInstance._processChildContext(parentComponent._reactInternalInstance._context) : emptyObject)._renderedComponent.getPublicInstance();\n    if (callback) {\n      callback.call(component);\n    }\n    return component;\n  },\n\n  /**\n   * Renders a React component into the DOM in the supplied `container`.\n   *\n   * If the React component was previously rendered into `container`, this will\n   * perform an update on it and only mutate the DOM as necessary to reflect the\n   * latest React component.\n   *\n   * @param {ReactElement} nextElement Component element to render.\n   * @param {DOMElement} container DOM element to render into.\n   * @param {?function} callback function triggered on completion\n   * @return {ReactComponent} Component instance rendered in `container`.\n   */\n  render: function (nextElement, container, callback) {\n    return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback);\n  },\n\n  /**\n   * Registers a container node into which React components will be rendered.\n   * This also creates the \"reactRoot\" ID that will be assigned to the element\n   * rendered within.\n   *\n   * @param {DOMElement} container DOM element to register as a container.\n   * @return {string} The \"reactRoot\" ID of elements rendered within.\n   */\n  registerContainer: function (container) {\n    var reactRootID = getReactRootID(container);\n    if (reactRootID) {\n      // If one exists, make sure it is a valid \"reactRoot\" ID.\n      reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);\n    }\n    if (!reactRootID) {\n      // No valid \"reactRoot\" ID found, create one.\n      reactRootID = ReactInstanceHandles.createReactRootID();\n    }\n    containersByReactRootID[reactRootID] = container;\n    return reactRootID;\n  },\n\n  /**\n   * Unmounts and destroys the React component rendered in the `container`.\n   *\n   * @param {DOMElement} container DOM element containing a React component.\n   * @return {boolean} True if a component was found in and unmounted from\n   *                   `container`\n   */\n  unmountComponentAtNode: function (container) {\n    // Various parts of our code (such as ReactCompositeComponent's\n    // _renderValidatedComponent) assume that calls to render aren't nested;\n    // verify that that's the case. (Strictly speaking, unmounting won't cause a\n    // render but we still don't expect to be in a render call here.)\n    process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : undefined;\n\n    !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : invariant(false) : undefined;\n\n    var reactRootID = getReactRootID(container);\n    var component = instancesByReactRootID[reactRootID];\n    if (!component) {\n      // Check if the node being unmounted was rendered by React, but isn't a\n      // root node.\n      var containerHasNonRootReactChild = hasNonRootReactChild(container);\n\n      // Check if the container itself is a React root node.\n      var containerID = internalGetID(container);\n      var isContainerReactRoot = containerID && containerID === ReactInstanceHandles.getReactRootIDFromNodeID(containerID);\n\n      if (process.env.NODE_ENV !== 'production') {\n        process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : undefined;\n      }\n\n      return false;\n    }\n    ReactUpdates.batchedUpdates(unmountComponentFromNode, component, container);\n    delete instancesByReactRootID[reactRootID];\n    delete containersByReactRootID[reactRootID];\n    if (process.env.NODE_ENV !== 'production') {\n      delete rootElementsByReactRootID[reactRootID];\n    }\n    return true;\n  },\n\n  /**\n   * Finds the container DOM element that contains React component to which the\n   * supplied DOM `id` belongs.\n   *\n   * @param {string} id The ID of an element rendered by a React component.\n   * @return {?DOMElement} DOM element that contains the `id`.\n   */\n  findReactContainerForID: function (id) {\n    var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);\n    var container = containersByReactRootID[reactRootID];\n\n    if (process.env.NODE_ENV !== 'production') {\n      var rootElement = rootElementsByReactRootID[reactRootID];\n      if (rootElement && rootElement.parentNode !== container) {\n        process.env.NODE_ENV !== 'production' ? warning(\n        // Call internalGetID here because getID calls isValid which calls\n        // findReactContainerForID (this function).\n        internalGetID(rootElement) === reactRootID, 'ReactMount: Root element ID differed from reactRootID.') : undefined;\n        var containerChild = container.firstChild;\n        if (containerChild && reactRootID === internalGetID(containerChild)) {\n          // If the container has a new child with the same ID as the old\n          // root element, then rootElementsByReactRootID[reactRootID] is\n          // just stale and needs to be updated. The case that deserves a\n          // warning is when the container is empty.\n          rootElementsByReactRootID[reactRootID] = containerChild;\n        } else {\n          process.env.NODE_ENV !== 'production' ? warning(false, 'ReactMount: Root element has been removed from its original ' + 'container. New container: %s', rootElement.parentNode) : undefined;\n        }\n      }\n    }\n\n    return container;\n  },\n\n  /**\n   * Finds an element rendered by React with the supplied ID.\n   *\n   * @param {string} id ID of a DOM node in the React component.\n   * @return {DOMElement} Root DOM node of the React component.\n   */\n  findReactNodeByID: function (id) {\n    var reactRoot = ReactMount.findReactContainerForID(id);\n    return ReactMount.findComponentRoot(reactRoot, id);\n  },\n\n  /**\n   * Traverses up the ancestors of the supplied node to find a node that is a\n   * DOM representation of a React component rendered by this copy of React.\n   *\n   * @param {*} node\n   * @return {?DOMEventTarget}\n   * @internal\n   */\n  getFirstReactDOM: function (node) {\n    return findFirstReactDOMImpl(node);\n  },\n\n  /**\n   * Finds a node with the supplied `targetID` inside of the supplied\n   * `ancestorNode`.  Exploits the ID naming scheme to perform the search\n   * quickly.\n   *\n   * @param {DOMEventTarget} ancestorNode Search from this root.\n   * @pararm {string} targetID ID of the DOM representation of the component.\n   * @return {DOMEventTarget} DOM node with the supplied `targetID`.\n   * @internal\n   */\n  findComponentRoot: function (ancestorNode, targetID) {\n    var firstChildren = findComponentRootReusableArray;\n    var childIndex = 0;\n\n    var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;\n\n    if (process.env.NODE_ENV !== 'production') {\n      // This will throw on the next line; give an early warning\n      process.env.NODE_ENV !== 'production' ? warning(deepestAncestor != null, 'React can\\'t find the root component node for data-reactid value ' + '`%s`. If you\\'re seeing this message, it probably means that ' + 'you\\'ve loaded two copies of React on the page. At this time, only ' + 'a single copy of React can be loaded at a time.', targetID) : undefined;\n    }\n\n    firstChildren[0] = deepestAncestor.firstChild;\n    firstChildren.length = 1;\n\n    while (childIndex < firstChildren.length) {\n      var child = firstChildren[childIndex++];\n      var targetChild;\n\n      while (child) {\n        var childID = ReactMount.getID(child);\n        if (childID) {\n          // Even if we find the node we're looking for, we finish looping\n          // through its siblings to ensure they're cached so that we don't have\n          // to revisit this node again. Otherwise, we make n^2 calls to getID\n          // when visiting the many children of a single node in order.\n\n          if (targetID === childID) {\n            targetChild = child;\n          } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) {\n            // If we find a child whose ID is an ancestor of the given ID,\n            // then we can be sure that we only want to search the subtree\n            // rooted at this child, so we can throw out the rest of the\n            // search state.\n            firstChildren.length = childIndex = 0;\n            firstChildren.push(child.firstChild);\n          }\n        } else {\n          // If this child had no ID, then there's a chance that it was\n          // injected automatically by the browser, as when a `<table>`\n          // element sprouts an extra `<tbody>` child as a side effect of\n          // `.innerHTML` parsing. Optimistically continue down this\n          // branch, but not before examining the other siblings.\n          firstChildren.push(child.firstChild);\n        }\n\n        child = child.nextSibling;\n      }\n\n      if (targetChild) {\n        // Emptying firstChildren/findComponentRootReusableArray is\n        // not necessary for correctness, but it helps the GC reclaim\n        // any nodes that were left at the end of the search.\n        firstChildren.length = 0;\n\n        return targetChild;\n      }\n    }\n\n    firstChildren.length = 0;\n\n    !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findComponentRoot(..., %s): Unable to find element. This probably ' + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + 'usually due to forgetting a <tbody> when using tables, nesting tags ' + 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + 'parent. ' + 'Try inspecting the child nodes of the element with React ID `%s`.', targetID, ReactMount.getID(ancestorNode)) : invariant(false) : undefined;\n  },\n\n  _mountImageIntoNode: function (markup, container, shouldReuseMarkup, transaction) {\n    !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : invariant(false) : undefined;\n\n    if (shouldReuseMarkup) {\n      var rootElement = getReactRootElementInContainer(container);\n      if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {\n        return;\n      } else {\n        var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);\n        rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);\n\n        var rootMarkup = rootElement.outerHTML;\n        rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum);\n\n        var normalizedMarkup = markup;\n        if (process.env.NODE_ENV !== 'production') {\n          // because rootMarkup is retrieved from the DOM, various normalizations\n          // will have occurred which will not be present in `markup`. Here,\n          // insert markup into a <div> or <iframe> depending on the container\n          // type to perform the same normalizations before comparing.\n          var normalizer;\n          if (container.nodeType === ELEMENT_NODE_TYPE) {\n            normalizer = document.createElement('div');\n            normalizer.innerHTML = markup;\n            normalizedMarkup = normalizer.innerHTML;\n          } else {\n            normalizer = document.createElement('iframe');\n            document.body.appendChild(normalizer);\n            normalizer.contentDocument.write(markup);\n            normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML;\n            document.body.removeChild(normalizer);\n          }\n        }\n\n        var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup);\n        var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);\n\n        !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\\'re trying to render a component to the document using ' + 'server rendering but the checksum was invalid. This usually ' + 'means you rendered a different component type or props on ' + 'the client from the one on the server, or your render() ' + 'methods are impure. React cannot handle this case due to ' + 'cross-browser quirks by rendering at the document root. You ' + 'should look for environment dependent code in your components ' + 'and ensure the props are the same client and server side:\\n%s', difference) : invariant(false) : undefined;\n\n        if (process.env.NODE_ENV !== 'production') {\n          process.env.NODE_ENV !== 'production' ? warning(false, 'React attempted to reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected ' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server:\\n%s', difference) : undefined;\n        }\n      }\n    }\n\n    !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\\'re trying to render a component to the document but ' + 'you didn\\'t use server rendering. We can\\'t do this ' + 'without using server rendering due to cross-browser quirks. ' + 'See ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined;\n\n    if (transaction.useCreateElement) {\n      while (container.lastChild) {\n        container.removeChild(container.lastChild);\n      }\n      container.appendChild(markup);\n    } else {\n      setInnerHTML(container, markup);\n    }\n  },\n\n  ownerDocumentContextKey: ownerDocumentContextKey,\n\n  /**\n   * React ID utilities.\n   */\n\n  getReactRootID: getReactRootID,\n\n  getID: getID,\n\n  setID: setID,\n\n  getNode: getNode,\n\n  getNodeFromInstance: getNodeFromInstance,\n\n  isValid: isValid,\n\n  purgeID: purgeID\n};\n\nReactPerf.measureMethods(ReactMount, 'ReactMount', {\n  _renderNewRootComponent: '_renderNewRootComponent',\n  _mountImageIntoNode: '_mountImageIntoNode'\n});\n\nmodule.exports = ReactMount;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactMount.js\n ** module id = 15\n ** module chunks = 0\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/~/node-libs-browser/~/process/browser.js\n ** module id = 16\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule DOMProperty\n * @typechecks static-only\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\nfunction checkMask(value, bitmask) {\n  return (value & bitmask) === bitmask;\n}\n\nvar DOMPropertyInjection = {\n  /**\n   * Mapping from normalized, camelcased property names to a configuration that\n   * specifies how the associated DOM property should be accessed or rendered.\n   */\n  MUST_USE_ATTRIBUTE: 0x1,\n  MUST_USE_PROPERTY: 0x2,\n  HAS_SIDE_EFFECTS: 0x4,\n  HAS_BOOLEAN_VALUE: 0x8,\n  HAS_NUMERIC_VALUE: 0x10,\n  HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10,\n  HAS_OVERLOADED_BOOLEAN_VALUE: 0x40,\n\n  /**\n   * Inject some specialized knowledge about the DOM. This takes a config object\n   * with the following properties:\n   *\n   * isCustomAttribute: function that given an attribute name will return true\n   * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*\n   * attributes where it's impossible to enumerate all of the possible\n   * attribute names,\n   *\n   * Properties: object mapping DOM property name to one of the\n   * DOMPropertyInjection constants or null. If your attribute isn't in here,\n   * it won't get written to the DOM.\n   *\n   * DOMAttributeNames: object mapping React attribute name to the DOM\n   * attribute name. Attribute names not specified use the **lowercase**\n   * normalized name.\n   *\n   * DOMAttributeNamespaces: object mapping React attribute name to the DOM\n   * attribute namespace URL. (Attribute names not specified use no namespace.)\n   *\n   * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.\n   * Property names not specified use the normalized name.\n   *\n   * DOMMutationMethods: Properties that require special mutation methods. If\n   * `value` is undefined, the mutation method should unset the property.\n   *\n   * @param {object} domPropertyConfig the config as described above.\n   */\n  injectDOMPropertyConfig: function (domPropertyConfig) {\n    var Injection = DOMPropertyInjection;\n    var Properties = domPropertyConfig.Properties || {};\n    var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {};\n    var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};\n    var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};\n    var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};\n\n    if (domPropertyConfig.isCustomAttribute) {\n      DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute);\n    }\n\n    for (var propName in Properties) {\n      !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\\'re trying to inject DOM property ' + '\\'%s\\' which has already been injected. You may be accidentally ' + 'injecting the same DOM property config twice, or you may be ' + 'injecting two configs that have conflicting property names.', propName) : invariant(false) : undefined;\n\n      var lowerCased = propName.toLowerCase();\n      var propConfig = Properties[propName];\n\n      var propertyInfo = {\n        attributeName: lowerCased,\n        attributeNamespace: null,\n        propertyName: propName,\n        mutationMethod: null,\n\n        mustUseAttribute: checkMask(propConfig, Injection.MUST_USE_ATTRIBUTE),\n        mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY),\n        hasSideEffects: checkMask(propConfig, Injection.HAS_SIDE_EFFECTS),\n        hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE),\n        hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE),\n        hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE),\n        hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE)\n      };\n\n      !(!propertyInfo.mustUseAttribute || !propertyInfo.mustUseProperty) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Cannot require using both attribute and property: %s', propName) : invariant(false) : undefined;\n      !(propertyInfo.mustUseProperty || !propertyInfo.hasSideEffects) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Properties that have side effects must use property: %s', propName) : invariant(false) : undefined;\n      !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName) : invariant(false) : undefined;\n\n      if (process.env.NODE_ENV !== 'production') {\n        DOMProperty.getPossibleStandardName[lowerCased] = propName;\n      }\n\n      if (DOMAttributeNames.hasOwnProperty(propName)) {\n        var attributeName = DOMAttributeNames[propName];\n        propertyInfo.attributeName = attributeName;\n        if (process.env.NODE_ENV !== 'production') {\n          DOMProperty.getPossibleStandardName[attributeName] = propName;\n        }\n      }\n\n      if (DOMAttributeNamespaces.hasOwnProperty(propName)) {\n        propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName];\n      }\n\n      if (DOMPropertyNames.hasOwnProperty(propName)) {\n        propertyInfo.propertyName = DOMPropertyNames[propName];\n      }\n\n      if (DOMMutationMethods.hasOwnProperty(propName)) {\n        propertyInfo.mutationMethod = DOMMutationMethods[propName];\n      }\n\n      DOMProperty.properties[propName] = propertyInfo;\n    }\n  }\n};\nvar defaultValueCache = {};\n\n/**\n * DOMProperty exports lookup objects that can be used like functions:\n *\n *   > DOMProperty.isValid['id']\n *   true\n *   > DOMProperty.isValid['foobar']\n *   undefined\n *\n * Although this may be confusing, it performs better in general.\n *\n * @see http://jsperf.com/key-exists\n * @see http://jsperf.com/key-missing\n */\nvar DOMProperty = {\n\n  ID_ATTRIBUTE_NAME: 'data-reactid',\n\n  /**\n   * Map from property \"standard name\" to an object with info about how to set\n   * the property in the DOM. Each object contains:\n   *\n   * attributeName:\n   *   Used when rendering markup or with `*Attribute()`.\n   * attributeNamespace\n   * propertyName:\n   *   Used on DOM node instances. (This includes properties that mutate due to\n   *   external factors.)\n   * mutationMethod:\n   *   If non-null, used instead of the property or `setAttribute()` after\n   *   initial render.\n   * mustUseAttribute:\n   *   Whether the property must be accessed and mutated using `*Attribute()`.\n   *   (This includes anything that fails `<propName> in <element>`.)\n   * mustUseProperty:\n   *   Whether the property must be accessed and mutated as an object property.\n   * hasSideEffects:\n   *   Whether or not setting a value causes side effects such as triggering\n   *   resources to be loaded or text selection changes. If true, we read from\n   *   the DOM before updating to ensure that the value is only set if it has\n   *   changed.\n   * hasBooleanValue:\n   *   Whether the property should be removed when set to a falsey value.\n   * hasNumericValue:\n   *   Whether the property must be numeric or parse as a numeric and should be\n   *   removed when set to a falsey value.\n   * hasPositiveNumericValue:\n   *   Whether the property must be positive numeric or parse as a positive\n   *   numeric and should be removed when set to a falsey value.\n   * hasOverloadedBooleanValue:\n   *   Whether the property can be used as a flag as well as with a value.\n   *   Removed when strictly equal to false; present without a value when\n   *   strictly equal to true; present with a value otherwise.\n   */\n  properties: {},\n\n  /**\n   * Mapping from lowercase property names to the properly cased version, used\n   * to warn in the case of missing properties. Available only in __DEV__.\n   * @type {Object}\n   */\n  getPossibleStandardName: process.env.NODE_ENV !== 'production' ? {} : null,\n\n  /**\n   * All of the isCustomAttribute() functions that have been injected.\n   */\n  _isCustomAttributeFunctions: [],\n\n  /**\n   * Checks whether a property name is a custom attribute.\n   * @method\n   */\n  isCustomAttribute: function (attributeName) {\n    for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {\n      var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];\n      if (isCustomAttributeFn(attributeName)) {\n        return true;\n      }\n    }\n    return false;\n  },\n\n  /**\n   * Returns the default property value for a DOM property (i.e., not an\n   * attribute). Most default values are '' or false, but not all. Worse yet,\n   * some (in particular, `type`) vary depending on the type of element.\n   *\n   * TODO: Is it better to grab all the possible properties when creating an\n   * element to avoid having to create the same element twice?\n   */\n  getDefaultValueForProperty: function (nodeName, prop) {\n    var nodeDefaults = defaultValueCache[nodeName];\n    var testElement;\n    if (!nodeDefaults) {\n      defaultValueCache[nodeName] = nodeDefaults = {};\n    }\n    if (!(prop in nodeDefaults)) {\n      testElement = document.createElement(nodeName);\n      nodeDefaults[prop] = testElement[prop];\n    }\n    return nodeDefaults[prop];\n  },\n\n  injection: DOMPropertyInjection\n};\n\nmodule.exports = DOMProperty;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/DOMProperty.js\n ** module id = 17\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule invariant\n */\n\n'use strict';\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar invariant = function (condition, format, a, b, c, d, e, f) {\n  if (process.env.NODE_ENV !== 'production') {\n    if (format === undefined) {\n      throw new Error('invariant requires an error message argument');\n    }\n  }\n\n  if (!condition) {\n    var error;\n    if (format === undefined) {\n      error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n    } else {\n      var args = [a, b, c, d, e, f];\n      var argIndex = 0;\n      error = new Error('Invariant Violation: ' + format.replace(/%s/g, function () {\n        return args[argIndex++];\n      }));\n    }\n\n    error.framesToPop = 1; // we don't care about invariant's own frame\n    throw error;\n  }\n};\n\nmodule.exports = invariant;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/invariant.js\n ** module id = 18\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactBrowserEventEmitter\n * @typechecks static-only\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventPluginHub = require('./EventPluginHub');\nvar EventPluginRegistry = require('./EventPluginRegistry');\nvar ReactEventEmitterMixin = require('./ReactEventEmitterMixin');\nvar ReactPerf = require('./ReactPerf');\nvar ViewportMetrics = require('./ViewportMetrics');\n\nvar assign = require('./Object.assign');\nvar isEventSupported = require('./isEventSupported');\n\n/**\n * Summary of `ReactBrowserEventEmitter` event handling:\n *\n *  - Top-level delegation is used to trap most native browser events. This\n *    may only occur in the main thread and is the responsibility of\n *    ReactEventListener, which is injected and can therefore support pluggable\n *    event sources. This is the only work that occurs in the main thread.\n *\n *  - We normalize and de-duplicate events to account for browser quirks. This\n *    may be done in the worker thread.\n *\n *  - Forward these native events (with the associated top-level type used to\n *    trap it) to `EventPluginHub`, which in turn will ask plugins if they want\n *    to extract any synthetic events.\n *\n *  - The `EventPluginHub` will then process each event by annotating them with\n *    \"dispatches\", a sequence of listeners and IDs that care about that event.\n *\n *  - The `EventPluginHub` then dispatches the events.\n *\n * Overview of React and the event system:\n *\n * +------------+    .\n * |    DOM     |    .\n * +------------+    .\n *       |           .\n *       v           .\n * +------------+    .\n * | ReactEvent |    .\n * |  Listener  |    .\n * +------------+    .                         +-----------+\n *       |           .               +--------+|SimpleEvent|\n *       |           .               |         |Plugin     |\n * +-----|------+    .               v         +-----------+\n * |     |      |    .    +--------------+                    +------------+\n * |     +-----------.--->|EventPluginHub|                    |    Event   |\n * |            |    .    |              |     +-----------+  | Propagators|\n * | ReactEvent |    .    |              |     |TapEvent   |  |------------|\n * |  Emitter   |    .    |              |<---+|Plugin     |  |other plugin|\n * |            |    .    |              |     +-----------+  |  utilities |\n * |     +-----------.--->|              |                    +------------+\n * |     |      |    .    +--------------+\n * +-----|------+    .                ^        +-----------+\n *       |           .                |        |Enter/Leave|\n *       +           .                +-------+|Plugin     |\n * +-------------+   .                         +-----------+\n * | application |   .\n * |-------------|   .\n * |             |   .\n * |             |   .\n * +-------------+   .\n *                   .\n *    React Core     .  General Purpose Event Plugin System\n */\n\nvar alreadyListeningTo = {};\nvar isMonitoringScrollValue = false;\nvar reactTopListenersCounter = 0;\n\n// For events like 'submit' which don't consistently bubble (which we trap at a\n// lower node than `document`), binding at `document` would cause duplicate\n// events so we don't include them here\nvar topEventMapping = {\n  topAbort: 'abort',\n  topBlur: 'blur',\n  topCanPlay: 'canplay',\n  topCanPlayThrough: 'canplaythrough',\n  topChange: 'change',\n  topClick: 'click',\n  topCompositionEnd: 'compositionend',\n  topCompositionStart: 'compositionstart',\n  topCompositionUpdate: 'compositionupdate',\n  topContextMenu: 'contextmenu',\n  topCopy: 'copy',\n  topCut: 'cut',\n  topDoubleClick: 'dblclick',\n  topDrag: 'drag',\n  topDragEnd: 'dragend',\n  topDragEnter: 'dragenter',\n  topDragExit: 'dragexit',\n  topDragLeave: 'dragleave',\n  topDragOver: 'dragover',\n  topDragStart: 'dragstart',\n  topDrop: 'drop',\n  topDurationChange: 'durationchange',\n  topEmptied: 'emptied',\n  topEncrypted: 'encrypted',\n  topEnded: 'ended',\n  topError: 'error',\n  topFocus: 'focus',\n  topInput: 'input',\n  topKeyDown: 'keydown',\n  topKeyPress: 'keypress',\n  topKeyUp: 'keyup',\n  topLoadedData: 'loadeddata',\n  topLoadedMetadata: 'loadedmetadata',\n  topLoadStart: 'loadstart',\n  topMouseDown: 'mousedown',\n  topMouseMove: 'mousemove',\n  topMouseOut: 'mouseout',\n  topMouseOver: 'mouseover',\n  topMouseUp: 'mouseup',\n  topPaste: 'paste',\n  topPause: 'pause',\n  topPlay: 'play',\n  topPlaying: 'playing',\n  topProgress: 'progress',\n  topRateChange: 'ratechange',\n  topScroll: 'scroll',\n  topSeeked: 'seeked',\n  topSeeking: 'seeking',\n  topSelectionChange: 'selectionchange',\n  topStalled: 'stalled',\n  topSuspend: 'suspend',\n  topTextInput: 'textInput',\n  topTimeUpdate: 'timeupdate',\n  topTouchCancel: 'touchcancel',\n  topTouchEnd: 'touchend',\n  topTouchMove: 'touchmove',\n  topTouchStart: 'touchstart',\n  topVolumeChange: 'volumechange',\n  topWaiting: 'waiting',\n  topWheel: 'wheel'\n};\n\n/**\n * To ensure no conflicts with other potential React instances on the page\n */\nvar topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2);\n\nfunction getListeningForDocument(mountAt) {\n  // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`\n  // directly.\n  if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {\n    mountAt[topListenersIDKey] = reactTopListenersCounter++;\n    alreadyListeningTo[mountAt[topListenersIDKey]] = {};\n  }\n  return alreadyListeningTo[mountAt[topListenersIDKey]];\n}\n\n/**\n * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For\n * example:\n *\n *   ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction);\n *\n * This would allocate a \"registration\" of `('onClick', myFunction)` on 'myID'.\n *\n * @internal\n */\nvar ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, {\n\n  /**\n   * Injectable event backend\n   */\n  ReactEventListener: null,\n\n  injection: {\n    /**\n     * @param {object} ReactEventListener\n     */\n    injectReactEventListener: function (ReactEventListener) {\n      ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel);\n      ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;\n    }\n  },\n\n  /**\n   * Sets whether or not any created callbacks should be enabled.\n   *\n   * @param {boolean} enabled True if callbacks should be enabled.\n   */\n  setEnabled: function (enabled) {\n    if (ReactBrowserEventEmitter.ReactEventListener) {\n      ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);\n    }\n  },\n\n  /**\n   * @return {boolean} True if callbacks are enabled.\n   */\n  isEnabled: function () {\n    return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled());\n  },\n\n  /**\n   * We listen for bubbled touch events on the document object.\n   *\n   * Firefox v8.01 (and possibly others) exhibited strange behavior when\n   * mounting `onmousemove` events at some node that was not the document\n   * element. The symptoms were that if your mouse is not moving over something\n   * contained within that mount point (for example on the background) the\n   * top-level listeners for `onmousemove` won't be called. However, if you\n   * register the `mousemove` on the document object, then it will of course\n   * catch all `mousemove`s. This along with iOS quirks, justifies restricting\n   * top-level listeners to the document object only, at least for these\n   * movement types of events and possibly all events.\n   *\n   * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n   *\n   * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but\n   * they bubble to document.\n   *\n   * @param {string} registrationName Name of listener (e.g. `onClick`).\n   * @param {object} contentDocumentHandle Document which owns the container\n   */\n  listenTo: function (registrationName, contentDocumentHandle) {\n    var mountAt = contentDocumentHandle;\n    var isListening = getListeningForDocument(mountAt);\n    var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName];\n\n    var topLevelTypes = EventConstants.topLevelTypes;\n    for (var i = 0; i < dependencies.length; i++) {\n      var dependency = dependencies[i];\n      if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {\n        if (dependency === topLevelTypes.topWheel) {\n          if (isEventSupported('wheel')) {\n            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);\n          } else if (isEventSupported('mousewheel')) {\n            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);\n          } else {\n            // Firefox needs to capture a different mouse scroll event.\n            // @see http://www.quirksmode.org/dom/events/tests/scroll.html\n            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt);\n          }\n        } else if (dependency === topLevelTypes.topScroll) {\n\n          if (isEventSupported('scroll', true)) {\n            ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);\n          } else {\n            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topScroll, 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE);\n          }\n        } else if (dependency === topLevelTypes.topFocus || dependency === topLevelTypes.topBlur) {\n\n          if (isEventSupported('focus', true)) {\n            ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);\n            ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);\n          } else if (isEventSupported('focusin')) {\n            // IE has `focusin` and `focusout` events which bubble.\n            // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html\n            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);\n            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);\n          }\n\n          // to make sure blur and focus event listeners are only attached once\n          isListening[topLevelTypes.topBlur] = true;\n          isListening[topLevelTypes.topFocus] = true;\n        } else if (topEventMapping.hasOwnProperty(dependency)) {\n          ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt);\n        }\n\n        isListening[dependency] = true;\n      }\n    }\n  },\n\n  trapBubbledEvent: function (topLevelType, handlerBaseName, handle) {\n    return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle);\n  },\n\n  trapCapturedEvent: function (topLevelType, handlerBaseName, handle) {\n    return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle);\n  },\n\n  /**\n   * Listens to window scroll and resize events. We cache scroll values so that\n   * application code can access them without triggering reflows.\n   *\n   * NOTE: Scroll events do not bubble.\n   *\n   * @see http://www.quirksmode.org/dom/events/scroll.html\n   */\n  ensureScrollValueMonitoring: function () {\n    if (!isMonitoringScrollValue) {\n      var refresh = ViewportMetrics.refreshScrollValues;\n      ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);\n      isMonitoringScrollValue = true;\n    }\n  },\n\n  eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs,\n\n  registrationNameModules: EventPluginHub.registrationNameModules,\n\n  putListener: EventPluginHub.putListener,\n\n  getListener: EventPluginHub.getListener,\n\n  deleteListener: EventPluginHub.deleteListener,\n\n  deleteAllListeners: EventPluginHub.deleteAllListeners\n\n});\n\nReactPerf.measureMethods(ReactBrowserEventEmitter, 'ReactBrowserEventEmitter', {\n  putListener: 'putListener',\n  deleteListener: 'deleteListener'\n});\n\nmodule.exports = ReactBrowserEventEmitter;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactBrowserEventEmitter.js\n ** module id = 19\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule EventConstants\n */\n\n'use strict';\n\nvar keyMirror = require('fbjs/lib/keyMirror');\n\nvar PropagationPhases = keyMirror({ bubbled: null, captured: null });\n\n/**\n * Types of raw signals from the browser caught at the top level.\n */\nvar topLevelTypes = keyMirror({\n  topAbort: null,\n  topBlur: null,\n  topCanPlay: null,\n  topCanPlayThrough: null,\n  topChange: null,\n  topClick: null,\n  topCompositionEnd: null,\n  topCompositionStart: null,\n  topCompositionUpdate: null,\n  topContextMenu: null,\n  topCopy: null,\n  topCut: null,\n  topDoubleClick: null,\n  topDrag: null,\n  topDragEnd: null,\n  topDragEnter: null,\n  topDragExit: null,\n  topDragLeave: null,\n  topDragOver: null,\n  topDragStart: null,\n  topDrop: null,\n  topDurationChange: null,\n  topEmptied: null,\n  topEncrypted: null,\n  topEnded: null,\n  topError: null,\n  topFocus: null,\n  topInput: null,\n  topKeyDown: null,\n  topKeyPress: null,\n  topKeyUp: null,\n  topLoad: null,\n  topLoadedData: null,\n  topLoadedMetadata: null,\n  topLoadStart: null,\n  topMouseDown: null,\n  topMouseMove: null,\n  topMouseOut: null,\n  topMouseOver: null,\n  topMouseUp: null,\n  topPaste: null,\n  topPause: null,\n  topPlay: null,\n  topPlaying: null,\n  topProgress: null,\n  topRateChange: null,\n  topReset: null,\n  topScroll: null,\n  topSeeked: null,\n  topSeeking: null,\n  topSelectionChange: null,\n  topStalled: null,\n  topSubmit: null,\n  topSuspend: null,\n  topTextInput: null,\n  topTimeUpdate: null,\n  topTouchCancel: null,\n  topTouchEnd: null,\n  topTouchMove: null,\n  topTouchStart: null,\n  topVolumeChange: null,\n  topWaiting: null,\n  topWheel: null\n});\n\nvar EventConstants = {\n  topLevelTypes: topLevelTypes,\n  PropagationPhases: PropagationPhases\n};\n\nmodule.exports = EventConstants;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/EventConstants.js\n ** module id = 20\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule keyMirror\n * @typechecks static-only\n */\n\n'use strict';\n\nvar invariant = require('./invariant');\n\n/**\n * Constructs an enumeration with keys equal to their value.\n *\n * For example:\n *\n *   var COLORS = keyMirror({blue: null, red: null});\n *   var myColor = COLORS.blue;\n *   var isColorValid = !!COLORS[myColor];\n *\n * The last line could not be performed if the values of the generated enum were\n * not equal to their keys.\n *\n *   Input:  {key1: val1, key2: val2}\n *   Output: {key1: key1, key2: key2}\n *\n * @param {object} obj\n * @return {object}\n */\nvar keyMirror = function (obj) {\n  var ret = {};\n  var key;\n  !(obj instanceof Object && !Array.isArray(obj)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'keyMirror(...): Argument must be an object.') : invariant(false) : undefined;\n  for (key in obj) {\n    if (!obj.hasOwnProperty(key)) {\n      continue;\n    }\n    ret[key] = key;\n  }\n  return ret;\n};\n\nmodule.exports = keyMirror;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/keyMirror.js\n ** module id = 21\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule EventPluginHub\n */\n\n'use strict';\n\nvar EventPluginRegistry = require('./EventPluginRegistry');\nvar EventPluginUtils = require('./EventPluginUtils');\nvar ReactErrorUtils = require('./ReactErrorUtils');\n\nvar accumulateInto = require('./accumulateInto');\nvar forEachAccumulated = require('./forEachAccumulated');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * Internal store for event listeners\n */\nvar listenerBank = {};\n\n/**\n * Internal queue of events that have accumulated their dispatches and are\n * waiting to have their dispatches executed.\n */\nvar eventQueue = null;\n\n/**\n * Dispatches an event and releases it back into the pool, unless persistent.\n *\n * @param {?object} event Synthetic event to be dispatched.\n * @param {boolean} simulated If the event is simulated (changes exn behavior)\n * @private\n */\nvar executeDispatchesAndRelease = function (event, simulated) {\n  if (event) {\n    EventPluginUtils.executeDispatchesInOrder(event, simulated);\n\n    if (!event.isPersistent()) {\n      event.constructor.release(event);\n    }\n  }\n};\nvar executeDispatchesAndReleaseSimulated = function (e) {\n  return executeDispatchesAndRelease(e, true);\n};\nvar executeDispatchesAndReleaseTopLevel = function (e) {\n  return executeDispatchesAndRelease(e, false);\n};\n\n/**\n * - `InstanceHandle`: [required] Module that performs logical traversals of DOM\n *   hierarchy given ids of the logical DOM elements involved.\n */\nvar InstanceHandle = null;\n\nfunction validateInstanceHandle() {\n  var valid = InstanceHandle && InstanceHandle.traverseTwoPhase && InstanceHandle.traverseEnterLeave;\n  process.env.NODE_ENV !== 'production' ? warning(valid, 'InstanceHandle not injected before use!') : undefined;\n}\n\n/**\n * This is a unified interface for event plugins to be installed and configured.\n *\n * Event plugins can implement the following properties:\n *\n *   `extractEvents` {function(string, DOMEventTarget, string, object): *}\n *     Required. When a top-level event is fired, this method is expected to\n *     extract synthetic events that will in turn be queued and dispatched.\n *\n *   `eventTypes` {object}\n *     Optional, plugins that fire events must publish a mapping of registration\n *     names that are used to register listeners. Values of this mapping must\n *     be objects that contain `registrationName` or `phasedRegistrationNames`.\n *\n *   `executeDispatch` {function(object, function, string)}\n *     Optional, allows plugins to override how an event gets dispatched. By\n *     default, the listener is simply invoked.\n *\n * Each plugin that is injected into `EventsPluginHub` is immediately operable.\n *\n * @public\n */\nvar EventPluginHub = {\n\n  /**\n   * Methods for injecting dependencies.\n   */\n  injection: {\n\n    /**\n     * @param {object} InjectedMount\n     * @public\n     */\n    injectMount: EventPluginUtils.injection.injectMount,\n\n    /**\n     * @param {object} InjectedInstanceHandle\n     * @public\n     */\n    injectInstanceHandle: function (InjectedInstanceHandle) {\n      InstanceHandle = InjectedInstanceHandle;\n      if (process.env.NODE_ENV !== 'production') {\n        validateInstanceHandle();\n      }\n    },\n\n    getInstanceHandle: function () {\n      if (process.env.NODE_ENV !== 'production') {\n        validateInstanceHandle();\n      }\n      return InstanceHandle;\n    },\n\n    /**\n     * @param {array} InjectedEventPluginOrder\n     * @public\n     */\n    injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,\n\n    /**\n     * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n     */\n    injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName\n\n  },\n\n  eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs,\n\n  registrationNameModules: EventPluginRegistry.registrationNameModules,\n\n  /**\n   * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent.\n   *\n   * @param {string} id ID of the DOM element.\n   * @param {string} registrationName Name of listener (e.g. `onClick`).\n   * @param {?function} listener The callback to store.\n   */\n  putListener: function (id, registrationName, listener) {\n    !(typeof listener === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : invariant(false) : undefined;\n\n    var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});\n    bankForRegistrationName[id] = listener;\n\n    var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];\n    if (PluginModule && PluginModule.didPutListener) {\n      PluginModule.didPutListener(id, registrationName, listener);\n    }\n  },\n\n  /**\n   * @param {string} id ID of the DOM element.\n   * @param {string} registrationName Name of listener (e.g. `onClick`).\n   * @return {?function} The stored callback.\n   */\n  getListener: function (id, registrationName) {\n    var bankForRegistrationName = listenerBank[registrationName];\n    return bankForRegistrationName && bankForRegistrationName[id];\n  },\n\n  /**\n   * Deletes a listener from the registration bank.\n   *\n   * @param {string} id ID of the DOM element.\n   * @param {string} registrationName Name of listener (e.g. `onClick`).\n   */\n  deleteListener: function (id, registrationName) {\n    var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];\n    if (PluginModule && PluginModule.willDeleteListener) {\n      PluginModule.willDeleteListener(id, registrationName);\n    }\n\n    var bankForRegistrationName = listenerBank[registrationName];\n    // TODO: This should never be null -- when is it?\n    if (bankForRegistrationName) {\n      delete bankForRegistrationName[id];\n    }\n  },\n\n  /**\n   * Deletes all listeners for the DOM element with the supplied ID.\n   *\n   * @param {string} id ID of the DOM element.\n   */\n  deleteAllListeners: function (id) {\n    for (var registrationName in listenerBank) {\n      if (!listenerBank[registrationName][id]) {\n        continue;\n      }\n\n      var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];\n      if (PluginModule && PluginModule.willDeleteListener) {\n        PluginModule.willDeleteListener(id, registrationName);\n      }\n\n      delete listenerBank[registrationName][id];\n    }\n  },\n\n  /**\n   * Allows registered plugins an opportunity to extract events from top-level\n   * native browser events.\n   *\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {DOMEventTarget} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native browser event.\n   * @return {*} An accumulation of synthetic events.\n   * @internal\n   */\n  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n    var events;\n    var plugins = EventPluginRegistry.plugins;\n    for (var i = 0; i < plugins.length; i++) {\n      // Not every plugin in the ordering may be loaded at runtime.\n      var possiblePlugin = plugins[i];\n      if (possiblePlugin) {\n        var extractedEvents = possiblePlugin.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget);\n        if (extractedEvents) {\n          events = accumulateInto(events, extractedEvents);\n        }\n      }\n    }\n    return events;\n  },\n\n  /**\n   * Enqueues a synthetic event that should be dispatched when\n   * `processEventQueue` is invoked.\n   *\n   * @param {*} events An accumulation of synthetic events.\n   * @internal\n   */\n  enqueueEvents: function (events) {\n    if (events) {\n      eventQueue = accumulateInto(eventQueue, events);\n    }\n  },\n\n  /**\n   * Dispatches all synthetic events on the event queue.\n   *\n   * @internal\n   */\n  processEventQueue: function (simulated) {\n    // Set `eventQueue` to null before processing it so that we can tell if more\n    // events get enqueued while processing.\n    var processingEventQueue = eventQueue;\n    eventQueue = null;\n    if (simulated) {\n      forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);\n    } else {\n      forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);\n    }\n    !!eventQueue ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing ' + 'an event queue. Support for this has not yet been implemented.') : invariant(false) : undefined;\n    // This would be a good time to rethrow if any of the event handlers threw.\n    ReactErrorUtils.rethrowCaughtError();\n  },\n\n  /**\n   * These are needed for tests only. Do not use!\n   */\n  __purge: function () {\n    listenerBank = {};\n  },\n\n  __getListenerBank: function () {\n    return listenerBank;\n  }\n\n};\n\nmodule.exports = EventPluginHub;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/EventPluginHub.js\n ** module id = 22\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule EventPluginRegistry\n * @typechecks static-only\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Injectable ordering of event plugins.\n */\nvar EventPluginOrder = null;\n\n/**\n * Injectable mapping from names to event plugin modules.\n */\nvar namesToPlugins = {};\n\n/**\n * Recomputes the plugin list using the injected plugins and plugin ordering.\n *\n * @private\n */\nfunction recomputePluginOrdering() {\n  if (!EventPluginOrder) {\n    // Wait until an `EventPluginOrder` is injected.\n    return;\n  }\n  for (var pluginName in namesToPlugins) {\n    var PluginModule = namesToPlugins[pluginName];\n    var pluginIndex = EventPluginOrder.indexOf(pluginName);\n    !(pluginIndex > -1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 'the plugin ordering, `%s`.', pluginName) : invariant(false) : undefined;\n    if (EventPluginRegistry.plugins[pluginIndex]) {\n      continue;\n    }\n    !PluginModule.extractEvents ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 'method, but `%s` does not.', pluginName) : invariant(false) : undefined;\n    EventPluginRegistry.plugins[pluginIndex] = PluginModule;\n    var publishedEvents = PluginModule.eventTypes;\n    for (var eventName in publishedEvents) {\n      !publishEventForPlugin(publishedEvents[eventName], PluginModule, eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : invariant(false) : undefined;\n    }\n  }\n}\n\n/**\n * Publishes an event so that it can be dispatched by the supplied plugin.\n *\n * @param {object} dispatchConfig Dispatch configuration for the event.\n * @param {object} PluginModule Plugin publishing the event.\n * @return {boolean} True if the event was successfully published.\n * @private\n */\nfunction publishEventForPlugin(dispatchConfig, PluginModule, eventName) {\n  !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'event name, `%s`.', eventName) : invariant(false) : undefined;\n  EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;\n\n  var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;\n  if (phasedRegistrationNames) {\n    for (var phaseName in phasedRegistrationNames) {\n      if (phasedRegistrationNames.hasOwnProperty(phaseName)) {\n        var phasedRegistrationName = phasedRegistrationNames[phaseName];\n        publishRegistrationName(phasedRegistrationName, PluginModule, eventName);\n      }\n    }\n    return true;\n  } else if (dispatchConfig.registrationName) {\n    publishRegistrationName(dispatchConfig.registrationName, PluginModule, eventName);\n    return true;\n  }\n  return false;\n}\n\n/**\n * Publishes a registration name that is used to identify dispatched events and\n * can be used with `EventPluginHub.putListener` to register listeners.\n *\n * @param {string} registrationName Registration name to add.\n * @param {object} PluginModule Plugin publishing the event.\n * @private\n */\nfunction publishRegistrationName(registrationName, PluginModule, eventName) {\n  !!EventPluginRegistry.registrationNameModules[registrationName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName) : invariant(false) : undefined;\n  EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;\n  EventPluginRegistry.registrationNameDependencies[registrationName] = PluginModule.eventTypes[eventName].dependencies;\n}\n\n/**\n * Registers plugins so that they can extract and dispatch events.\n *\n * @see {EventPluginHub}\n */\nvar EventPluginRegistry = {\n\n  /**\n   * Ordered list of injected plugins.\n   */\n  plugins: [],\n\n  /**\n   * Mapping from event name to dispatch config\n   */\n  eventNameDispatchConfigs: {},\n\n  /**\n   * Mapping from registration name to plugin module\n   */\n  registrationNameModules: {},\n\n  /**\n   * Mapping from registration name to event name\n   */\n  registrationNameDependencies: {},\n\n  /**\n   * Injects an ordering of plugins (by plugin name). This allows the ordering\n   * to be decoupled from injection of the actual plugins so that ordering is\n   * always deterministic regardless of packaging, on-the-fly injection, etc.\n   *\n   * @param {array} InjectedEventPluginOrder\n   * @internal\n   * @see {EventPluginHub.injection.injectEventPluginOrder}\n   */\n  injectEventPluginOrder: function (InjectedEventPluginOrder) {\n    !!EventPluginOrder ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + 'once. You are likely trying to load more than one copy of React.') : invariant(false) : undefined;\n    // Clone the ordering so it cannot be dynamically mutated.\n    EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);\n    recomputePluginOrdering();\n  },\n\n  /**\n   * Injects plugins to be used by `EventPluginHub`. The plugin names must be\n   * in the ordering injected by `injectEventPluginOrder`.\n   *\n   * Plugins can be injected as part of page initialization or on-the-fly.\n   *\n   * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n   * @internal\n   * @see {EventPluginHub.injection.injectEventPluginsByName}\n   */\n  injectEventPluginsByName: function (injectedNamesToPlugins) {\n    var isOrderingDirty = false;\n    for (var pluginName in injectedNamesToPlugins) {\n      if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {\n        continue;\n      }\n      var PluginModule = injectedNamesToPlugins[pluginName];\n      if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== PluginModule) {\n        !!namesToPlugins[pluginName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins ' + 'using the same name, `%s`.', pluginName) : invariant(false) : undefined;\n        namesToPlugins[pluginName] = PluginModule;\n        isOrderingDirty = true;\n      }\n    }\n    if (isOrderingDirty) {\n      recomputePluginOrdering();\n    }\n  },\n\n  /**\n   * Looks up the plugin for the supplied event.\n   *\n   * @param {object} event A synthetic event.\n   * @return {?object} The plugin that created the supplied event.\n   * @internal\n   */\n  getPluginModuleForEvent: function (event) {\n    var dispatchConfig = event.dispatchConfig;\n    if (dispatchConfig.registrationName) {\n      return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName] || null;\n    }\n    for (var phase in dispatchConfig.phasedRegistrationNames) {\n      if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {\n        continue;\n      }\n      var PluginModule = EventPluginRegistry.registrationNameModules[dispatchConfig.phasedRegistrationNames[phase]];\n      if (PluginModule) {\n        return PluginModule;\n      }\n    }\n    return null;\n  },\n\n  /**\n   * Exposed for unit testing.\n   * @private\n   */\n  _resetEventPlugins: function () {\n    EventPluginOrder = null;\n    for (var pluginName in namesToPlugins) {\n      if (namesToPlugins.hasOwnProperty(pluginName)) {\n        delete namesToPlugins[pluginName];\n      }\n    }\n    EventPluginRegistry.plugins.length = 0;\n\n    var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;\n    for (var eventName in eventNameDispatchConfigs) {\n      if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {\n        delete eventNameDispatchConfigs[eventName];\n      }\n    }\n\n    var registrationNameModules = EventPluginRegistry.registrationNameModules;\n    for (var registrationName in registrationNameModules) {\n      if (registrationNameModules.hasOwnProperty(registrationName)) {\n        delete registrationNameModules[registrationName];\n      }\n    }\n  }\n\n};\n\nmodule.exports = EventPluginRegistry;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/EventPluginRegistry.js\n ** module id = 23\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule EventPluginUtils\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar ReactErrorUtils = require('./ReactErrorUtils');\n\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * Injected dependencies:\n */\n\n/**\n * - `Mount`: [required] Module that can convert between React dom IDs and\n *   actual node references.\n */\nvar injection = {\n  Mount: null,\n  injectMount: function (InjectedMount) {\n    injection.Mount = InjectedMount;\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(InjectedMount && InjectedMount.getNode && InjectedMount.getID, 'EventPluginUtils.injection.injectMount(...): Injected Mount ' + 'module is missing getNode or getID.') : undefined;\n    }\n  }\n};\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\nfunction isEndish(topLevelType) {\n  return topLevelType === topLevelTypes.topMouseUp || topLevelType === topLevelTypes.topTouchEnd || topLevelType === topLevelTypes.topTouchCancel;\n}\n\nfunction isMoveish(topLevelType) {\n  return topLevelType === topLevelTypes.topMouseMove || topLevelType === topLevelTypes.topTouchMove;\n}\nfunction isStartish(topLevelType) {\n  return topLevelType === topLevelTypes.topMouseDown || topLevelType === topLevelTypes.topTouchStart;\n}\n\nvar validateEventDispatches;\nif (process.env.NODE_ENV !== 'production') {\n  validateEventDispatches = function (event) {\n    var dispatchListeners = event._dispatchListeners;\n    var dispatchIDs = event._dispatchIDs;\n\n    var listenersIsArr = Array.isArray(dispatchListeners);\n    var idsIsArr = Array.isArray(dispatchIDs);\n    var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;\n    var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;\n\n    process.env.NODE_ENV !== 'production' ? warning(idsIsArr === listenersIsArr && IDsLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : undefined;\n  };\n}\n\n/**\n * Dispatch the event to the listener.\n * @param {SyntheticEvent} event SyntheticEvent to handle\n * @param {boolean} simulated If the event is simulated (changes exn behavior)\n * @param {function} listener Application-level callback\n * @param {string} domID DOM id to pass to the callback.\n */\nfunction executeDispatch(event, simulated, listener, domID) {\n  var type = event.type || 'unknown-event';\n  event.currentTarget = injection.Mount.getNode(domID);\n  if (simulated) {\n    ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event, domID);\n  } else {\n    ReactErrorUtils.invokeGuardedCallback(type, listener, event, domID);\n  }\n  event.currentTarget = null;\n}\n\n/**\n * Standard/simple iteration through an event's collected dispatches.\n */\nfunction executeDispatchesInOrder(event, simulated) {\n  var dispatchListeners = event._dispatchListeners;\n  var dispatchIDs = event._dispatchIDs;\n  if (process.env.NODE_ENV !== 'production') {\n    validateEventDispatches(event);\n  }\n  if (Array.isArray(dispatchListeners)) {\n    for (var i = 0; i < dispatchListeners.length; i++) {\n      if (event.isPropagationStopped()) {\n        break;\n      }\n      // Listeners and IDs are two parallel arrays that are always in sync.\n      executeDispatch(event, simulated, dispatchListeners[i], dispatchIDs[i]);\n    }\n  } else if (dispatchListeners) {\n    executeDispatch(event, simulated, dispatchListeners, dispatchIDs);\n  }\n  event._dispatchListeners = null;\n  event._dispatchIDs = null;\n}\n\n/**\n * Standard/simple iteration through an event's collected dispatches, but stops\n * at the first dispatch execution returning true, and returns that id.\n *\n * @return {?string} id of the first dispatch execution who's listener returns\n * true, or null if no listener returned true.\n */\nfunction executeDispatchesInOrderStopAtTrueImpl(event) {\n  var dispatchListeners = event._dispatchListeners;\n  var dispatchIDs = event._dispatchIDs;\n  if (process.env.NODE_ENV !== 'production') {\n    validateEventDispatches(event);\n  }\n  if (Array.isArray(dispatchListeners)) {\n    for (var i = 0; i < dispatchListeners.length; i++) {\n      if (event.isPropagationStopped()) {\n        break;\n      }\n      // Listeners and IDs are two parallel arrays that are always in sync.\n      if (dispatchListeners[i](event, dispatchIDs[i])) {\n        return dispatchIDs[i];\n      }\n    }\n  } else if (dispatchListeners) {\n    if (dispatchListeners(event, dispatchIDs)) {\n      return dispatchIDs;\n    }\n  }\n  return null;\n}\n\n/**\n * @see executeDispatchesInOrderStopAtTrueImpl\n */\nfunction executeDispatchesInOrderStopAtTrue(event) {\n  var ret = executeDispatchesInOrderStopAtTrueImpl(event);\n  event._dispatchIDs = null;\n  event._dispatchListeners = null;\n  return ret;\n}\n\n/**\n * Execution of a \"direct\" dispatch - there must be at most one dispatch\n * accumulated on the event or it is considered an error. It doesn't really make\n * sense for an event with multiple dispatches (bubbled) to keep track of the\n * return values at each dispatch execution, but it does tend to make sense when\n * dealing with \"direct\" dispatches.\n *\n * @return {*} The return value of executing the single dispatch.\n */\nfunction executeDirectDispatch(event) {\n  if (process.env.NODE_ENV !== 'production') {\n    validateEventDispatches(event);\n  }\n  var dispatchListener = event._dispatchListeners;\n  var dispatchID = event._dispatchIDs;\n  !!Array.isArray(dispatchListener) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : invariant(false) : undefined;\n  var res = dispatchListener ? dispatchListener(event, dispatchID) : null;\n  event._dispatchListeners = null;\n  event._dispatchIDs = null;\n  return res;\n}\n\n/**\n * @param {SyntheticEvent} event\n * @return {boolean} True iff number of dispatches accumulated is greater than 0.\n */\nfunction hasDispatches(event) {\n  return !!event._dispatchListeners;\n}\n\n/**\n * General utilities that are useful in creating custom Event Plugins.\n */\nvar EventPluginUtils = {\n  isEndish: isEndish,\n  isMoveish: isMoveish,\n  isStartish: isStartish,\n\n  executeDirectDispatch: executeDirectDispatch,\n  executeDispatchesInOrder: executeDispatchesInOrder,\n  executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,\n  hasDispatches: hasDispatches,\n\n  getNode: function (id) {\n    return injection.Mount.getNode(id);\n  },\n  getID: function (node) {\n    return injection.Mount.getID(node);\n  },\n\n  injection: injection\n};\n\nmodule.exports = EventPluginUtils;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/EventPluginUtils.js\n ** module id = 24\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactErrorUtils\n * @typechecks\n */\n\n'use strict';\n\nvar caughtError = null;\n\n/**\n * Call a function while guarding against errors that happens within it.\n *\n * @param {?String} name of the guard to use for logging or debugging\n * @param {Function} func The function to invoke\n * @param {*} a First argument\n * @param {*} b Second argument\n */\nfunction invokeGuardedCallback(name, func, a, b) {\n  try {\n    return func(a, b);\n  } catch (x) {\n    if (caughtError === null) {\n      caughtError = x;\n    }\n    return undefined;\n  }\n}\n\nvar ReactErrorUtils = {\n  invokeGuardedCallback: invokeGuardedCallback,\n\n  /**\n   * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event\n   * handler are sure to be rethrown by rethrowCaughtError.\n   */\n  invokeGuardedCallbackWithCatch: invokeGuardedCallback,\n\n  /**\n   * During execution of guarded functions we will capture the first error which\n   * we will rethrow to be handled by the top level error handler.\n   */\n  rethrowCaughtError: function () {\n    if (caughtError) {\n      var error = caughtError;\n      caughtError = null;\n      throw error;\n    }\n  }\n};\n\nif (process.env.NODE_ENV !== 'production') {\n  /**\n   * To help development we can get better devtools integration by simulating a\n   * real browser event.\n   */\n  if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {\n    var fakeNode = document.createElement('react');\n    ReactErrorUtils.invokeGuardedCallback = function (name, func, a, b) {\n      var boundFunc = func.bind(null, a, b);\n      var evtType = 'react-' + name;\n      fakeNode.addEventListener(evtType, boundFunc, false);\n      var evt = document.createEvent('Event');\n      evt.initEvent(evtType, false, false);\n      fakeNode.dispatchEvent(evt);\n      fakeNode.removeEventListener(evtType, boundFunc, false);\n    };\n  }\n}\n\nmodule.exports = ReactErrorUtils;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactErrorUtils.js\n ** module id = 25\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule warning\n */\n\n'use strict';\n\nvar emptyFunction = require('./emptyFunction');\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar warning = emptyFunction;\n\nif (process.env.NODE_ENV !== 'production') {\n  warning = function (condition, format) {\n    for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n      args[_key - 2] = arguments[_key];\n    }\n\n    if (format === undefined) {\n      throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');\n    }\n\n    if (format.indexOf('Failed Composite propType: ') === 0) {\n      return; // Ignore CompositeComponent proptype check.\n    }\n\n    if (!condition) {\n      var argIndex = 0;\n      var message = 'Warning: ' + format.replace(/%s/g, function () {\n        return args[argIndex++];\n      });\n      if (typeof console !== 'undefined') {\n        console.error(message);\n      }\n      try {\n        // --- Welcome to debugging React ---\n        // This error was thrown as a convenience so that you can use this stack\n        // to find the callsite that caused this warning to fire.\n        throw new Error(message);\n      } catch (x) {}\n    }\n  };\n}\n\nmodule.exports = warning;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/warning.js\n ** module id = 26\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule emptyFunction\n */\n\n\"use strict\";\n\nfunction makeEmptyFunction(arg) {\n  return function () {\n    return arg;\n  };\n}\n\n/**\n * This function accepts and discards inputs; it has no side effects. This is\n * primarily useful idiomatically for overridable function endpoints which\n * always need to be callable, since JS lacks a null-call idiom ala Cocoa.\n */\nfunction emptyFunction() {}\n\nemptyFunction.thatReturns = makeEmptyFunction;\nemptyFunction.thatReturnsFalse = makeEmptyFunction(false);\nemptyFunction.thatReturnsTrue = makeEmptyFunction(true);\nemptyFunction.thatReturnsNull = makeEmptyFunction(null);\nemptyFunction.thatReturnsThis = function () {\n  return this;\n};\nemptyFunction.thatReturnsArgument = function (arg) {\n  return arg;\n};\n\nmodule.exports = emptyFunction;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/emptyFunction.js\n ** module id = 27\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule accumulateInto\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n *\n * Accumulates items that must not be null or undefined into the first one. This\n * is used to conserve memory by avoiding array allocations, and thus sacrifices\n * API cleanness. Since `current` can be null before being passed in and not\n * null after this function, make sure to assign it back to `current`:\n *\n * `a = accumulateInto(a, b);`\n *\n * This API should be sparingly used. Try `accumulate` for something cleaner.\n *\n * @return {*|array<*>} An accumulation of items.\n */\n\nfunction accumulateInto(current, next) {\n  !(next != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : invariant(false) : undefined;\n  if (current == null) {\n    return next;\n  }\n\n  // Both are not empty. Warning: Never call x.concat(y) when you are not\n  // certain that x is an Array (x could be a string with concat method).\n  var currentIsArray = Array.isArray(current);\n  var nextIsArray = Array.isArray(next);\n\n  if (currentIsArray && nextIsArray) {\n    current.push.apply(current, next);\n    return current;\n  }\n\n  if (currentIsArray) {\n    current.push(next);\n    return current;\n  }\n\n  if (nextIsArray) {\n    // A bit too dangerous to mutate `next`.\n    return [current].concat(next);\n  }\n\n  return [current, next];\n}\n\nmodule.exports = accumulateInto;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/accumulateInto.js\n ** module id = 28\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule forEachAccumulated\n */\n\n'use strict';\n\n/**\n * @param {array} arr an \"accumulation\" of items which is either an Array or\n * a single item. Useful when paired with the `accumulate` module. This is a\n * simple utility that allows us to reason about a collection of items, but\n * handling the case when there is exactly one item (and we do not need to\n * allocate an array).\n */\nvar forEachAccumulated = function (arr, cb, scope) {\n  if (Array.isArray(arr)) {\n    arr.forEach(cb, scope);\n  } else if (arr) {\n    cb.call(scope, arr);\n  }\n};\n\nmodule.exports = forEachAccumulated;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/forEachAccumulated.js\n ** module id = 29\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactEventEmitterMixin\n */\n\n'use strict';\n\nvar EventPluginHub = require('./EventPluginHub');\n\nfunction runEventQueueInBatch(events) {\n  EventPluginHub.enqueueEvents(events);\n  EventPluginHub.processEventQueue(false);\n}\n\nvar ReactEventEmitterMixin = {\n\n  /**\n   * Streams a fired top-level event to `EventPluginHub` where plugins have the\n   * opportunity to create `ReactEvent`s to be dispatched.\n   *\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {object} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native environment event.\n   */\n  handleTopLevel: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n    var events = EventPluginHub.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget);\n    runEventQueueInBatch(events);\n  }\n};\n\nmodule.exports = ReactEventEmitterMixin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactEventEmitterMixin.js\n ** module id = 30\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactPerf\n * @typechecks static-only\n */\n\n'use strict';\n\n/**\n * ReactPerf is a general AOP system designed to measure performance. This\n * module only has the hooks: see ReactDefaultPerf for the analysis tool.\n */\nvar ReactPerf = {\n  /**\n   * Boolean to enable/disable measurement. Set to false by default to prevent\n   * accidental logging and perf loss.\n   */\n  enableMeasure: false,\n\n  /**\n   * Holds onto the measure function in use. By default, don't measure\n   * anything, but we'll override this if we inject a measure function.\n   */\n  storedMeasure: _noMeasure,\n\n  /**\n   * @param {object} object\n   * @param {string} objectName\n   * @param {object<string>} methodNames\n   */\n  measureMethods: function (object, objectName, methodNames) {\n    if (process.env.NODE_ENV !== 'production') {\n      for (var key in methodNames) {\n        if (!methodNames.hasOwnProperty(key)) {\n          continue;\n        }\n        object[key] = ReactPerf.measure(objectName, methodNames[key], object[key]);\n      }\n    }\n  },\n\n  /**\n   * Use this to wrap methods you want to measure. Zero overhead in production.\n   *\n   * @param {string} objName\n   * @param {string} fnName\n   * @param {function} func\n   * @return {function}\n   */\n  measure: function (objName, fnName, func) {\n    if (process.env.NODE_ENV !== 'production') {\n      var measuredFunc = null;\n      var wrapper = function () {\n        if (ReactPerf.enableMeasure) {\n          if (!measuredFunc) {\n            measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);\n          }\n          return measuredFunc.apply(this, arguments);\n        }\n        return func.apply(this, arguments);\n      };\n      wrapper.displayName = objName + '_' + fnName;\n      return wrapper;\n    }\n    return func;\n  },\n\n  injection: {\n    /**\n     * @param {function} measure\n     */\n    injectMeasure: function (measure) {\n      ReactPerf.storedMeasure = measure;\n    }\n  }\n};\n\n/**\n * Simply passes through the measured function, without measuring it.\n *\n * @param {string} objName\n * @param {string} fnName\n * @param {function} func\n * @return {function}\n */\nfunction _noMeasure(objName, fnName, func) {\n  return func;\n}\n\nmodule.exports = ReactPerf;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactPerf.js\n ** module id = 31\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ViewportMetrics\n */\n\n'use strict';\n\nvar ViewportMetrics = {\n\n  currentScrollLeft: 0,\n\n  currentScrollTop: 0,\n\n  refreshScrollValues: function (scrollPosition) {\n    ViewportMetrics.currentScrollLeft = scrollPosition.x;\n    ViewportMetrics.currentScrollTop = scrollPosition.y;\n  }\n\n};\n\nmodule.exports = ViewportMetrics;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ViewportMetrics.js\n ** module id = 32\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule Object.assign\n */\n\n// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign\n\n'use strict';\n\nfunction assign(target, sources) {\n  if (target == null) {\n    throw new TypeError('Object.assign target cannot be null or undefined');\n  }\n\n  var to = Object(target);\n  var hasOwnProperty = Object.prototype.hasOwnProperty;\n\n  for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) {\n    var nextSource = arguments[nextIndex];\n    if (nextSource == null) {\n      continue;\n    }\n\n    var from = Object(nextSource);\n\n    // We don't currently support accessors nor proxies. Therefore this\n    // copy cannot throw. If we ever supported this then we must handle\n    // exceptions and side-effects. We don't support symbols so they won't\n    // be transferred.\n\n    for (var key in from) {\n      if (hasOwnProperty.call(from, key)) {\n        to[key] = from[key];\n      }\n    }\n  }\n\n  return to;\n}\n\nmodule.exports = assign;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/Object.assign.js\n ** module id = 33\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule isEventSupported\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n\nvar useHasFeature;\nif (ExecutionEnvironment.canUseDOM) {\n  useHasFeature = document.implementation && document.implementation.hasFeature &&\n  // always returns true in newer browsers as per the standard.\n  // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature\n  document.implementation.hasFeature('', '') !== true;\n}\n\n/**\n * Checks if an event is supported in the current execution environment.\n *\n * NOTE: This will not work correctly for non-generic events such as `change`,\n * `reset`, `load`, `error`, and `select`.\n *\n * Borrows from Modernizr.\n *\n * @param {string} eventNameSuffix Event name, e.g. \"click\".\n * @param {?boolean} capture Check if the capture phase is supported.\n * @return {boolean} True if the event is supported.\n * @internal\n * @license Modernizr 3.0.0pre (Custom Build) | MIT\n */\nfunction isEventSupported(eventNameSuffix, capture) {\n  if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) {\n    return false;\n  }\n\n  var eventName = 'on' + eventNameSuffix;\n  var isSupported = (eventName in document);\n\n  if (!isSupported) {\n    var element = document.createElement('div');\n    element.setAttribute(eventName, 'return;');\n    isSupported = typeof element[eventName] === 'function';\n  }\n\n  if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {\n    // This is the only way to test support for the `wheel` event in IE9+.\n    isSupported = document.implementation.hasFeature('Events.wheel', '3.0');\n  }\n\n  return isSupported;\n}\n\nmodule.exports = isEventSupported;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/isEventSupported.js\n ** module id = 34\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ExecutionEnvironment\n */\n\n'use strict';\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n\n/**\n * Simple, lightweight module assisting with the detection and context of\n * Worker. Helps avoid circular dependencies and allows code to reason about\n * whether or not they are in a Worker, even if they never include the main\n * `ReactWorker` dependency.\n */\nvar ExecutionEnvironment = {\n\n  canUseDOM: canUseDOM,\n\n  canUseWorkers: typeof Worker !== 'undefined',\n\n  canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),\n\n  canUseViewport: canUseDOM && !!window.screen,\n\n  isInWorker: !canUseDOM // For now, this is true - might change in the future.\n\n};\n\nmodule.exports = ExecutionEnvironment;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/ExecutionEnvironment.js\n ** module id = 35\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactCurrentOwner\n */\n\n'use strict';\n\n/**\n * Keeps track of the current owner.\n *\n * The current owner is the component who should own any components that are\n * currently being constructed.\n */\nvar ReactCurrentOwner = {\n\n  /**\n   * @internal\n   * @type {ReactComponent}\n   */\n  current: null\n\n};\n\nmodule.exports = ReactCurrentOwner;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactCurrentOwner.js\n ** module id = 36\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMFeatureFlags\n */\n\n'use strict';\n\nvar ReactDOMFeatureFlags = {\n  useCreateElement: false\n};\n\nmodule.exports = ReactDOMFeatureFlags;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMFeatureFlags.js\n ** module id = 37\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactElement\n */\n\n'use strict';\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\n\nvar assign = require('./Object.assign');\nvar canDefineProperty = require('./canDefineProperty');\n\n// The Symbol used to tag the ReactElement type. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;\n\nvar RESERVED_PROPS = {\n  key: true,\n  ref: true,\n  __self: true,\n  __source: true\n};\n\n/**\n * Base constructor for all React elements. This is only used to make this\n * work with a dynamic instanceof check. Nothing should live on this prototype.\n *\n * @param {*} type\n * @param {*} key\n * @param {string|object} ref\n * @param {*} self A *temporary* helper to detect places where `this` is\n * different from the `owner` when React.createElement is called, so that we\n * can warn. We want to get rid of owner and replace string `ref`s with arrow\n * functions, and as long as `this` and owner are the same, there will be no\n * change in behavior.\n * @param {*} source An annotation object (added by a transpiler or otherwise)\n * indicating filename, line number, and/or other information.\n * @param {*} owner\n * @param {*} props\n * @internal\n */\nvar ReactElement = function (type, key, ref, self, source, owner, props) {\n  var element = {\n    // This tag allow us to uniquely identify this as a React Element\n    $$typeof: REACT_ELEMENT_TYPE,\n\n    // Built-in properties that belong on the element\n    type: type,\n    key: key,\n    ref: ref,\n    props: props,\n\n    // Record the component responsible for creating this element.\n    _owner: owner\n  };\n\n  if (process.env.NODE_ENV !== 'production') {\n    // The validation flag is currently mutative. We put it on\n    // an external backing store so that we can freeze the whole object.\n    // This can be replaced with a WeakMap once they are implemented in\n    // commonly used development environments.\n    element._store = {};\n\n    // To make comparing ReactElements easier for testing purposes, we make\n    // the validation flag non-enumerable (where possible, which should\n    // include every environment we run tests in), so the test framework\n    // ignores it.\n    if (canDefineProperty) {\n      Object.defineProperty(element._store, 'validated', {\n        configurable: false,\n        enumerable: false,\n        writable: true,\n        value: false\n      });\n      // self and source are DEV only properties.\n      Object.defineProperty(element, '_self', {\n        configurable: false,\n        enumerable: false,\n        writable: false,\n        value: self\n      });\n      // Two elements created in two different places should be considered\n      // equal for testing purposes and therefore we hide it from enumeration.\n      Object.defineProperty(element, '_source', {\n        configurable: false,\n        enumerable: false,\n        writable: false,\n        value: source\n      });\n    } else {\n      element._store.validated = false;\n      element._self = self;\n      element._source = source;\n    }\n    Object.freeze(element.props);\n    Object.freeze(element);\n  }\n\n  return element;\n};\n\nReactElement.createElement = function (type, config, children) {\n  var propName;\n\n  // Reserved names are extracted\n  var props = {};\n\n  var key = null;\n  var ref = null;\n  var self = null;\n  var source = null;\n\n  if (config != null) {\n    ref = config.ref === undefined ? null : config.ref;\n    key = config.key === undefined ? null : '' + config.key;\n    self = config.__self === undefined ? null : config.__self;\n    source = config.__source === undefined ? null : config.__source;\n    // Remaining properties are added to a new props object\n    for (propName in config) {\n      if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n        props[propName] = config[propName];\n      }\n    }\n  }\n\n  // Children can be more than one argument, and those are transferred onto\n  // the newly allocated props object.\n  var childrenLength = arguments.length - 2;\n  if (childrenLength === 1) {\n    props.children = children;\n  } else if (childrenLength > 1) {\n    var childArray = Array(childrenLength);\n    for (var i = 0; i < childrenLength; i++) {\n      childArray[i] = arguments[i + 2];\n    }\n    props.children = childArray;\n  }\n\n  // Resolve default props\n  if (type && type.defaultProps) {\n    var defaultProps = type.defaultProps;\n    for (propName in defaultProps) {\n      if (typeof props[propName] === 'undefined') {\n        props[propName] = defaultProps[propName];\n      }\n    }\n  }\n\n  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);\n};\n\nReactElement.createFactory = function (type) {\n  var factory = ReactElement.createElement.bind(null, type);\n  // Expose the type on the factory and the prototype so that it can be\n  // easily accessed on elements. E.g. `<Foo />.type === Foo`.\n  // This should not be named `constructor` since this may not be the function\n  // that created the element, and it may not even be a constructor.\n  // Legacy hook TODO: Warn if this is accessed\n  factory.type = type;\n  return factory;\n};\n\nReactElement.cloneAndReplaceKey = function (oldElement, newKey) {\n  var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);\n\n  return newElement;\n};\n\nReactElement.cloneAndReplaceProps = function (oldElement, newProps) {\n  var newElement = ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, newProps);\n\n  if (process.env.NODE_ENV !== 'production') {\n    // If the key on the original is valid, then the clone is valid\n    newElement._store.validated = oldElement._store.validated;\n  }\n\n  return newElement;\n};\n\nReactElement.cloneElement = function (element, config, children) {\n  var propName;\n\n  // Original props are copied\n  var props = assign({}, element.props);\n\n  // Reserved names are extracted\n  var key = element.key;\n  var ref = element.ref;\n  // Self is preserved since the owner is preserved.\n  var self = element._self;\n  // Source is preserved since cloneElement is unlikely to be targeted by a\n  // transpiler, and the original source is probably a better indicator of the\n  // true owner.\n  var source = element._source;\n\n  // Owner will be preserved, unless ref is overridden\n  var owner = element._owner;\n\n  if (config != null) {\n    if (config.ref !== undefined) {\n      // Silently steal the ref from the parent.\n      ref = config.ref;\n      owner = ReactCurrentOwner.current;\n    }\n    if (config.key !== undefined) {\n      key = '' + config.key;\n    }\n    // Remaining properties override existing props\n    for (propName in config) {\n      if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n        props[propName] = config[propName];\n      }\n    }\n  }\n\n  // Children can be more than one argument, and those are transferred onto\n  // the newly allocated props object.\n  var childrenLength = arguments.length - 2;\n  if (childrenLength === 1) {\n    props.children = children;\n  } else if (childrenLength > 1) {\n    var childArray = Array(childrenLength);\n    for (var i = 0; i < childrenLength; i++) {\n      childArray[i] = arguments[i + 2];\n    }\n    props.children = childArray;\n  }\n\n  return ReactElement(element.type, key, ref, self, source, owner, props);\n};\n\n/**\n * @param {?object} object\n * @return {boolean} True if `object` is a valid component.\n * @final\n */\nReactElement.isValidElement = function (object) {\n  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n};\n\nmodule.exports = ReactElement;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactElement.js\n ** module id = 38\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule canDefineProperty\n */\n\n'use strict';\n\nvar canDefineProperty = false;\nif (process.env.NODE_ENV !== 'production') {\n  try {\n    Object.defineProperty({}, 'x', { get: function () {} });\n    canDefineProperty = true;\n  } catch (x) {\n    // IE will fail on defineProperty\n  }\n}\n\nmodule.exports = canDefineProperty;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/canDefineProperty.js\n ** module id = 39\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactEmptyComponentRegistry\n */\n\n'use strict';\n\n// This registry keeps track of the React IDs of the components that rendered to\n// `null` (in reality a placeholder such as `noscript`)\nvar nullComponentIDsRegistry = {};\n\n/**\n * @param {string} id Component's `_rootNodeID`.\n * @return {boolean} True if the component is rendered to null.\n */\nfunction isNullComponentID(id) {\n  return !!nullComponentIDsRegistry[id];\n}\n\n/**\n * Mark the component as having rendered to null.\n * @param {string} id Component's `_rootNodeID`.\n */\nfunction registerNullComponentID(id) {\n  nullComponentIDsRegistry[id] = true;\n}\n\n/**\n * Unmark the component as having rendered to null: it renders to something now.\n * @param {string} id Component's `_rootNodeID`.\n */\nfunction deregisterNullComponentID(id) {\n  delete nullComponentIDsRegistry[id];\n}\n\nvar ReactEmptyComponentRegistry = {\n  isNullComponentID: isNullComponentID,\n  registerNullComponentID: registerNullComponentID,\n  deregisterNullComponentID: deregisterNullComponentID\n};\n\nmodule.exports = ReactEmptyComponentRegistry;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactEmptyComponentRegistry.js\n ** module id = 40\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactInstanceHandles\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactRootIndex = require('./ReactRootIndex');\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar SEPARATOR = '.';\nvar SEPARATOR_LENGTH = SEPARATOR.length;\n\n/**\n * Maximum depth of traversals before we consider the possibility of a bad ID.\n */\nvar MAX_TREE_DEPTH = 10000;\n\n/**\n * Creates a DOM ID prefix to use when mounting React components.\n *\n * @param {number} index A unique integer\n * @return {string} React root ID.\n * @internal\n */\nfunction getReactRootIDString(index) {\n  return SEPARATOR + index.toString(36);\n}\n\n/**\n * Checks if a character in the supplied ID is a separator or the end.\n *\n * @param {string} id A React DOM ID.\n * @param {number} index Index of the character to check.\n * @return {boolean} True if the character is a separator or end of the ID.\n * @private\n */\nfunction isBoundary(id, index) {\n  return id.charAt(index) === SEPARATOR || index === id.length;\n}\n\n/**\n * Checks if the supplied string is a valid React DOM ID.\n *\n * @param {string} id A React DOM ID, maybe.\n * @return {boolean} True if the string is a valid React DOM ID.\n * @private\n */\nfunction isValidID(id) {\n  return id === '' || id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR;\n}\n\n/**\n * Checks if the first ID is an ancestor of or equal to the second ID.\n *\n * @param {string} ancestorID\n * @param {string} descendantID\n * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.\n * @internal\n */\nfunction isAncestorIDOf(ancestorID, descendantID) {\n  return descendantID.indexOf(ancestorID) === 0 && isBoundary(descendantID, ancestorID.length);\n}\n\n/**\n * Gets the parent ID of the supplied React DOM ID, `id`.\n *\n * @param {string} id ID of a component.\n * @return {string} ID of the parent, or an empty string.\n * @private\n */\nfunction getParentID(id) {\n  return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';\n}\n\n/**\n * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the\n * supplied `destinationID`. If they are equal, the ID is returned.\n *\n * @param {string} ancestorID ID of an ancestor node of `destinationID`.\n * @param {string} destinationID ID of the destination node.\n * @return {string} Next ID on the path from `ancestorID` to `destinationID`.\n * @private\n */\nfunction getNextDescendantID(ancestorID, destinationID) {\n  !(isValidID(ancestorID) && isValidID(destinationID)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', ancestorID, destinationID) : invariant(false) : undefined;\n  !isAncestorIDOf(ancestorID, destinationID) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNextDescendantID(...): React has made an invalid assumption about ' + 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', ancestorID, destinationID) : invariant(false) : undefined;\n  if (ancestorID === destinationID) {\n    return ancestorID;\n  }\n  // Skip over the ancestor and the immediate separator. Traverse until we hit\n  // another separator or we reach the end of `destinationID`.\n  var start = ancestorID.length + SEPARATOR_LENGTH;\n  var i;\n  for (i = start; i < destinationID.length; i++) {\n    if (isBoundary(destinationID, i)) {\n      break;\n    }\n  }\n  return destinationID.substr(0, i);\n}\n\n/**\n * Gets the nearest common ancestor ID of two IDs.\n *\n * Using this ID scheme, the nearest common ancestor ID is the longest common\n * prefix of the two IDs that immediately preceded a \"marker\" in both strings.\n *\n * @param {string} oneID\n * @param {string} twoID\n * @return {string} Nearest common ancestor ID, or the empty string if none.\n * @private\n */\nfunction getFirstCommonAncestorID(oneID, twoID) {\n  var minLength = Math.min(oneID.length, twoID.length);\n  if (minLength === 0) {\n    return '';\n  }\n  var lastCommonMarkerIndex = 0;\n  // Use `<=` to traverse until the \"EOL\" of the shorter string.\n  for (var i = 0; i <= minLength; i++) {\n    if (isBoundary(oneID, i) && isBoundary(twoID, i)) {\n      lastCommonMarkerIndex = i;\n    } else if (oneID.charAt(i) !== twoID.charAt(i)) {\n      break;\n    }\n  }\n  var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);\n  !isValidID(longestCommonID) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', oneID, twoID, longestCommonID) : invariant(false) : undefined;\n  return longestCommonID;\n}\n\n/**\n * Traverses the parent path between two IDs (either up or down). The IDs must\n * not be the same, and there must exist a parent path between them. If the\n * callback returns `false`, traversal is stopped.\n *\n * @param {?string} start ID at which to start traversal.\n * @param {?string} stop ID at which to end traversal.\n * @param {function} cb Callback to invoke each ID with.\n * @param {*} arg Argument to invoke the callback with.\n * @param {?boolean} skipFirst Whether or not to skip the first node.\n * @param {?boolean} skipLast Whether or not to skip the last node.\n * @private\n */\nfunction traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {\n  start = start || '';\n  stop = stop || '';\n  !(start !== stop) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', start) : invariant(false) : undefined;\n  var traverseUp = isAncestorIDOf(stop, start);\n  !(traverseUp || isAncestorIDOf(start, stop)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + 'not have a parent path.', start, stop) : invariant(false) : undefined;\n  // Traverse from `start` to `stop` one depth at a time.\n  var depth = 0;\n  var traverse = traverseUp ? getParentID : getNextDescendantID;\n  for (var id = start;; /* until break */id = traverse(id, stop)) {\n    var ret;\n    if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {\n      ret = cb(id, traverseUp, arg);\n    }\n    if (ret === false || id === stop) {\n      // Only break //after// visiting `stop`.\n      break;\n    }\n    !(depth++ < MAX_TREE_DEPTH) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', start, stop, id) : invariant(false) : undefined;\n  }\n}\n\n/**\n * Manages the IDs assigned to DOM representations of React components. This\n * uses a specific scheme in order to traverse the DOM efficiently (e.g. in\n * order to simulate events).\n *\n * @internal\n */\nvar ReactInstanceHandles = {\n\n  /**\n   * Constructs a React root ID\n   * @return {string} A React root ID.\n   */\n  createReactRootID: function () {\n    return getReactRootIDString(ReactRootIndex.createReactRootIndex());\n  },\n\n  /**\n   * Constructs a React ID by joining a root ID with a name.\n   *\n   * @param {string} rootID Root ID of a parent component.\n   * @param {string} name A component's name (as flattened children).\n   * @return {string} A React ID.\n   * @internal\n   */\n  createReactID: function (rootID, name) {\n    return rootID + name;\n  },\n\n  /**\n   * Gets the DOM ID of the React component that is the root of the tree that\n   * contains the React component with the supplied DOM ID.\n   *\n   * @param {string} id DOM ID of a React component.\n   * @return {?string} DOM ID of the React component that is the root.\n   * @internal\n   */\n  getReactRootIDFromNodeID: function (id) {\n    if (id && id.charAt(0) === SEPARATOR && id.length > 1) {\n      var index = id.indexOf(SEPARATOR, 1);\n      return index > -1 ? id.substr(0, index) : id;\n    }\n    return null;\n  },\n\n  /**\n   * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that\n   * should would receive a `mouseEnter` or `mouseLeave` event.\n   *\n   * NOTE: Does not invoke the callback on the nearest common ancestor because\n   * nothing \"entered\" or \"left\" that element.\n   *\n   * @param {string} leaveID ID being left.\n   * @param {string} enterID ID being entered.\n   * @param {function} cb Callback to invoke on each entered/left ID.\n   * @param {*} upArg Argument to invoke the callback with on left IDs.\n   * @param {*} downArg Argument to invoke the callback with on entered IDs.\n   * @internal\n   */\n  traverseEnterLeave: function (leaveID, enterID, cb, upArg, downArg) {\n    var ancestorID = getFirstCommonAncestorID(leaveID, enterID);\n    if (ancestorID !== leaveID) {\n      traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);\n    }\n    if (ancestorID !== enterID) {\n      traverseParentPath(ancestorID, enterID, cb, downArg, true, false);\n    }\n  },\n\n  /**\n   * Simulates the traversal of a two-phase, capture/bubble event dispatch.\n   *\n   * NOTE: This traversal happens on IDs without touching the DOM.\n   *\n   * @param {string} targetID ID of the target node.\n   * @param {function} cb Callback to invoke.\n   * @param {*} arg Argument to invoke the callback with.\n   * @internal\n   */\n  traverseTwoPhase: function (targetID, cb, arg) {\n    if (targetID) {\n      traverseParentPath('', targetID, cb, arg, true, false);\n      traverseParentPath(targetID, '', cb, arg, false, true);\n    }\n  },\n\n  /**\n   * Same as `traverseTwoPhase` but skips the `targetID`.\n   */\n  traverseTwoPhaseSkipTarget: function (targetID, cb, arg) {\n    if (targetID) {\n      traverseParentPath('', targetID, cb, arg, true, true);\n      traverseParentPath(targetID, '', cb, arg, true, true);\n    }\n  },\n\n  /**\n   * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For\n   * example, passing `.0.$row-0.1` would result in `cb` getting called\n   * with `.0`, `.0.$row-0`, and `.0.$row-0.1`.\n   *\n   * NOTE: This traversal happens on IDs without touching the DOM.\n   *\n   * @param {string} targetID ID of the target node.\n   * @param {function} cb Callback to invoke.\n   * @param {*} arg Argument to invoke the callback with.\n   * @internal\n   */\n  traverseAncestors: function (targetID, cb, arg) {\n    traverseParentPath('', targetID, cb, arg, true, false);\n  },\n\n  getFirstCommonAncestorID: getFirstCommonAncestorID,\n\n  /**\n   * Exposed for unit testing.\n   * @private\n   */\n  _getNextDescendantID: getNextDescendantID,\n\n  isAncestorIDOf: isAncestorIDOf,\n\n  SEPARATOR: SEPARATOR\n\n};\n\nmodule.exports = ReactInstanceHandles;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactInstanceHandles.js\n ** module id = 41\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactRootIndex\n * @typechecks\n */\n\n'use strict';\n\nvar ReactRootIndexInjection = {\n  /**\n   * @param {function} _createReactRootIndex\n   */\n  injectCreateReactRootIndex: function (_createReactRootIndex) {\n    ReactRootIndex.createReactRootIndex = _createReactRootIndex;\n  }\n};\n\nvar ReactRootIndex = {\n  createReactRootIndex: null,\n  injection: ReactRootIndexInjection\n};\n\nmodule.exports = ReactRootIndex;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactRootIndex.js\n ** module id = 42\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactInstanceMap\n */\n\n'use strict';\n\n/**\n * `ReactInstanceMap` maintains a mapping from a public facing stateful\n * instance (key) and the internal representation (value). This allows public\n * methods to accept the user facing instance as an argument and map them back\n * to internal methods.\n */\n\n// TODO: Replace this with ES6: var ReactInstanceMap = new Map();\nvar ReactInstanceMap = {\n\n  /**\n   * This API should be called `delete` but we'd have to make sure to always\n   * transform these to strings for IE support. When this transform is fully\n   * supported we can rename it.\n   */\n  remove: function (key) {\n    key._reactInternalInstance = undefined;\n  },\n\n  get: function (key) {\n    return key._reactInternalInstance;\n  },\n\n  has: function (key) {\n    return key._reactInternalInstance !== undefined;\n  },\n\n  set: function (key, value) {\n    key._reactInternalInstance = value;\n  }\n\n};\n\nmodule.exports = ReactInstanceMap;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactInstanceMap.js\n ** module id = 43\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactMarkupChecksum\n */\n\n'use strict';\n\nvar adler32 = require('./adler32');\n\nvar TAG_END = /\\/?>/;\n\nvar ReactMarkupChecksum = {\n  CHECKSUM_ATTR_NAME: 'data-react-checksum',\n\n  /**\n   * @param {string} markup Markup string\n   * @return {string} Markup string with checksum attribute attached\n   */\n  addChecksumToMarkup: function (markup) {\n    var checksum = adler32(markup);\n\n    // Add checksum (handle both parent tags and self-closing tags)\n    return markup.replace(TAG_END, ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '=\"' + checksum + '\"$&');\n  },\n\n  /**\n   * @param {string} markup to use\n   * @param {DOMElement} element root React element\n   * @returns {boolean} whether or not the markup is the same\n   */\n  canReuseMarkup: function (markup, element) {\n    var existingChecksum = element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);\n    existingChecksum = existingChecksum && parseInt(existingChecksum, 10);\n    var markupChecksum = adler32(markup);\n    return markupChecksum === existingChecksum;\n  }\n};\n\nmodule.exports = ReactMarkupChecksum;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactMarkupChecksum.js\n ** module id = 44\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule adler32\n */\n\n'use strict';\n\nvar MOD = 65521;\n\n// adler32 is not cryptographically strong, and is only used to sanity check that\n// markup generated on the server matches the markup generated on the client.\n// This implementation (a modified version of the SheetJS version) has been optimized\n// for our use case, at the expense of conforming to the adler32 specification\n// for non-ascii inputs.\nfunction adler32(data) {\n  var a = 1;\n  var b = 0;\n  var i = 0;\n  var l = data.length;\n  var m = l & ~0x3;\n  while (i < m) {\n    for (; i < Math.min(i + 4096, m); i += 4) {\n      b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3));\n    }\n    a %= MOD;\n    b %= MOD;\n  }\n  for (; i < l; i++) {\n    b += a += data.charCodeAt(i);\n  }\n  a %= MOD;\n  b %= MOD;\n  return a | b << 16;\n}\n\nmodule.exports = adler32;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/adler32.js\n ** module id = 45\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactReconciler\n */\n\n'use strict';\n\nvar ReactRef = require('./ReactRef');\n\n/**\n * Helper to call ReactRef.attachRefs with this composite component, split out\n * to avoid allocations in the transaction mount-ready queue.\n */\nfunction attachRefs() {\n  ReactRef.attachRefs(this, this._currentElement);\n}\n\nvar ReactReconciler = {\n\n  /**\n   * Initializes the component, renders markup, and registers event listeners.\n   *\n   * @param {ReactComponent} internalInstance\n   * @param {string} rootID DOM ID of the root node.\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @return {?string} Rendered markup to be inserted into the DOM.\n   * @final\n   * @internal\n   */\n  mountComponent: function (internalInstance, rootID, transaction, context) {\n    var markup = internalInstance.mountComponent(rootID, transaction, context);\n    if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {\n      transaction.getReactMountReady().enqueue(attachRefs, internalInstance);\n    }\n    return markup;\n  },\n\n  /**\n   * Releases any resources allocated by `mountComponent`.\n   *\n   * @final\n   * @internal\n   */\n  unmountComponent: function (internalInstance) {\n    ReactRef.detachRefs(internalInstance, internalInstance._currentElement);\n    internalInstance.unmountComponent();\n  },\n\n  /**\n   * Update a component using a new element.\n   *\n   * @param {ReactComponent} internalInstance\n   * @param {ReactElement} nextElement\n   * @param {ReactReconcileTransaction} transaction\n   * @param {object} context\n   * @internal\n   */\n  receiveComponent: function (internalInstance, nextElement, transaction, context) {\n    var prevElement = internalInstance._currentElement;\n\n    if (nextElement === prevElement && context === internalInstance._context) {\n      // Since elements are immutable after the owner is rendered,\n      // we can do a cheap identity compare here to determine if this is a\n      // superfluous reconcile. It's possible for state to be mutable but such\n      // change should trigger an update of the owner which would recreate\n      // the element. We explicitly check for the existence of an owner since\n      // it's possible for an element created outside a composite to be\n      // deeply mutated and reused.\n\n      // TODO: Bailing out early is just a perf optimization right?\n      // TODO: Removing the return statement should affect correctness?\n      return;\n    }\n\n    var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement);\n\n    if (refsChanged) {\n      ReactRef.detachRefs(internalInstance, prevElement);\n    }\n\n    internalInstance.receiveComponent(nextElement, transaction, context);\n\n    if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) {\n      transaction.getReactMountReady().enqueue(attachRefs, internalInstance);\n    }\n  },\n\n  /**\n   * Flush any dirty changes in a component.\n   *\n   * @param {ReactComponent} internalInstance\n   * @param {ReactReconcileTransaction} transaction\n   * @internal\n   */\n  performUpdateIfNecessary: function (internalInstance, transaction) {\n    internalInstance.performUpdateIfNecessary(transaction);\n  }\n\n};\n\nmodule.exports = ReactReconciler;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactReconciler.js\n ** module id = 46\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactRef\n */\n\n'use strict';\n\nvar ReactOwner = require('./ReactOwner');\n\nvar ReactRef = {};\n\nfunction attachRef(ref, component, owner) {\n  if (typeof ref === 'function') {\n    ref(component.getPublicInstance());\n  } else {\n    // Legacy ref\n    ReactOwner.addComponentAsRefTo(component, ref, owner);\n  }\n}\n\nfunction detachRef(ref, component, owner) {\n  if (typeof ref === 'function') {\n    ref(null);\n  } else {\n    // Legacy ref\n    ReactOwner.removeComponentAsRefFrom(component, ref, owner);\n  }\n}\n\nReactRef.attachRefs = function (instance, element) {\n  if (element === null || element === false) {\n    return;\n  }\n  var ref = element.ref;\n  if (ref != null) {\n    attachRef(ref, instance, element._owner);\n  }\n};\n\nReactRef.shouldUpdateRefs = function (prevElement, nextElement) {\n  // If either the owner or a `ref` has changed, make sure the newest owner\n  // has stored a reference to `this`, and the previous owner (if different)\n  // has forgotten the reference to `this`. We use the element instead\n  // of the public this.props because the post processing cannot determine\n  // a ref. The ref conceptually lives on the element.\n\n  // TODO: Should this even be possible? The owner cannot change because\n  // it's forbidden by shouldUpdateReactComponent. The ref can change\n  // if you swap the keys of but not the refs. Reconsider where this check\n  // is made. It probably belongs where the key checking and\n  // instantiateReactComponent is done.\n\n  var prevEmpty = prevElement === null || prevElement === false;\n  var nextEmpty = nextElement === null || nextElement === false;\n\n  return(\n    // This has a few false positives w/r/t empty components.\n    prevEmpty || nextEmpty || nextElement._owner !== prevElement._owner || nextElement.ref !== prevElement.ref\n  );\n};\n\nReactRef.detachRefs = function (instance, element) {\n  if (element === null || element === false) {\n    return;\n  }\n  var ref = element.ref;\n  if (ref != null) {\n    detachRef(ref, instance, element._owner);\n  }\n};\n\nmodule.exports = ReactRef;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactRef.js\n ** module id = 47\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactOwner\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * ReactOwners are capable of storing references to owned components.\n *\n * All components are capable of //being// referenced by owner components, but\n * only ReactOwner components are capable of //referencing// owned components.\n * The named reference is known as a \"ref\".\n *\n * Refs are available when mounted and updated during reconciliation.\n *\n *   var MyComponent = React.createClass({\n *     render: function() {\n *       return (\n *         <div onClick={this.handleClick}>\n *           <CustomComponent ref=\"custom\" />\n *         </div>\n *       );\n *     },\n *     handleClick: function() {\n *       this.refs.custom.handleClick();\n *     },\n *     componentDidMount: function() {\n *       this.refs.custom.initialize();\n *     }\n *   });\n *\n * Refs should rarely be used. When refs are used, they should only be done to\n * control data that is not handled by React's data flow.\n *\n * @class ReactOwner\n */\nvar ReactOwner = {\n\n  /**\n   * @param {?object} object\n   * @return {boolean} True if `object` is a valid owner.\n   * @final\n   */\n  isValidOwner: function (object) {\n    return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function');\n  },\n\n  /**\n   * Adds a component by ref to an owner component.\n   *\n   * @param {ReactComponent} component Component to reference.\n   * @param {string} ref Name by which to refer to the component.\n   * @param {ReactOwner} owner Component on which to record the ref.\n   * @final\n   * @internal\n   */\n  addComponentAsRefTo: function (component, ref, owner) {\n    !ReactOwner.isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might ' + 'be adding a ref to a component that was not created inside a component\\'s ' + '`render` method, or you have multiple copies of React loaded ' + '(details: https://fb.me/react-refs-must-have-owner).') : invariant(false) : undefined;\n    owner.attachRef(ref, component);\n  },\n\n  /**\n   * Removes a component by ref from an owner component.\n   *\n   * @param {ReactComponent} component Component to dereference.\n   * @param {string} ref Name of the ref to remove.\n   * @param {ReactOwner} owner Component on which the ref is recorded.\n   * @final\n   * @internal\n   */\n  removeComponentAsRefFrom: function (component, ref, owner) {\n    !ReactOwner.isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might ' + 'be removing a ref to a component that was not created inside a component\\'s ' + '`render` method, or you have multiple copies of React loaded ' + '(details: https://fb.me/react-refs-must-have-owner).') : invariant(false) : undefined;\n    // Check that `component` is still the current ref because we do not want to\n    // detach the ref if another component stole it.\n    if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) {\n      owner.detachRef(ref);\n    }\n  }\n\n};\n\nmodule.exports = ReactOwner;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactOwner.js\n ** module id = 48\n ** module chunks = 0\n **/","/**\n * Copyright 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactUpdateQueue\n */\n\n'use strict';\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactElement = require('./ReactElement');\nvar ReactInstanceMap = require('./ReactInstanceMap');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\nfunction enqueueUpdate(internalInstance) {\n  ReactUpdates.enqueueUpdate(internalInstance);\n}\n\nfunction getInternalInstanceReadyForUpdate(publicInstance, callerName) {\n  var internalInstance = ReactInstanceMap.get(publicInstance);\n  if (!internalInstance) {\n    if (process.env.NODE_ENV !== 'production') {\n      // Only warn when we have a callerName. Otherwise we should be silent.\n      // We're probably calling from enqueueCallback. We don't want to warn\n      // there because we already warned for the corresponding lifecycle method.\n      process.env.NODE_ENV !== 'production' ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, publicInstance.constructor.displayName) : undefined;\n    }\n    return null;\n  }\n\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition ' + '(such as within `render`). Render methods should be a pure function ' + 'of props and state.', callerName) : undefined;\n  }\n\n  return internalInstance;\n}\n\n/**\n * ReactUpdateQueue allows for state updates to be scheduled into a later\n * reconciliation step.\n */\nvar ReactUpdateQueue = {\n\n  /**\n   * Checks whether or not this composite component is mounted.\n   * @param {ReactClass} publicInstance The instance we want to test.\n   * @return {boolean} True if mounted, false otherwise.\n   * @protected\n   * @final\n   */\n  isMounted: function (publicInstance) {\n    if (process.env.NODE_ENV !== 'production') {\n      var owner = ReactCurrentOwner.current;\n      if (owner !== null) {\n        process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : undefined;\n        owner._warnedAboutRefsInRender = true;\n      }\n    }\n    var internalInstance = ReactInstanceMap.get(publicInstance);\n    if (internalInstance) {\n      // During componentWillMount and render this will still be null but after\n      // that will always render to something. At least for now. So we can use\n      // this hack.\n      return !!internalInstance._renderedComponent;\n    } else {\n      return false;\n    }\n  },\n\n  /**\n   * Enqueue a callback that will be executed after all the pending updates\n   * have processed.\n   *\n   * @param {ReactClass} publicInstance The instance to use as `this` context.\n   * @param {?function} callback Called after state is updated.\n   * @internal\n   */\n  enqueueCallback: function (publicInstance, callback) {\n    !(typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\\'t callable.') : invariant(false) : undefined;\n    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);\n\n    // Previously we would throw an error if we didn't have an internal\n    // instance. Since we want to make it a no-op instead, we mirror the same\n    // behavior we have in other enqueue* methods.\n    // We also need to ignore callbacks in componentWillMount. See\n    // enqueueUpdates.\n    if (!internalInstance) {\n      return null;\n    }\n\n    if (internalInstance._pendingCallbacks) {\n      internalInstance._pendingCallbacks.push(callback);\n    } else {\n      internalInstance._pendingCallbacks = [callback];\n    }\n    // TODO: The callback here is ignored when setState is called from\n    // componentWillMount. Either fix it or disallow doing so completely in\n    // favor of getInitialState. Alternatively, we can disallow\n    // componentWillMount during server-side rendering.\n    enqueueUpdate(internalInstance);\n  },\n\n  enqueueCallbackInternal: function (internalInstance, callback) {\n    !(typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\\'t callable.') : invariant(false) : undefined;\n    if (internalInstance._pendingCallbacks) {\n      internalInstance._pendingCallbacks.push(callback);\n    } else {\n      internalInstance._pendingCallbacks = [callback];\n    }\n    enqueueUpdate(internalInstance);\n  },\n\n  /**\n   * Forces an update. This should only be invoked when it is known with\n   * certainty that we are **not** in a DOM transaction.\n   *\n   * You may want to call this when you know that some deeper aspect of the\n   * component's state has changed but `setState` was not called.\n   *\n   * This will not invoke `shouldComponentUpdate`, but it will invoke\n   * `componentWillUpdate` and `componentDidUpdate`.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @internal\n   */\n  enqueueForceUpdate: function (publicInstance) {\n    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate');\n\n    if (!internalInstance) {\n      return;\n    }\n\n    internalInstance._pendingForceUpdate = true;\n\n    enqueueUpdate(internalInstance);\n  },\n\n  /**\n   * Replaces all of the state. Always use this or `setState` to mutate state.\n   * You should treat `this.state` as immutable.\n   *\n   * There is no guarantee that `this.state` will be immediately updated, so\n   * accessing `this.state` after calling this method may return the old value.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} completeState Next state.\n   * @internal\n   */\n  enqueueReplaceState: function (publicInstance, completeState) {\n    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState');\n\n    if (!internalInstance) {\n      return;\n    }\n\n    internalInstance._pendingStateQueue = [completeState];\n    internalInstance._pendingReplaceState = true;\n\n    enqueueUpdate(internalInstance);\n  },\n\n  /**\n   * Sets a subset of the state. This only exists because _pendingState is\n   * internal. This provides a merging strategy that is not available to deep\n   * properties which is confusing. TODO: Expose pendingState or don't use it\n   * during the merge.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} partialState Next partial state to be merged with state.\n   * @internal\n   */\n  enqueueSetState: function (publicInstance, partialState) {\n    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');\n\n    if (!internalInstance) {\n      return;\n    }\n\n    var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);\n    queue.push(partialState);\n\n    enqueueUpdate(internalInstance);\n  },\n\n  /**\n   * Sets a subset of the props.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} partialProps Subset of the next props.\n   * @internal\n   */\n  enqueueSetProps: function (publicInstance, partialProps) {\n    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setProps');\n    if (!internalInstance) {\n      return;\n    }\n    ReactUpdateQueue.enqueueSetPropsInternal(internalInstance, partialProps);\n  },\n\n  enqueueSetPropsInternal: function (internalInstance, partialProps) {\n    var topLevelWrapper = internalInstance._topLevelWrapper;\n    !topLevelWrapper ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setProps(...): You called `setProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.') : invariant(false) : undefined;\n\n    // Merge with the pending element if it exists, otherwise with existing\n    // element props.\n    var wrapElement = topLevelWrapper._pendingElement || topLevelWrapper._currentElement;\n    var element = wrapElement.props;\n    var props = assign({}, element.props, partialProps);\n    topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(wrapElement, ReactElement.cloneAndReplaceProps(element, props));\n\n    enqueueUpdate(topLevelWrapper);\n  },\n\n  /**\n   * Replaces all of the props.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} props New props.\n   * @internal\n   */\n  enqueueReplaceProps: function (publicInstance, props) {\n    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceProps');\n    if (!internalInstance) {\n      return;\n    }\n    ReactUpdateQueue.enqueueReplacePropsInternal(internalInstance, props);\n  },\n\n  enqueueReplacePropsInternal: function (internalInstance, props) {\n    var topLevelWrapper = internalInstance._topLevelWrapper;\n    !topLevelWrapper ? process.env.NODE_ENV !== 'production' ? invariant(false, 'replaceProps(...): You called `replaceProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.') : invariant(false) : undefined;\n\n    // Merge with the pending element if it exists, otherwise with existing\n    // element props.\n    var wrapElement = topLevelWrapper._pendingElement || topLevelWrapper._currentElement;\n    var element = wrapElement.props;\n    topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(wrapElement, ReactElement.cloneAndReplaceProps(element, props));\n\n    enqueueUpdate(topLevelWrapper);\n  },\n\n  enqueueElementInternal: function (internalInstance, newElement) {\n    internalInstance._pendingElement = newElement;\n    enqueueUpdate(internalInstance);\n  }\n\n};\n\nmodule.exports = ReactUpdateQueue;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactUpdateQueue.js\n ** module id = 49\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactUpdates\n */\n\n'use strict';\n\nvar CallbackQueue = require('./CallbackQueue');\nvar PooledClass = require('./PooledClass');\nvar ReactPerf = require('./ReactPerf');\nvar ReactReconciler = require('./ReactReconciler');\nvar Transaction = require('./Transaction');\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\n\nvar dirtyComponents = [];\nvar asapCallbackQueue = CallbackQueue.getPooled();\nvar asapEnqueued = false;\n\nvar batchingStrategy = null;\n\nfunction ensureInjected() {\n  !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching ' + 'strategy') : invariant(false) : undefined;\n}\n\nvar NESTED_UPDATES = {\n  initialize: function () {\n    this.dirtyComponentsLength = dirtyComponents.length;\n  },\n  close: function () {\n    if (this.dirtyComponentsLength !== dirtyComponents.length) {\n      // Additional updates were enqueued by componentDidUpdate handlers or\n      // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run\n      // these new updates so that if A's componentDidUpdate calls setState on\n      // B, B will update before the callback A's updater provided when calling\n      // setState.\n      dirtyComponents.splice(0, this.dirtyComponentsLength);\n      flushBatchedUpdates();\n    } else {\n      dirtyComponents.length = 0;\n    }\n  }\n};\n\nvar UPDATE_QUEUEING = {\n  initialize: function () {\n    this.callbackQueue.reset();\n  },\n  close: function () {\n    this.callbackQueue.notifyAll();\n  }\n};\n\nvar TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];\n\nfunction ReactUpdatesFlushTransaction() {\n  this.reinitializeTransaction();\n  this.dirtyComponentsLength = null;\n  this.callbackQueue = CallbackQueue.getPooled();\n  this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( /* forceHTML */false);\n}\n\nassign(ReactUpdatesFlushTransaction.prototype, Transaction.Mixin, {\n  getTransactionWrappers: function () {\n    return TRANSACTION_WRAPPERS;\n  },\n\n  destructor: function () {\n    this.dirtyComponentsLength = null;\n    CallbackQueue.release(this.callbackQueue);\n    this.callbackQueue = null;\n    ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);\n    this.reconcileTransaction = null;\n  },\n\n  perform: function (method, scope, a) {\n    // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`\n    // with this transaction's wrappers around it.\n    return Transaction.Mixin.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);\n  }\n});\n\nPooledClass.addPoolingTo(ReactUpdatesFlushTransaction);\n\nfunction batchedUpdates(callback, a, b, c, d, e) {\n  ensureInjected();\n  batchingStrategy.batchedUpdates(callback, a, b, c, d, e);\n}\n\n/**\n * Array comparator for ReactComponents by mount ordering.\n *\n * @param {ReactComponent} c1 first component you're comparing\n * @param {ReactComponent} c2 second component you're comparing\n * @return {number} Return value usable by Array.prototype.sort().\n */\nfunction mountOrderComparator(c1, c2) {\n  return c1._mountOrder - c2._mountOrder;\n}\n\nfunction runBatchedUpdates(transaction) {\n  var len = transaction.dirtyComponentsLength;\n  !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\\'s stored dirty-components length (%s) to ' + 'match dirty-components array length (%s).', len, dirtyComponents.length) : invariant(false) : undefined;\n\n  // Since reconciling a component higher in the owner hierarchy usually (not\n  // always -- see shouldComponentUpdate()) will reconcile children, reconcile\n  // them before their children by sorting the array.\n  dirtyComponents.sort(mountOrderComparator);\n\n  for (var i = 0; i < len; i++) {\n    // If a component is unmounted before pending changes apply, it will still\n    // be here, but we assume that it has cleared its _pendingCallbacks and\n    // that performUpdateIfNecessary is a noop.\n    var component = dirtyComponents[i];\n\n    // If performUpdateIfNecessary happens to enqueue any new updates, we\n    // shouldn't execute the callbacks until the next render happens, so\n    // stash the callbacks first\n    var callbacks = component._pendingCallbacks;\n    component._pendingCallbacks = null;\n\n    ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction);\n\n    if (callbacks) {\n      for (var j = 0; j < callbacks.length; j++) {\n        transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance());\n      }\n    }\n  }\n}\n\nvar flushBatchedUpdates = function () {\n  // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents\n  // array and perform any updates enqueued by mount-ready handlers (i.e.,\n  // componentDidUpdate) but we need to check here too in order to catch\n  // updates enqueued by setState callbacks and asap calls.\n  while (dirtyComponents.length || asapEnqueued) {\n    if (dirtyComponents.length) {\n      var transaction = ReactUpdatesFlushTransaction.getPooled();\n      transaction.perform(runBatchedUpdates, null, transaction);\n      ReactUpdatesFlushTransaction.release(transaction);\n    }\n\n    if (asapEnqueued) {\n      asapEnqueued = false;\n      var queue = asapCallbackQueue;\n      asapCallbackQueue = CallbackQueue.getPooled();\n      queue.notifyAll();\n      CallbackQueue.release(queue);\n    }\n  }\n};\nflushBatchedUpdates = ReactPerf.measure('ReactUpdates', 'flushBatchedUpdates', flushBatchedUpdates);\n\n/**\n * Mark a component as needing a rerender, adding an optional callback to a\n * list of functions which will be executed once the rerender occurs.\n */\nfunction enqueueUpdate(component) {\n  ensureInjected();\n\n  // Various parts of our code (such as ReactCompositeComponent's\n  // _renderValidatedComponent) assume that calls to render aren't nested;\n  // verify that that's the case. (This is called by each top-level update\n  // function, like setProps, setState, forceUpdate, etc.; creation and\n  // destruction of top-level components is guarded in ReactMount.)\n\n  if (!batchingStrategy.isBatchingUpdates) {\n    batchingStrategy.batchedUpdates(enqueueUpdate, component);\n    return;\n  }\n\n  dirtyComponents.push(component);\n}\n\n/**\n * Enqueue a callback to be run at the end of the current batching cycle. Throws\n * if no updates are currently being performed.\n */\nfunction asap(callback, context) {\n  !batchingStrategy.isBatchingUpdates ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates.asap: Can\\'t enqueue an asap callback in a context where' + 'updates are not being batched.') : invariant(false) : undefined;\n  asapCallbackQueue.enqueue(callback, context);\n  asapEnqueued = true;\n}\n\nvar ReactUpdatesInjection = {\n  injectReconcileTransaction: function (ReconcileTransaction) {\n    !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : invariant(false) : undefined;\n    ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;\n  },\n\n  injectBatchingStrategy: function (_batchingStrategy) {\n    !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : invariant(false) : undefined;\n    !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : invariant(false) : undefined;\n    !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : invariant(false) : undefined;\n    batchingStrategy = _batchingStrategy;\n  }\n};\n\nvar ReactUpdates = {\n  /**\n   * React references `ReactReconcileTransaction` using this property in order\n   * to allow dependency injection.\n   *\n   * @internal\n   */\n  ReactReconcileTransaction: null,\n\n  batchedUpdates: batchedUpdates,\n  enqueueUpdate: enqueueUpdate,\n  flushBatchedUpdates: flushBatchedUpdates,\n  injection: ReactUpdatesInjection,\n  asap: asap\n};\n\nmodule.exports = ReactUpdates;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactUpdates.js\n ** module id = 50\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule CallbackQueue\n */\n\n'use strict';\n\nvar PooledClass = require('./PooledClass');\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * A specialized pseudo-event module to help keep track of components waiting to\n * be notified when their DOM representations are available for use.\n *\n * This implements `PooledClass`, so you should never need to instantiate this.\n * Instead, use `CallbackQueue.getPooled()`.\n *\n * @class ReactMountReady\n * @implements PooledClass\n * @internal\n */\nfunction CallbackQueue() {\n  this._callbacks = null;\n  this._contexts = null;\n}\n\nassign(CallbackQueue.prototype, {\n\n  /**\n   * Enqueues a callback to be invoked when `notifyAll` is invoked.\n   *\n   * @param {function} callback Invoked when `notifyAll` is invoked.\n   * @param {?object} context Context to call `callback` with.\n   * @internal\n   */\n  enqueue: function (callback, context) {\n    this._callbacks = this._callbacks || [];\n    this._contexts = this._contexts || [];\n    this._callbacks.push(callback);\n    this._contexts.push(context);\n  },\n\n  /**\n   * Invokes all enqueued callbacks and clears the queue. This is invoked after\n   * the DOM representation of a component has been created or updated.\n   *\n   * @internal\n   */\n  notifyAll: function () {\n    var callbacks = this._callbacks;\n    var contexts = this._contexts;\n    if (callbacks) {\n      !(callbacks.length === contexts.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : invariant(false) : undefined;\n      this._callbacks = null;\n      this._contexts = null;\n      for (var i = 0; i < callbacks.length; i++) {\n        callbacks[i].call(contexts[i]);\n      }\n      callbacks.length = 0;\n      contexts.length = 0;\n    }\n  },\n\n  /**\n   * Resets the internal queue.\n   *\n   * @internal\n   */\n  reset: function () {\n    this._callbacks = null;\n    this._contexts = null;\n  },\n\n  /**\n   * `PooledClass` looks for this.\n   */\n  destructor: function () {\n    this.reset();\n  }\n\n});\n\nPooledClass.addPoolingTo(CallbackQueue);\n\nmodule.exports = CallbackQueue;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/CallbackQueue.js\n ** module id = 51\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule PooledClass\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Static poolers. Several custom versions for each potential number of\n * arguments. A completely generic pooler is easy to implement, but would\n * require accessing the `arguments` object. In each of these, `this` refers to\n * the Class itself, not an instance. If any others are needed, simply add them\n * here, or in their own files.\n */\nvar oneArgumentPooler = function (copyFieldsFrom) {\n  var Klass = this;\n  if (Klass.instancePool.length) {\n    var instance = Klass.instancePool.pop();\n    Klass.call(instance, copyFieldsFrom);\n    return instance;\n  } else {\n    return new Klass(copyFieldsFrom);\n  }\n};\n\nvar twoArgumentPooler = function (a1, a2) {\n  var Klass = this;\n  if (Klass.instancePool.length) {\n    var instance = Klass.instancePool.pop();\n    Klass.call(instance, a1, a2);\n    return instance;\n  } else {\n    return new Klass(a1, a2);\n  }\n};\n\nvar threeArgumentPooler = function (a1, a2, a3) {\n  var Klass = this;\n  if (Klass.instancePool.length) {\n    var instance = Klass.instancePool.pop();\n    Klass.call(instance, a1, a2, a3);\n    return instance;\n  } else {\n    return new Klass(a1, a2, a3);\n  }\n};\n\nvar fourArgumentPooler = function (a1, a2, a3, a4) {\n  var Klass = this;\n  if (Klass.instancePool.length) {\n    var instance = Klass.instancePool.pop();\n    Klass.call(instance, a1, a2, a3, a4);\n    return instance;\n  } else {\n    return new Klass(a1, a2, a3, a4);\n  }\n};\n\nvar fiveArgumentPooler = function (a1, a2, a3, a4, a5) {\n  var Klass = this;\n  if (Klass.instancePool.length) {\n    var instance = Klass.instancePool.pop();\n    Klass.call(instance, a1, a2, a3, a4, a5);\n    return instance;\n  } else {\n    return new Klass(a1, a2, a3, a4, a5);\n  }\n};\n\nvar standardReleaser = function (instance) {\n  var Klass = this;\n  !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : invariant(false) : undefined;\n  instance.destructor();\n  if (Klass.instancePool.length < Klass.poolSize) {\n    Klass.instancePool.push(instance);\n  }\n};\n\nvar DEFAULT_POOL_SIZE = 10;\nvar DEFAULT_POOLER = oneArgumentPooler;\n\n/**\n * Augments `CopyConstructor` to be a poolable class, augmenting only the class\n * itself (statically) not adding any prototypical fields. Any CopyConstructor\n * you give this may have a `poolSize` property, and will look for a\n * prototypical `destructor` on instances (optional).\n *\n * @param {Function} CopyConstructor Constructor that can be used to reset.\n * @param {Function} pooler Customizable pooler.\n */\nvar addPoolingTo = function (CopyConstructor, pooler) {\n  var NewKlass = CopyConstructor;\n  NewKlass.instancePool = [];\n  NewKlass.getPooled = pooler || DEFAULT_POOLER;\n  if (!NewKlass.poolSize) {\n    NewKlass.poolSize = DEFAULT_POOL_SIZE;\n  }\n  NewKlass.release = standardReleaser;\n  return NewKlass;\n};\n\nvar PooledClass = {\n  addPoolingTo: addPoolingTo,\n  oneArgumentPooler: oneArgumentPooler,\n  twoArgumentPooler: twoArgumentPooler,\n  threeArgumentPooler: threeArgumentPooler,\n  fourArgumentPooler: fourArgumentPooler,\n  fiveArgumentPooler: fiveArgumentPooler\n};\n\nmodule.exports = PooledClass;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/PooledClass.js\n ** module id = 52\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule Transaction\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * `Transaction` creates a black box that is able to wrap any method such that\n * certain invariants are maintained before and after the method is invoked\n * (Even if an exception is thrown while invoking the wrapped method). Whoever\n * instantiates a transaction can provide enforcers of the invariants at\n * creation time. The `Transaction` class itself will supply one additional\n * automatic invariant for you - the invariant that any transaction instance\n * should not be run while it is already being run. You would typically create a\n * single instance of a `Transaction` for reuse multiple times, that potentially\n * is used to wrap several different methods. Wrappers are extremely simple -\n * they only require implementing two methods.\n *\n * <pre>\n *                       wrappers (injected at creation time)\n *                                      +        +\n *                                      |        |\n *                    +-----------------|--------|--------------+\n *                    |                 v        |              |\n *                    |      +---------------+   |              |\n *                    |   +--|    wrapper1   |---|----+         |\n *                    |   |  +---------------+   v    |         |\n *                    |   |          +-------------+  |         |\n *                    |   |     +----|   wrapper2  |--------+   |\n *                    |   |     |    +-------------+  |     |   |\n *                    |   |     |                     |     |   |\n *                    |   v     v                     v     v   | wrapper\n *                    | +---+ +---+   +---------+   +---+ +---+ | invariants\n * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained\n * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->\n *                    | |   | |   |   |         |   |   | |   | |\n *                    | |   | |   |   |         |   |   | |   | |\n *                    | |   | |   |   |         |   |   | |   | |\n *                    | +---+ +---+   +---------+   +---+ +---+ |\n *                    |  initialize                    close    |\n *                    +-----------------------------------------+\n * </pre>\n *\n * Use cases:\n * - Preserving the input selection ranges before/after reconciliation.\n *   Restoring selection even in the event of an unexpected error.\n * - Deactivating events while rearranging the DOM, preventing blurs/focuses,\n *   while guaranteeing that afterwards, the event system is reactivated.\n * - Flushing a queue of collected DOM mutations to the main UI thread after a\n *   reconciliation takes place in a worker thread.\n * - Invoking any collected `componentDidUpdate` callbacks after rendering new\n *   content.\n * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue\n *   to preserve the `scrollTop` (an automatic scroll aware DOM).\n * - (Future use case): Layout calculations before and after DOM updates.\n *\n * Transactional plugin API:\n * - A module that has an `initialize` method that returns any precomputation.\n * - and a `close` method that accepts the precomputation. `close` is invoked\n *   when the wrapped process is completed, or has failed.\n *\n * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules\n * that implement `initialize` and `close`.\n * @return {Transaction} Single transaction for reuse in thread.\n *\n * @class Transaction\n */\nvar Mixin = {\n  /**\n   * Sets up this instance so that it is prepared for collecting metrics. Does\n   * so such that this setup method may be used on an instance that is already\n   * initialized, in a way that does not consume additional memory upon reuse.\n   * That can be useful if you decide to make your subclass of this mixin a\n   * \"PooledClass\".\n   */\n  reinitializeTransaction: function () {\n    this.transactionWrappers = this.getTransactionWrappers();\n    if (this.wrapperInitData) {\n      this.wrapperInitData.length = 0;\n    } else {\n      this.wrapperInitData = [];\n    }\n    this._isInTransaction = false;\n  },\n\n  _isInTransaction: false,\n\n  /**\n   * @abstract\n   * @return {Array<TransactionWrapper>} Array of transaction wrappers.\n   */\n  getTransactionWrappers: null,\n\n  isInTransaction: function () {\n    return !!this._isInTransaction;\n  },\n\n  /**\n   * Executes the function within a safety window. Use this for the top level\n   * methods that result in large amounts of computation/mutations that would\n   * need to be safety checked. The optional arguments helps prevent the need\n   * to bind in many cases.\n   *\n   * @param {function} method Member of scope to call.\n   * @param {Object} scope Scope to invoke from.\n   * @param {Object?=} a Argument to pass to the method.\n   * @param {Object?=} b Argument to pass to the method.\n   * @param {Object?=} c Argument to pass to the method.\n   * @param {Object?=} d Argument to pass to the method.\n   * @param {Object?=} e Argument to pass to the method.\n   * @param {Object?=} f Argument to pass to the method.\n   *\n   * @return {*} Return value from `method`.\n   */\n  perform: function (method, scope, a, b, c, d, e, f) {\n    !!this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there ' + 'is already an outstanding transaction.') : invariant(false) : undefined;\n    var errorThrown;\n    var ret;\n    try {\n      this._isInTransaction = true;\n      // Catching errors makes debugging more difficult, so we start with\n      // errorThrown set to true before setting it to false after calling\n      // close -- if it's still set to true in the finally block, it means\n      // one of these calls threw.\n      errorThrown = true;\n      this.initializeAll(0);\n      ret = method.call(scope, a, b, c, d, e, f);\n      errorThrown = false;\n    } finally {\n      try {\n        if (errorThrown) {\n          // If `method` throws, prefer to show that stack trace over any thrown\n          // by invoking `closeAll`.\n          try {\n            this.closeAll(0);\n          } catch (err) {}\n        } else {\n          // Since `method` didn't throw, we don't want to silence the exception\n          // here.\n          this.closeAll(0);\n        }\n      } finally {\n        this._isInTransaction = false;\n      }\n    }\n    return ret;\n  },\n\n  initializeAll: function (startIndex) {\n    var transactionWrappers = this.transactionWrappers;\n    for (var i = startIndex; i < transactionWrappers.length; i++) {\n      var wrapper = transactionWrappers[i];\n      try {\n        // Catching errors makes debugging more difficult, so we start with the\n        // OBSERVED_ERROR state before overwriting it with the real return value\n        // of initialize -- if it's still set to OBSERVED_ERROR in the finally\n        // block, it means wrapper.initialize threw.\n        this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;\n        this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null;\n      } finally {\n        if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) {\n          // The initializer for wrapper i threw an error; initialize the\n          // remaining wrappers but silence any exceptions from them to ensure\n          // that the first error is the one to bubble up.\n          try {\n            this.initializeAll(i + 1);\n          } catch (err) {}\n        }\n      }\n    }\n  },\n\n  /**\n   * Invokes each of `this.transactionWrappers.close[i]` functions, passing into\n   * them the respective return values of `this.transactionWrappers.init[i]`\n   * (`close`rs that correspond to initializers that failed will not be\n   * invoked).\n   */\n  closeAll: function (startIndex) {\n    !this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : invariant(false) : undefined;\n    var transactionWrappers = this.transactionWrappers;\n    for (var i = startIndex; i < transactionWrappers.length; i++) {\n      var wrapper = transactionWrappers[i];\n      var initData = this.wrapperInitData[i];\n      var errorThrown;\n      try {\n        // Catching errors makes debugging more difficult, so we start with\n        // errorThrown set to true before setting it to false after calling\n        // close -- if it's still set to true in the finally block, it means\n        // wrapper.close threw.\n        errorThrown = true;\n        if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) {\n          wrapper.close.call(this, initData);\n        }\n        errorThrown = false;\n      } finally {\n        if (errorThrown) {\n          // The closer for wrapper i threw an error; close the remaining\n          // wrappers but silence any exceptions from them to ensure that the\n          // first error is the one to bubble up.\n          try {\n            this.closeAll(i + 1);\n          } catch (e) {}\n        }\n      }\n    }\n    this.wrapperInitData.length = 0;\n  }\n};\n\nvar Transaction = {\n\n  Mixin: Mixin,\n\n  /**\n   * Token to look for to determine if an error occurred.\n   */\n  OBSERVED_ERROR: {}\n\n};\n\nmodule.exports = Transaction;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/Transaction.js\n ** module id = 53\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule emptyObject\n */\n\n'use strict';\n\nvar emptyObject = {};\n\nif (process.env.NODE_ENV !== 'production') {\n  Object.freeze(emptyObject);\n}\n\nmodule.exports = emptyObject;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/emptyObject.js\n ** module id = 54\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule containsNode\n * @typechecks\n */\n\n'use strict';\n\nvar isTextNode = require('./isTextNode');\n\n/*eslint-disable no-bitwise */\n\n/**\n * Checks if a given DOM node contains or is another DOM node.\n *\n * @param {?DOMNode} outerNode Outer DOM node.\n * @param {?DOMNode} innerNode Inner DOM node.\n * @return {boolean} True if `outerNode` contains or is `innerNode`.\n */\nfunction containsNode(_x, _x2) {\n  var _again = true;\n\n  _function: while (_again) {\n    var outerNode = _x,\n        innerNode = _x2;\n    _again = false;\n\n    if (!outerNode || !innerNode) {\n      return false;\n    } else if (outerNode === innerNode) {\n      return true;\n    } else if (isTextNode(outerNode)) {\n      return false;\n    } else if (isTextNode(innerNode)) {\n      _x = outerNode;\n      _x2 = innerNode.parentNode;\n      _again = true;\n      continue _function;\n    } else if (outerNode.contains) {\n      return outerNode.contains(innerNode);\n    } else if (outerNode.compareDocumentPosition) {\n      return !!(outerNode.compareDocumentPosition(innerNode) & 16);\n    } else {\n      return false;\n    }\n  }\n}\n\nmodule.exports = containsNode;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/containsNode.js\n ** module id = 55\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule isTextNode\n * @typechecks\n */\n\n'use strict';\n\nvar isNode = require('./isNode');\n\n/**\n * @param {*} object The object to check.\n * @return {boolean} Whether or not the object is a DOM text node.\n */\nfunction isTextNode(object) {\n  return isNode(object) && object.nodeType == 3;\n}\n\nmodule.exports = isTextNode;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/isTextNode.js\n ** module id = 56\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule isNode\n * @typechecks\n */\n\n/**\n * @param {*} object The object to check.\n * @return {boolean} Whether or not the object is a DOM node.\n */\n'use strict';\n\nfunction isNode(object) {\n  return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));\n}\n\nmodule.exports = isNode;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/isNode.js\n ** module id = 57\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule instantiateReactComponent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactCompositeComponent = require('./ReactCompositeComponent');\nvar ReactEmptyComponent = require('./ReactEmptyComponent');\nvar ReactNativeComponent = require('./ReactNativeComponent');\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\n// To avoid a cyclic dependency, we create the final class in this module\nvar ReactCompositeComponentWrapper = function () {};\nassign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent.Mixin, {\n  _instantiateReactComponent: instantiateReactComponent\n});\n\nfunction getDeclarationErrorAddendum(owner) {\n  if (owner) {\n    var name = owner.getName();\n    if (name) {\n      return ' Check the render method of `' + name + '`.';\n    }\n  }\n  return '';\n}\n\n/**\n * Check if the type reference is a known internal type. I.e. not a user\n * provided composite type.\n *\n * @param {function} type\n * @return {boolean} Returns true if this is a valid internal type.\n */\nfunction isInternalComponentType(type) {\n  return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function';\n}\n\n/**\n * Given a ReactNode, create an instance that will actually be mounted.\n *\n * @param {ReactNode} node\n * @return {object} A new instance of the element's constructor.\n * @protected\n */\nfunction instantiateReactComponent(node) {\n  var instance;\n\n  if (node === null || node === false) {\n    instance = new ReactEmptyComponent(instantiateReactComponent);\n  } else if (typeof node === 'object') {\n    var element = node;\n    !(element && (typeof element.type === 'function' || typeof element.type === 'string')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) ' + 'or a class/function (for composite components) but got: %s.%s', element.type == null ? element.type : typeof element.type, getDeclarationErrorAddendum(element._owner)) : invariant(false) : undefined;\n\n    // Special case string values\n    if (typeof element.type === 'string') {\n      instance = ReactNativeComponent.createInternalComponent(element);\n    } else if (isInternalComponentType(element.type)) {\n      // This is temporarily available for custom components that are not string\n      // representations. I.e. ART. Once those are updated to use the string\n      // representation, we can drop this code path.\n      instance = new element.type(element);\n    } else {\n      instance = new ReactCompositeComponentWrapper();\n    }\n  } else if (typeof node === 'string' || typeof node === 'number') {\n    instance = ReactNativeComponent.createInstanceForText(node);\n  } else {\n    !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : invariant(false) : undefined;\n  }\n\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(typeof instance.construct === 'function' && typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : undefined;\n  }\n\n  // Sets up the instance. This can probably just move into the constructor now.\n  instance.construct(node);\n\n  // These two fields are used by the DOM and ART diffing algorithms\n  // respectively. Instead of using expandos on components, we should be\n  // storing the state needed by the diffing algorithms elsewhere.\n  instance._mountIndex = 0;\n  instance._mountImage = null;\n\n  if (process.env.NODE_ENV !== 'production') {\n    instance._isOwnerNecessary = false;\n    instance._warnedAboutRefsInRender = false;\n  }\n\n  // Internal instances should fully constructed at this point, so they should\n  // not get any new fields added to them at this point.\n  if (process.env.NODE_ENV !== 'production') {\n    if (Object.preventExtensions) {\n      Object.preventExtensions(instance);\n    }\n  }\n\n  return instance;\n}\n\nmodule.exports = instantiateReactComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/instantiateReactComponent.js\n ** module id = 58\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactCompositeComponent\n */\n\n'use strict';\n\nvar ReactComponentEnvironment = require('./ReactComponentEnvironment');\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactElement = require('./ReactElement');\nvar ReactInstanceMap = require('./ReactInstanceMap');\nvar ReactPerf = require('./ReactPerf');\nvar ReactPropTypeLocations = require('./ReactPropTypeLocations');\nvar ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');\nvar ReactReconciler = require('./ReactReconciler');\nvar ReactUpdateQueue = require('./ReactUpdateQueue');\n\nvar assign = require('./Object.assign');\nvar emptyObject = require('fbjs/lib/emptyObject');\nvar invariant = require('fbjs/lib/invariant');\nvar shouldUpdateReactComponent = require('./shouldUpdateReactComponent');\nvar warning = require('fbjs/lib/warning');\n\nfunction getDeclarationErrorAddendum(component) {\n  var owner = component._currentElement._owner || null;\n  if (owner) {\n    var name = owner.getName();\n    if (name) {\n      return ' Check the render method of `' + name + '`.';\n    }\n  }\n  return '';\n}\n\nfunction StatelessComponent(Component) {}\nStatelessComponent.prototype.render = function () {\n  var Component = ReactInstanceMap.get(this)._currentElement.type;\n  return Component(this.props, this.context, this.updater);\n};\n\n/**\n * ------------------ The Life-Cycle of a Composite Component ------------------\n *\n * - constructor: Initialization of state. The instance is now retained.\n *   - componentWillMount\n *   - render\n *   - [children's constructors]\n *     - [children's componentWillMount and render]\n *     - [children's componentDidMount]\n *     - componentDidMount\n *\n *       Update Phases:\n *       - componentWillReceiveProps (only called if parent updated)\n *       - shouldComponentUpdate\n *         - componentWillUpdate\n *           - render\n *           - [children's constructors or receive props phases]\n *         - componentDidUpdate\n *\n *     - componentWillUnmount\n *     - [children's componentWillUnmount]\n *   - [children destroyed]\n * - (destroyed): The instance is now blank, released by React and ready for GC.\n *\n * -----------------------------------------------------------------------------\n */\n\n/**\n * An incrementing ID assigned to each component when it is mounted. This is\n * used to enforce the order in which `ReactUpdates` updates dirty components.\n *\n * @private\n */\nvar nextMountID = 1;\n\n/**\n * @lends {ReactCompositeComponent.prototype}\n */\nvar ReactCompositeComponentMixin = {\n\n  /**\n   * Base constructor for all composite component.\n   *\n   * @param {ReactElement} element\n   * @final\n   * @internal\n   */\n  construct: function (element) {\n    this._currentElement = element;\n    this._rootNodeID = null;\n    this._instance = null;\n\n    // See ReactUpdateQueue\n    this._pendingElement = null;\n    this._pendingStateQueue = null;\n    this._pendingReplaceState = false;\n    this._pendingForceUpdate = false;\n\n    this._renderedComponent = null;\n\n    this._context = null;\n    this._mountOrder = 0;\n    this._topLevelWrapper = null;\n\n    // See ReactUpdates and ReactUpdateQueue.\n    this._pendingCallbacks = null;\n  },\n\n  /**\n   * Initializes the component, renders markup, and registers event listeners.\n   *\n   * @param {string} rootID DOM ID of the root node.\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @return {?string} Rendered markup to be inserted into the DOM.\n   * @final\n   * @internal\n   */\n  mountComponent: function (rootID, transaction, context) {\n    this._context = context;\n    this._mountOrder = nextMountID++;\n    this._rootNodeID = rootID;\n\n    var publicProps = this._processProps(this._currentElement.props);\n    var publicContext = this._processContext(context);\n\n    var Component = this._currentElement.type;\n\n    // Initialize the public class\n    var inst;\n    var renderedElement;\n\n    // This is a way to detect if Component is a stateless arrow function\n    // component, which is not newable. It might not be 100% reliable but is\n    // something we can do until we start detecting that Component extends\n    // React.Component. We already assume that typeof Component === 'function'.\n    var canInstantiate = ('prototype' in Component);\n\n    if (canInstantiate) {\n      if (process.env.NODE_ENV !== 'production') {\n        ReactCurrentOwner.current = this;\n        try {\n          inst = new Component(publicProps, publicContext, ReactUpdateQueue);\n        } finally {\n          ReactCurrentOwner.current = null;\n        }\n      } else {\n        inst = new Component(publicProps, publicContext, ReactUpdateQueue);\n      }\n    }\n\n    if (!canInstantiate || inst === null || inst === false || ReactElement.isValidElement(inst)) {\n      renderedElement = inst;\n      inst = new StatelessComponent(Component);\n    }\n\n    if (process.env.NODE_ENV !== 'production') {\n      // This will throw later in _renderValidatedComponent, but add an early\n      // warning now to help debugging\n      if (inst.render == null) {\n        process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`, returned ' + 'null/false from a stateless component, or tried to render an ' + 'element whose type is a function that isn\\'t a React component.', Component.displayName || Component.name || 'Component') : undefined;\n      } else {\n        // We support ES6 inheriting from React.Component, the module pattern,\n        // and stateless components, but not ES6 classes that don't extend\n        process.env.NODE_ENV !== 'production' ? warning(Component.prototype && Component.prototype.isReactComponent || !canInstantiate || !(inst instanceof Component), '%s(...): React component classes must extend React.Component.', Component.displayName || Component.name || 'Component') : undefined;\n      }\n    }\n\n    // These should be set up in the constructor, but as a convenience for\n    // simpler class abstractions, we set them up after the fact.\n    inst.props = publicProps;\n    inst.context = publicContext;\n    inst.refs = emptyObject;\n    inst.updater = ReactUpdateQueue;\n\n    this._instance = inst;\n\n    // Store a reference from the instance back to the internal representation\n    ReactInstanceMap.set(inst, this);\n\n    if (process.env.NODE_ENV !== 'production') {\n      // Since plain JS classes are defined without any special initialization\n      // logic, we can not catch common errors early. Therefore, we have to\n      // catch them here, at initialization time, instead.\n      process.env.NODE_ENV !== 'production' ? warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentShouldUpdate !== 'function', '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', this.getName() || 'A component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : undefined;\n    }\n\n    var initialState = inst.state;\n    if (initialState === undefined) {\n      inst.state = initialState = null;\n    }\n    !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined;\n\n    this._pendingStateQueue = null;\n    this._pendingReplaceState = false;\n    this._pendingForceUpdate = false;\n\n    if (inst.componentWillMount) {\n      inst.componentWillMount();\n      // When mounting, calls to `setState` by `componentWillMount` will set\n      // `this._pendingStateQueue` without triggering a re-render.\n      if (this._pendingStateQueue) {\n        inst.state = this._processPendingState(inst.props, inst.context);\n      }\n    }\n\n    // If not a stateless component, we now render\n    if (renderedElement === undefined) {\n      renderedElement = this._renderValidatedComponent();\n    }\n\n    this._renderedComponent = this._instantiateReactComponent(renderedElement);\n\n    var markup = ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, this._processChildContext(context));\n    if (inst.componentDidMount) {\n      transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);\n    }\n\n    return markup;\n  },\n\n  /**\n   * Releases any resources allocated by `mountComponent`.\n   *\n   * @final\n   * @internal\n   */\n  unmountComponent: function () {\n    var inst = this._instance;\n\n    if (inst.componentWillUnmount) {\n      inst.componentWillUnmount();\n    }\n\n    ReactReconciler.unmountComponent(this._renderedComponent);\n    this._renderedComponent = null;\n    this._instance = null;\n\n    // Reset pending fields\n    // Even if this component is scheduled for another update in ReactUpdates,\n    // it would still be ignored because these fields are reset.\n    this._pendingStateQueue = null;\n    this._pendingReplaceState = false;\n    this._pendingForceUpdate = false;\n    this._pendingCallbacks = null;\n    this._pendingElement = null;\n\n    // These fields do not really need to be reset since this object is no\n    // longer accessible.\n    this._context = null;\n    this._rootNodeID = null;\n    this._topLevelWrapper = null;\n\n    // Delete the reference from the instance to this internal representation\n    // which allow the internals to be properly cleaned up even if the user\n    // leaks a reference to the public instance.\n    ReactInstanceMap.remove(inst);\n\n    // Some existing components rely on inst.props even after they've been\n    // destroyed (in event handlers).\n    // TODO: inst.props = null;\n    // TODO: inst.state = null;\n    // TODO: inst.context = null;\n  },\n\n  /**\n   * Filters the context object to only contain keys specified in\n   * `contextTypes`\n   *\n   * @param {object} context\n   * @return {?object}\n   * @private\n   */\n  _maskContext: function (context) {\n    var maskedContext = null;\n    var Component = this._currentElement.type;\n    var contextTypes = Component.contextTypes;\n    if (!contextTypes) {\n      return emptyObject;\n    }\n    maskedContext = {};\n    for (var contextName in contextTypes) {\n      maskedContext[contextName] = context[contextName];\n    }\n    return maskedContext;\n  },\n\n  /**\n   * Filters the context object to only contain keys specified in\n   * `contextTypes`, and asserts that they are valid.\n   *\n   * @param {object} context\n   * @return {?object}\n   * @private\n   */\n  _processContext: function (context) {\n    var maskedContext = this._maskContext(context);\n    if (process.env.NODE_ENV !== 'production') {\n      var Component = this._currentElement.type;\n      if (Component.contextTypes) {\n        this._checkPropTypes(Component.contextTypes, maskedContext, ReactPropTypeLocations.context);\n      }\n    }\n    return maskedContext;\n  },\n\n  /**\n   * @param {object} currentContext\n   * @return {object}\n   * @private\n   */\n  _processChildContext: function (currentContext) {\n    var Component = this._currentElement.type;\n    var inst = this._instance;\n    var childContext = inst.getChildContext && inst.getChildContext();\n    if (childContext) {\n      !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined;\n      if (process.env.NODE_ENV !== 'production') {\n        this._checkPropTypes(Component.childContextTypes, childContext, ReactPropTypeLocations.childContext);\n      }\n      for (var name in childContext) {\n        !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key \"%s\" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : invariant(false) : undefined;\n      }\n      return assign({}, currentContext, childContext);\n    }\n    return currentContext;\n  },\n\n  /**\n   * Processes props by setting default values for unspecified props and\n   * asserting that the props are valid. Does not mutate its argument; returns\n   * a new props object with defaults merged in.\n   *\n   * @param {object} newProps\n   * @return {object}\n   * @private\n   */\n  _processProps: function (newProps) {\n    if (process.env.NODE_ENV !== 'production') {\n      var Component = this._currentElement.type;\n      if (Component.propTypes) {\n        this._checkPropTypes(Component.propTypes, newProps, ReactPropTypeLocations.prop);\n      }\n    }\n    return newProps;\n  },\n\n  /**\n   * Assert that the props are valid\n   *\n   * @param {object} propTypes Map of prop name to a ReactPropType\n   * @param {object} props\n   * @param {string} location e.g. \"prop\", \"context\", \"child context\"\n   * @private\n   */\n  _checkPropTypes: function (propTypes, props, location) {\n    // TODO: Stop validating prop types here and only use the element\n    // validation.\n    var componentName = this.getName();\n    for (var propName in propTypes) {\n      if (propTypes.hasOwnProperty(propName)) {\n        var error;\n        try {\n          // This is intentionally an invariant that gets caught. It's the same\n          // behavior as without this statement except with a better message.\n          !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually ' + 'from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : undefined;\n          error = propTypes[propName](props, propName, componentName, location);\n        } catch (ex) {\n          error = ex;\n        }\n        if (error instanceof Error) {\n          // We may want to extend this logic for similar errors in\n          // top-level render calls, so I'm abstracting it away into\n          // a function to minimize refactoring in the future\n          var addendum = getDeclarationErrorAddendum(this);\n\n          if (location === ReactPropTypeLocations.prop) {\n            // Preface gives us something to blacklist in warning module\n            process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Composite propType: %s%s', error.message, addendum) : undefined;\n          } else {\n            process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Context Types: %s%s', error.message, addendum) : undefined;\n          }\n        }\n      }\n    }\n  },\n\n  receiveComponent: function (nextElement, transaction, nextContext) {\n    var prevElement = this._currentElement;\n    var prevContext = this._context;\n\n    this._pendingElement = null;\n\n    this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext);\n  },\n\n  /**\n   * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`\n   * is set, update the component.\n   *\n   * @param {ReactReconcileTransaction} transaction\n   * @internal\n   */\n  performUpdateIfNecessary: function (transaction) {\n    if (this._pendingElement != null) {\n      ReactReconciler.receiveComponent(this, this._pendingElement || this._currentElement, transaction, this._context);\n    }\n\n    if (this._pendingStateQueue !== null || this._pendingForceUpdate) {\n      this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context);\n    }\n  },\n\n  /**\n   * Perform an update to a mounted component. The componentWillReceiveProps and\n   * shouldComponentUpdate methods are called, then (assuming the update isn't\n   * skipped) the remaining update lifecycle methods are called and the DOM\n   * representation is updated.\n   *\n   * By default, this implements React's rendering and reconciliation algorithm.\n   * Sophisticated clients may wish to override this.\n   *\n   * @param {ReactReconcileTransaction} transaction\n   * @param {ReactElement} prevParentElement\n   * @param {ReactElement} nextParentElement\n   * @internal\n   * @overridable\n   */\n  updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) {\n    var inst = this._instance;\n\n    var nextContext = this._context === nextUnmaskedContext ? inst.context : this._processContext(nextUnmaskedContext);\n    var nextProps;\n\n    // Distinguish between a props update versus a simple state update\n    if (prevParentElement === nextParentElement) {\n      // Skip checking prop types again -- we don't read inst.props to avoid\n      // warning for DOM component props in this upgrade\n      nextProps = nextParentElement.props;\n    } else {\n      nextProps = this._processProps(nextParentElement.props);\n      // An update here will schedule an update but immediately set\n      // _pendingStateQueue which will ensure that any state updates gets\n      // immediately reconciled instead of waiting for the next batch.\n\n      if (inst.componentWillReceiveProps) {\n        inst.componentWillReceiveProps(nextProps, nextContext);\n      }\n    }\n\n    var nextState = this._processPendingState(nextProps, nextContext);\n\n    var shouldUpdate = this._pendingForceUpdate || !inst.shouldComponentUpdate || inst.shouldComponentUpdate(nextProps, nextState, nextContext);\n\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(typeof shouldUpdate !== 'undefined', '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : undefined;\n    }\n\n    if (shouldUpdate) {\n      this._pendingForceUpdate = false;\n      // Will set `this.props`, `this.state` and `this.context`.\n      this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext);\n    } else {\n      // If it's determined that a component should not update, we still want\n      // to set props and state but we shortcut the rest of the update.\n      this._currentElement = nextParentElement;\n      this._context = nextUnmaskedContext;\n      inst.props = nextProps;\n      inst.state = nextState;\n      inst.context = nextContext;\n    }\n  },\n\n  _processPendingState: function (props, context) {\n    var inst = this._instance;\n    var queue = this._pendingStateQueue;\n    var replace = this._pendingReplaceState;\n    this._pendingReplaceState = false;\n    this._pendingStateQueue = null;\n\n    if (!queue) {\n      return inst.state;\n    }\n\n    if (replace && queue.length === 1) {\n      return queue[0];\n    }\n\n    var nextState = assign({}, replace ? queue[0] : inst.state);\n    for (var i = replace ? 1 : 0; i < queue.length; i++) {\n      var partial = queue[i];\n      assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial);\n    }\n\n    return nextState;\n  },\n\n  /**\n   * Merges new props and state, notifies delegate methods of update and\n   * performs update.\n   *\n   * @param {ReactElement} nextElement Next element\n   * @param {object} nextProps Next public object to set as properties.\n   * @param {?object} nextState Next object to set as state.\n   * @param {?object} nextContext Next public object to set as context.\n   * @param {ReactReconcileTransaction} transaction\n   * @param {?object} unmaskedContext\n   * @private\n   */\n  _performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) {\n    var inst = this._instance;\n\n    var hasComponentDidUpdate = Boolean(inst.componentDidUpdate);\n    var prevProps;\n    var prevState;\n    var prevContext;\n    if (hasComponentDidUpdate) {\n      prevProps = inst.props;\n      prevState = inst.state;\n      prevContext = inst.context;\n    }\n\n    if (inst.componentWillUpdate) {\n      inst.componentWillUpdate(nextProps, nextState, nextContext);\n    }\n\n    this._currentElement = nextElement;\n    this._context = unmaskedContext;\n    inst.props = nextProps;\n    inst.state = nextState;\n    inst.context = nextContext;\n\n    this._updateRenderedComponent(transaction, unmaskedContext);\n\n    if (hasComponentDidUpdate) {\n      transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst);\n    }\n  },\n\n  /**\n   * Call the component's `render` method and update the DOM accordingly.\n   *\n   * @param {ReactReconcileTransaction} transaction\n   * @internal\n   */\n  _updateRenderedComponent: function (transaction, context) {\n    var prevComponentInstance = this._renderedComponent;\n    var prevRenderedElement = prevComponentInstance._currentElement;\n    var nextRenderedElement = this._renderValidatedComponent();\n    if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {\n      ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context));\n    } else {\n      // These two IDs are actually the same! But nothing should rely on that.\n      var thisID = this._rootNodeID;\n      var prevComponentID = prevComponentInstance._rootNodeID;\n      ReactReconciler.unmountComponent(prevComponentInstance);\n\n      this._renderedComponent = this._instantiateReactComponent(nextRenderedElement);\n      var nextMarkup = ReactReconciler.mountComponent(this._renderedComponent, thisID, transaction, this._processChildContext(context));\n      this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup);\n    }\n  },\n\n  /**\n   * @protected\n   */\n  _replaceNodeWithMarkupByID: function (prevComponentID, nextMarkup) {\n    ReactComponentEnvironment.replaceNodeWithMarkupByID(prevComponentID, nextMarkup);\n  },\n\n  /**\n   * @protected\n   */\n  _renderValidatedComponentWithoutOwnerOrContext: function () {\n    var inst = this._instance;\n    var renderedComponent = inst.render();\n    if (process.env.NODE_ENV !== 'production') {\n      // We allow auto-mocks to proceed as if they're returning null.\n      if (typeof renderedComponent === 'undefined' && inst.render._isMockFunction) {\n        // This is probably bad practice. Consider warning here and\n        // deprecating this convenience.\n        renderedComponent = null;\n      }\n    }\n\n    return renderedComponent;\n  },\n\n  /**\n   * @private\n   */\n  _renderValidatedComponent: function () {\n    var renderedComponent;\n    ReactCurrentOwner.current = this;\n    try {\n      renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext();\n    } finally {\n      ReactCurrentOwner.current = null;\n    }\n    !(\n    // TODO: An `isValidNode` function would probably be more appropriate\n    renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined;\n    return renderedComponent;\n  },\n\n  /**\n   * Lazily allocates the refs object and stores `component` as `ref`.\n   *\n   * @param {string} ref Reference name.\n   * @param {component} component Component to store as `ref`.\n   * @final\n   * @private\n   */\n  attachRef: function (ref, component) {\n    var inst = this.getPublicInstance();\n    !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : invariant(false) : undefined;\n    var publicComponentInstance = component.getPublicInstance();\n    if (process.env.NODE_ENV !== 'production') {\n      var componentName = component && component.getName ? component.getName() : 'a component';\n      process.env.NODE_ENV !== 'production' ? warning(publicComponentInstance != null, 'Stateless function components cannot be given refs ' + '(See ref \"%s\" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : undefined;\n    }\n    var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs;\n    refs[ref] = publicComponentInstance;\n  },\n\n  /**\n   * Detaches a reference name.\n   *\n   * @param {string} ref Name to dereference.\n   * @final\n   * @private\n   */\n  detachRef: function (ref) {\n    var refs = this.getPublicInstance().refs;\n    delete refs[ref];\n  },\n\n  /**\n   * Get a text description of the component that can be used to identify it\n   * in error messages.\n   * @return {string} The name or null.\n   * @internal\n   */\n  getName: function () {\n    var type = this._currentElement.type;\n    var constructor = this._instance && this._instance.constructor;\n    return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null;\n  },\n\n  /**\n   * Get the publicly accessible representation of this component - i.e. what\n   * is exposed by refs and returned by render. Can be null for stateless\n   * components.\n   *\n   * @return {ReactComponent} the public component instance.\n   * @internal\n   */\n  getPublicInstance: function () {\n    var inst = this._instance;\n    if (inst instanceof StatelessComponent) {\n      return null;\n    }\n    return inst;\n  },\n\n  // Stub\n  _instantiateReactComponent: null\n\n};\n\nReactPerf.measureMethods(ReactCompositeComponentMixin, 'ReactCompositeComponent', {\n  mountComponent: 'mountComponent',\n  updateComponent: 'updateComponent',\n  _renderValidatedComponent: '_renderValidatedComponent'\n});\n\nvar ReactCompositeComponent = {\n\n  Mixin: ReactCompositeComponentMixin\n\n};\n\nmodule.exports = ReactCompositeComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactCompositeComponent.js\n ** module id = 59\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactComponentEnvironment\n */\n\n'use strict';\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar injected = false;\n\nvar ReactComponentEnvironment = {\n\n  /**\n   * Optionally injectable environment dependent cleanup hook. (server vs.\n   * browser etc). Example: A browser system caches DOM nodes based on component\n   * ID and must remove that cache entry when this instance is unmounted.\n   */\n  unmountIDFromEnvironment: null,\n\n  /**\n   * Optionally injectable hook for swapping out mount images in the middle of\n   * the tree.\n   */\n  replaceNodeWithMarkupByID: null,\n\n  /**\n   * Optionally injectable hook for processing a queue of child updates. Will\n   * later move into MultiChildComponents.\n   */\n  processChildrenUpdates: null,\n\n  injection: {\n    injectEnvironment: function (environment) {\n      !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : invariant(false) : undefined;\n      ReactComponentEnvironment.unmountIDFromEnvironment = environment.unmountIDFromEnvironment;\n      ReactComponentEnvironment.replaceNodeWithMarkupByID = environment.replaceNodeWithMarkupByID;\n      ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates;\n      injected = true;\n    }\n  }\n\n};\n\nmodule.exports = ReactComponentEnvironment;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactComponentEnvironment.js\n ** module id = 60\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactPropTypeLocations\n */\n\n'use strict';\n\nvar keyMirror = require('fbjs/lib/keyMirror');\n\nvar ReactPropTypeLocations = keyMirror({\n  prop: null,\n  context: null,\n  childContext: null\n});\n\nmodule.exports = ReactPropTypeLocations;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactPropTypeLocations.js\n ** module id = 61\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactPropTypeLocationNames\n */\n\n'use strict';\n\nvar ReactPropTypeLocationNames = {};\n\nif (process.env.NODE_ENV !== 'production') {\n  ReactPropTypeLocationNames = {\n    prop: 'prop',\n    context: 'context',\n    childContext: 'child context'\n  };\n}\n\nmodule.exports = ReactPropTypeLocationNames;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactPropTypeLocationNames.js\n ** module id = 62\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule shouldUpdateReactComponent\n * @typechecks static-only\n */\n\n'use strict';\n\n/**\n * Given a `prevElement` and `nextElement`, determines if the existing\n * instance should be updated as opposed to being destroyed or replaced by a new\n * instance. Both arguments are elements. This ensures that this logic can\n * operate on stateless trees without any backing instance.\n *\n * @param {?object} prevElement\n * @param {?object} nextElement\n * @return {boolean} True if the existing instance should be updated.\n * @protected\n */\nfunction shouldUpdateReactComponent(prevElement, nextElement) {\n  var prevEmpty = prevElement === null || prevElement === false;\n  var nextEmpty = nextElement === null || nextElement === false;\n  if (prevEmpty || nextEmpty) {\n    return prevEmpty === nextEmpty;\n  }\n\n  var prevType = typeof prevElement;\n  var nextType = typeof nextElement;\n  if (prevType === 'string' || prevType === 'number') {\n    return nextType === 'string' || nextType === 'number';\n  } else {\n    return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key;\n  }\n  return false;\n}\n\nmodule.exports = shouldUpdateReactComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/shouldUpdateReactComponent.js\n ** module id = 63\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactEmptyComponent\n */\n\n'use strict';\n\nvar ReactElement = require('./ReactElement');\nvar ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry');\nvar ReactReconciler = require('./ReactReconciler');\n\nvar assign = require('./Object.assign');\n\nvar placeholderElement;\n\nvar ReactEmptyComponentInjection = {\n  injectEmptyComponent: function (component) {\n    placeholderElement = ReactElement.createElement(component);\n  }\n};\n\nvar ReactEmptyComponent = function (instantiate) {\n  this._currentElement = null;\n  this._rootNodeID = null;\n  this._renderedComponent = instantiate(placeholderElement);\n};\nassign(ReactEmptyComponent.prototype, {\n  construct: function (element) {},\n  mountComponent: function (rootID, transaction, context) {\n    ReactEmptyComponentRegistry.registerNullComponentID(rootID);\n    this._rootNodeID = rootID;\n    return ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, context);\n  },\n  receiveComponent: function () {},\n  unmountComponent: function (rootID, transaction, context) {\n    ReactReconciler.unmountComponent(this._renderedComponent);\n    ReactEmptyComponentRegistry.deregisterNullComponentID(this._rootNodeID);\n    this._rootNodeID = null;\n    this._renderedComponent = null;\n  }\n});\n\nReactEmptyComponent.injection = ReactEmptyComponentInjection;\n\nmodule.exports = ReactEmptyComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactEmptyComponent.js\n ** module id = 64\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactNativeComponent\n */\n\n'use strict';\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\n\nvar autoGenerateWrapperClass = null;\nvar genericComponentClass = null;\n// This registry keeps track of wrapper classes around native tags.\nvar tagToComponentClass = {};\nvar textComponentClass = null;\n\nvar ReactNativeComponentInjection = {\n  // This accepts a class that receives the tag string. This is a catch all\n  // that can render any kind of tag.\n  injectGenericComponentClass: function (componentClass) {\n    genericComponentClass = componentClass;\n  },\n  // This accepts a text component class that takes the text string to be\n  // rendered as props.\n  injectTextComponentClass: function (componentClass) {\n    textComponentClass = componentClass;\n  },\n  // This accepts a keyed object with classes as values. Each key represents a\n  // tag. That particular tag will use this class instead of the generic one.\n  injectComponentClasses: function (componentClasses) {\n    assign(tagToComponentClass, componentClasses);\n  }\n};\n\n/**\n * Get a composite component wrapper class for a specific tag.\n *\n * @param {ReactElement} element The tag for which to get the class.\n * @return {function} The React class constructor function.\n */\nfunction getComponentClassForElement(element) {\n  if (typeof element.type === 'function') {\n    return element.type;\n  }\n  var tag = element.type;\n  var componentClass = tagToComponentClass[tag];\n  if (componentClass == null) {\n    tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag);\n  }\n  return componentClass;\n}\n\n/**\n * Get a native internal component class for a specific tag.\n *\n * @param {ReactElement} element The element to create.\n * @return {function} The internal class constructor function.\n */\nfunction createInternalComponent(element) {\n  !genericComponentClass ? process.env.NODE_ENV !== 'production' ? invariant(false, 'There is no registered component for the tag %s', element.type) : invariant(false) : undefined;\n  return new genericComponentClass(element.type, element.props);\n}\n\n/**\n * @param {ReactText} text\n * @return {ReactComponent}\n */\nfunction createInstanceForText(text) {\n  return new textComponentClass(text);\n}\n\n/**\n * @param {ReactComponent} component\n * @return {boolean}\n */\nfunction isTextComponent(component) {\n  return component instanceof textComponentClass;\n}\n\nvar ReactNativeComponent = {\n  getComponentClassForElement: getComponentClassForElement,\n  createInternalComponent: createInternalComponent,\n  createInstanceForText: createInstanceForText,\n  isTextComponent: isTextComponent,\n  injection: ReactNativeComponentInjection\n};\n\nmodule.exports = ReactNativeComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactNativeComponent.js\n ** module id = 65\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule setInnerHTML\n */\n\n/* globals MSApp */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n\nvar WHITESPACE_TEST = /^[ \\r\\n\\t\\f]/;\nvar NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \\r\\n\\t\\f\\/>]/;\n\n/**\n * Set the innerHTML property of a node, ensuring that whitespace is preserved\n * even in IE8.\n *\n * @param {DOMElement} node\n * @param {string} html\n * @internal\n */\nvar setInnerHTML = function (node, html) {\n  node.innerHTML = html;\n};\n\n// Win8 apps: Allow all html to be inserted\nif (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {\n  setInnerHTML = function (node, html) {\n    MSApp.execUnsafeLocalFunction(function () {\n      node.innerHTML = html;\n    });\n  };\n}\n\nif (ExecutionEnvironment.canUseDOM) {\n  // IE8: When updating a just created node with innerHTML only leading\n  // whitespace is removed. When updating an existing node with innerHTML\n  // whitespace in root TextNodes is also collapsed.\n  // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html\n\n  // Feature detection; only IE8 is known to behave improperly like this.\n  var testElement = document.createElement('div');\n  testElement.innerHTML = ' ';\n  if (testElement.innerHTML === '') {\n    setInnerHTML = function (node, html) {\n      // Magic theory: IE8 supposedly differentiates between added and updated\n      // nodes when processing innerHTML, innerHTML on updated nodes suffers\n      // from worse whitespace behavior. Re-adding a node like this triggers\n      // the initial and more favorable whitespace behavior.\n      // TODO: What to do on a detached node?\n      if (node.parentNode) {\n        node.parentNode.replaceChild(node, node);\n      }\n\n      // We also implement a workaround for non-visible tags disappearing into\n      // thin air on IE8, this only happens if there is no visible text\n      // in-front of the non-visible tags. Piggyback on the whitespace fix\n      // and simply check if any non-visible tags appear in the source.\n      if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) {\n        // Recover leading whitespace by temporarily prepending any character.\n        // \\uFEFF has the potential advantage of being zero-width/invisible.\n        // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode\n        // in hopes that this is preserved even if \"\\uFEFF\" is transformed to\n        // the actual Unicode character (by Babel, for example).\n        // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216\n        node.innerHTML = String.fromCharCode(0xFEFF) + html;\n\n        // deleteData leaves an empty `TextNode` which offsets the index of all\n        // children. Definitely want to avoid this.\n        var textNode = node.firstChild;\n        if (textNode.data.length === 1) {\n          node.removeChild(textNode);\n        } else {\n          textNode.deleteData(0, 1);\n        }\n      } else {\n        node.innerHTML = html;\n      }\n    };\n  }\n}\n\nmodule.exports = setInnerHTML;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/setInnerHTML.js\n ** module id = 66\n ** module chunks = 0\n **/","/**\n * Copyright 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule validateDOMNesting\n */\n\n'use strict';\n\nvar assign = require('./Object.assign');\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar warning = require('fbjs/lib/warning');\n\nvar validateDOMNesting = emptyFunction;\n\nif (process.env.NODE_ENV !== 'production') {\n  // This validation code was written based on the HTML5 parsing spec:\n  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope\n  //\n  // Note: this does not catch all invalid nesting, nor does it try to (as it's\n  // not clear what practical benefit doing so provides); instead, we warn only\n  // for cases where the parser will give a parse tree differing from what React\n  // intended. For example, <b><div></div></b> is invalid but we don't warn\n  // because it still parses correctly; we do warn for other cases like nested\n  // <p> tags where the beginning of the second element implicitly closes the\n  // first, causing a confusing mess.\n\n  // https://html.spec.whatwg.org/multipage/syntax.html#special\n  var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'];\n\n  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope\n  var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',\n\n  // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point\n  // TODO: Distinguish by namespace here -- for <title>, including it here\n  // errs on the side of fewer warnings\n  'foreignObject', 'desc', 'title'];\n\n  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope\n  var buttonScopeTags = inScopeTags.concat(['button']);\n\n  // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags\n  var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];\n\n  var emptyAncestorInfo = {\n    parentTag: null,\n\n    formTag: null,\n    aTagInScope: null,\n    buttonTagInScope: null,\n    nobrTagInScope: null,\n    pTagInButtonScope: null,\n\n    listItemTagAutoclosing: null,\n    dlItemTagAutoclosing: null\n  };\n\n  var updatedAncestorInfo = function (oldInfo, tag, instance) {\n    var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);\n    var info = { tag: tag, instance: instance };\n\n    if (inScopeTags.indexOf(tag) !== -1) {\n      ancestorInfo.aTagInScope = null;\n      ancestorInfo.buttonTagInScope = null;\n      ancestorInfo.nobrTagInScope = null;\n    }\n    if (buttonScopeTags.indexOf(tag) !== -1) {\n      ancestorInfo.pTagInButtonScope = null;\n    }\n\n    // See rules for 'li', 'dd', 'dt' start tags in\n    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody\n    if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {\n      ancestorInfo.listItemTagAutoclosing = null;\n      ancestorInfo.dlItemTagAutoclosing = null;\n    }\n\n    ancestorInfo.parentTag = info;\n\n    if (tag === 'form') {\n      ancestorInfo.formTag = info;\n    }\n    if (tag === 'a') {\n      ancestorInfo.aTagInScope = info;\n    }\n    if (tag === 'button') {\n      ancestorInfo.buttonTagInScope = info;\n    }\n    if (tag === 'nobr') {\n      ancestorInfo.nobrTagInScope = info;\n    }\n    if (tag === 'p') {\n      ancestorInfo.pTagInButtonScope = info;\n    }\n    if (tag === 'li') {\n      ancestorInfo.listItemTagAutoclosing = info;\n    }\n    if (tag === 'dd' || tag === 'dt') {\n      ancestorInfo.dlItemTagAutoclosing = info;\n    }\n\n    return ancestorInfo;\n  };\n\n  /**\n   * Returns whether\n   */\n  var isTagValidWithParent = function (tag, parentTag) {\n    // First, let's check if we're in an unusual parsing mode...\n    switch (parentTag) {\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect\n      case 'select':\n        return tag === 'option' || tag === 'optgroup' || tag === '#text';\n      case 'optgroup':\n        return tag === 'option' || tag === '#text';\n      // Strictly speaking, seeing an <option> doesn't mean we're in a <select>\n      // but\n      case 'option':\n        return tag === '#text';\n\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption\n      // No special behavior since these rules fall back to \"in body\" mode for\n      // all except special table nodes which cause bad parsing behavior anyway.\n\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr\n      case 'tr':\n        return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';\n\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody\n      case 'tbody':\n      case 'thead':\n      case 'tfoot':\n        return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';\n\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup\n      case 'colgroup':\n        return tag === 'col' || tag === 'template';\n\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable\n      case 'table':\n        return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';\n\n      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead\n      case 'head':\n        return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';\n\n      // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element\n      case 'html':\n        return tag === 'head' || tag === 'body';\n    }\n\n    // Probably in the \"in body\" parsing mode, so we outlaw only tag combos\n    // where the parsing rules cause implicit opens or closes to be added.\n    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody\n    switch (tag) {\n      case 'h1':\n      case 'h2':\n      case 'h3':\n      case 'h4':\n      case 'h5':\n      case 'h6':\n        return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';\n\n      case 'rp':\n      case 'rt':\n        return impliedEndTags.indexOf(parentTag) === -1;\n\n      case 'caption':\n      case 'col':\n      case 'colgroup':\n      case 'frame':\n      case 'head':\n      case 'tbody':\n      case 'td':\n      case 'tfoot':\n      case 'th':\n      case 'thead':\n      case 'tr':\n        // These tags are only valid with a few parents that have special child\n        // parsing rules -- if we're down here, then none of those matched and\n        // so we allow it only if we don't know what the parent is, as all other\n        // cases are invalid.\n        return parentTag == null;\n    }\n\n    return true;\n  };\n\n  /**\n   * Returns whether\n   */\n  var findInvalidAncestorForTag = function (tag, ancestorInfo) {\n    switch (tag) {\n      case 'address':\n      case 'article':\n      case 'aside':\n      case 'blockquote':\n      case 'center':\n      case 'details':\n      case 'dialog':\n      case 'dir':\n      case 'div':\n      case 'dl':\n      case 'fieldset':\n      case 'figcaption':\n      case 'figure':\n      case 'footer':\n      case 'header':\n      case 'hgroup':\n      case 'main':\n      case 'menu':\n      case 'nav':\n      case 'ol':\n      case 'p':\n      case 'section':\n      case 'summary':\n      case 'ul':\n\n      case 'pre':\n      case 'listing':\n\n      case 'table':\n\n      case 'hr':\n\n      case 'xmp':\n\n      case 'h1':\n      case 'h2':\n      case 'h3':\n      case 'h4':\n      case 'h5':\n      case 'h6':\n        return ancestorInfo.pTagInButtonScope;\n\n      case 'form':\n        return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;\n\n      case 'li':\n        return ancestorInfo.listItemTagAutoclosing;\n\n      case 'dd':\n      case 'dt':\n        return ancestorInfo.dlItemTagAutoclosing;\n\n      case 'button':\n        return ancestorInfo.buttonTagInScope;\n\n      case 'a':\n        // Spec says something about storing a list of markers, but it sounds\n        // equivalent to this check.\n        return ancestorInfo.aTagInScope;\n\n      case 'nobr':\n        return ancestorInfo.nobrTagInScope;\n    }\n\n    return null;\n  };\n\n  /**\n   * Given a ReactCompositeComponent instance, return a list of its recursive\n   * owners, starting at the root and ending with the instance itself.\n   */\n  var findOwnerStack = function (instance) {\n    if (!instance) {\n      return [];\n    }\n\n    var stack = [];\n    /*eslint-disable space-after-keywords */\n    do {\n      /*eslint-enable space-after-keywords */\n      stack.push(instance);\n    } while (instance = instance._currentElement._owner);\n    stack.reverse();\n    return stack;\n  };\n\n  var didWarn = {};\n\n  validateDOMNesting = function (childTag, childInstance, ancestorInfo) {\n    ancestorInfo = ancestorInfo || emptyAncestorInfo;\n    var parentInfo = ancestorInfo.parentTag;\n    var parentTag = parentInfo && parentInfo.tag;\n\n    var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;\n    var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);\n    var problematic = invalidParent || invalidAncestor;\n\n    if (problematic) {\n      var ancestorTag = problematic.tag;\n      var ancestorInstance = problematic.instance;\n\n      var childOwner = childInstance && childInstance._currentElement._owner;\n      var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner;\n\n      var childOwners = findOwnerStack(childOwner);\n      var ancestorOwners = findOwnerStack(ancestorOwner);\n\n      var minStackLen = Math.min(childOwners.length, ancestorOwners.length);\n      var i;\n\n      var deepestCommon = -1;\n      for (i = 0; i < minStackLen; i++) {\n        if (childOwners[i] === ancestorOwners[i]) {\n          deepestCommon = i;\n        } else {\n          break;\n        }\n      }\n\n      var UNKNOWN = '(unknown)';\n      var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) {\n        return inst.getName() || UNKNOWN;\n      });\n      var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) {\n        return inst.getName() || UNKNOWN;\n      });\n      var ownerInfo = [].concat(\n      // If the parent and child instances have a common owner ancestor, start\n      // with that -- otherwise we just start with the parent's owners.\n      deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag,\n      // If we're warning about an invalid (non-parent) ancestry, add '...'\n      invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > ');\n\n      var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo;\n      if (didWarn[warnKey]) {\n        return;\n      }\n      didWarn[warnKey] = true;\n\n      if (invalidParent) {\n        var info = '';\n        if (ancestorTag === 'table' && childTag === 'tr') {\n          info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';\n        }\n        process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a child of <%s>. ' + 'See %s.%s', childTag, ancestorTag, ownerInfo, info) : undefined;\n      } else {\n        process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a descendant of ' + '<%s>. See %s.', childTag, ancestorTag, ownerInfo) : undefined;\n      }\n    }\n  };\n\n  validateDOMNesting.ancestorInfoContextKey = '__validateDOMNesting_ancestorInfo$' + Math.random().toString(36).slice(2);\n\n  validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo;\n\n  // For testing\n  validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) {\n    ancestorInfo = ancestorInfo || emptyAncestorInfo;\n    var parentInfo = ancestorInfo.parentTag;\n    var parentTag = parentInfo && parentInfo.tag;\n    return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo);\n  };\n}\n\nmodule.exports = validateDOMNesting;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/validateDOMNesting.js\n ** module id = 67\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = require('./lib/React');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/react.js\n ** module id = 68\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule React\n */\n\n'use strict';\n\nvar ReactDOM = require('./ReactDOM');\nvar ReactDOMServer = require('./ReactDOMServer');\nvar ReactIsomorphic = require('./ReactIsomorphic');\n\nvar assign = require('./Object.assign');\nvar deprecated = require('./deprecated');\n\n// `version` will be added here by ReactIsomorphic.\nvar React = {};\n\nassign(React, ReactIsomorphic);\n\nassign(React, {\n  // ReactDOM\n  findDOMNode: deprecated('findDOMNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.findDOMNode),\n  render: deprecated('render', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.render),\n  unmountComponentAtNode: deprecated('unmountComponentAtNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.unmountComponentAtNode),\n\n  // ReactDOMServer\n  renderToString: deprecated('renderToString', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToString),\n  renderToStaticMarkup: deprecated('renderToStaticMarkup', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToStaticMarkup)\n});\n\nReact.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOM;\nReact.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOMServer;\n\nmodule.exports = React;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/React.js\n ** module id = 69\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOM\n */\n\n/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/\n\n'use strict';\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactDOMTextComponent = require('./ReactDOMTextComponent');\nvar ReactDefaultInjection = require('./ReactDefaultInjection');\nvar ReactInstanceHandles = require('./ReactInstanceHandles');\nvar ReactMount = require('./ReactMount');\nvar ReactPerf = require('./ReactPerf');\nvar ReactReconciler = require('./ReactReconciler');\nvar ReactUpdates = require('./ReactUpdates');\nvar ReactVersion = require('./ReactVersion');\n\nvar findDOMNode = require('./findDOMNode');\nvar renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');\nvar warning = require('fbjs/lib/warning');\n\nReactDefaultInjection.inject();\n\nvar render = ReactPerf.measure('React', 'render', ReactMount.render);\n\nvar React = {\n  findDOMNode: findDOMNode,\n  render: render,\n  unmountComponentAtNode: ReactMount.unmountComponentAtNode,\n  version: ReactVersion,\n\n  /* eslint-disable camelcase */\n  unstable_batchedUpdates: ReactUpdates.batchedUpdates,\n  unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer\n};\n\n// Inject the runtime into a devtools global hook regardless of browser.\n// Allows for debugging when the hook is injected on the page.\n/* eslint-enable camelcase */\nif (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {\n  __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({\n    CurrentOwner: ReactCurrentOwner,\n    InstanceHandles: ReactInstanceHandles,\n    Mount: ReactMount,\n    Reconciler: ReactReconciler,\n    TextComponent: ReactDOMTextComponent\n  });\n}\n\nif (process.env.NODE_ENV !== 'production') {\n  var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n  if (ExecutionEnvironment.canUseDOM && window.top === window.self) {\n\n    // First check if devtools is not installed\n    if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {\n      // If we're in Chrome or Firefox, provide a download link if not installed.\n      if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {\n        console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools');\n      }\n    }\n\n    // If we're in IE8, check to see if we are in compatibility mode and provide\n    // information on preventing compatibility mode\n    var ieCompatibilityMode = document.documentMode && document.documentMode < 8;\n\n    process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />') : undefined;\n\n    var expectedFeatures = [\n    // shims\n    Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim,\n\n    // shams\n    Object.create, Object.freeze];\n\n    for (var i = 0; i < expectedFeatures.length; i++) {\n      if (!expectedFeatures[i]) {\n        console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills');\n        break;\n      }\n    }\n  }\n}\n\nmodule.exports = React;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOM.js\n ** module id = 70\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMTextComponent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar DOMChildrenOperations = require('./DOMChildrenOperations');\nvar DOMPropertyOperations = require('./DOMPropertyOperations');\nvar ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');\nvar ReactMount = require('./ReactMount');\n\nvar assign = require('./Object.assign');\nvar escapeTextContentForBrowser = require('./escapeTextContentForBrowser');\nvar setTextContent = require('./setTextContent');\nvar validateDOMNesting = require('./validateDOMNesting');\n\n/**\n * Text nodes violate a couple assumptions that React makes about components:\n *\n *  - When mounting text into the DOM, adjacent text nodes are merged.\n *  - Text nodes cannot be assigned a React root ID.\n *\n * This component is used to wrap strings in elements so that they can undergo\n * the same reconciliation that is applied to elements.\n *\n * TODO: Investigate representing React components in the DOM with text nodes.\n *\n * @class ReactDOMTextComponent\n * @extends ReactComponent\n * @internal\n */\nvar ReactDOMTextComponent = function (props) {\n  // This constructor and its argument is currently used by mocks.\n};\n\nassign(ReactDOMTextComponent.prototype, {\n\n  /**\n   * @param {ReactText} text\n   * @internal\n   */\n  construct: function (text) {\n    // TODO: This is really a ReactText (ReactNode), not a ReactElement\n    this._currentElement = text;\n    this._stringText = '' + text;\n\n    // Properties\n    this._rootNodeID = null;\n    this._mountIndex = 0;\n  },\n\n  /**\n   * Creates the markup for this text node. This node is not intended to have\n   * any features besides containing text content.\n   *\n   * @param {string} rootID DOM ID of the root node.\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @return {string} Markup for this text node.\n   * @internal\n   */\n  mountComponent: function (rootID, transaction, context) {\n    if (process.env.NODE_ENV !== 'production') {\n      if (context[validateDOMNesting.ancestorInfoContextKey]) {\n        validateDOMNesting('span', null, context[validateDOMNesting.ancestorInfoContextKey]);\n      }\n    }\n\n    this._rootNodeID = rootID;\n    if (transaction.useCreateElement) {\n      var ownerDocument = context[ReactMount.ownerDocumentContextKey];\n      var el = ownerDocument.createElement('span');\n      DOMPropertyOperations.setAttributeForID(el, rootID);\n      // Populate node cache\n      ReactMount.getID(el);\n      setTextContent(el, this._stringText);\n      return el;\n    } else {\n      var escapedText = escapeTextContentForBrowser(this._stringText);\n\n      if (transaction.renderToStaticMarkup) {\n        // Normally we'd wrap this in a `span` for the reasons stated above, but\n        // since this is a situation where React won't take over (static pages),\n        // we can simply return the text as it is.\n        return escapedText;\n      }\n\n      return '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + escapedText + '</span>';\n    }\n  },\n\n  /**\n   * Updates this component by updating the text content.\n   *\n   * @param {ReactText} nextText The next text content\n   * @param {ReactReconcileTransaction} transaction\n   * @internal\n   */\n  receiveComponent: function (nextText, transaction) {\n    if (nextText !== this._currentElement) {\n      this._currentElement = nextText;\n      var nextStringText = '' + nextText;\n      if (nextStringText !== this._stringText) {\n        // TODO: Save this as pending props and use performUpdateIfNecessary\n        // and/or updateComponent to do the actual update for consistency with\n        // other component types?\n        this._stringText = nextStringText;\n        var node = ReactMount.getNode(this._rootNodeID);\n        DOMChildrenOperations.updateTextContent(node, nextStringText);\n      }\n    }\n  },\n\n  unmountComponent: function () {\n    ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);\n  }\n\n});\n\nmodule.exports = ReactDOMTextComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMTextComponent.js\n ** module id = 71\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule DOMChildrenOperations\n * @typechecks static-only\n */\n\n'use strict';\n\nvar Danger = require('./Danger');\nvar ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes');\nvar ReactPerf = require('./ReactPerf');\n\nvar setInnerHTML = require('./setInnerHTML');\nvar setTextContent = require('./setTextContent');\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Inserts `childNode` as a child of `parentNode` at the `index`.\n *\n * @param {DOMElement} parentNode Parent node in which to insert.\n * @param {DOMElement} childNode Child node to insert.\n * @param {number} index Index at which to insert the child.\n * @internal\n */\nfunction insertChildAt(parentNode, childNode, index) {\n  // By exploiting arrays returning `undefined` for an undefined index, we can\n  // rely exclusively on `insertBefore(node, null)` instead of also using\n  // `appendChild(node)`. However, using `undefined` is not allowed by all\n  // browsers so we must replace it with `null`.\n\n  // fix render order error in safari\n  // IE8 will throw error when index out of list size.\n  var beforeChild = index >= parentNode.childNodes.length ? null : parentNode.childNodes.item(index);\n\n  parentNode.insertBefore(childNode, beforeChild);\n}\n\n/**\n * Operations for updating with DOM children.\n */\nvar DOMChildrenOperations = {\n\n  dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,\n\n  updateTextContent: setTextContent,\n\n  /**\n   * Updates a component's children by processing a series of updates. The\n   * update configurations are each expected to have a `parentNode` property.\n   *\n   * @param {array<object>} updates List of update configurations.\n   * @param {array<string>} markupList List of markup strings.\n   * @internal\n   */\n  processUpdates: function (updates, markupList) {\n    var update;\n    // Mapping from parent IDs to initial child orderings.\n    var initialChildren = null;\n    // List of children that will be moved or removed.\n    var updatedChildren = null;\n\n    for (var i = 0; i < updates.length; i++) {\n      update = updates[i];\n      if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {\n        var updatedIndex = update.fromIndex;\n        var updatedChild = update.parentNode.childNodes[updatedIndex];\n        var parentID = update.parentID;\n\n        !updatedChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processUpdates(): Unable to find child %s of element. This ' + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + 'browser), usually due to forgetting a <tbody> when using tables, ' + 'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' + 'in an <svg> parent. Try inspecting the child nodes of the element ' + 'with React ID `%s`.', updatedIndex, parentID) : invariant(false) : undefined;\n\n        initialChildren = initialChildren || {};\n        initialChildren[parentID] = initialChildren[parentID] || [];\n        initialChildren[parentID][updatedIndex] = updatedChild;\n\n        updatedChildren = updatedChildren || [];\n        updatedChildren.push(updatedChild);\n      }\n    }\n\n    var renderedMarkup;\n    // markupList is either a list of markup or just a list of elements\n    if (markupList.length && typeof markupList[0] === 'string') {\n      renderedMarkup = Danger.dangerouslyRenderMarkup(markupList);\n    } else {\n      renderedMarkup = markupList;\n    }\n\n    // Remove updated children first so that `toIndex` is consistent.\n    if (updatedChildren) {\n      for (var j = 0; j < updatedChildren.length; j++) {\n        updatedChildren[j].parentNode.removeChild(updatedChildren[j]);\n      }\n    }\n\n    for (var k = 0; k < updates.length; k++) {\n      update = updates[k];\n      switch (update.type) {\n        case ReactMultiChildUpdateTypes.INSERT_MARKUP:\n          insertChildAt(update.parentNode, renderedMarkup[update.markupIndex], update.toIndex);\n          break;\n        case ReactMultiChildUpdateTypes.MOVE_EXISTING:\n          insertChildAt(update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex);\n          break;\n        case ReactMultiChildUpdateTypes.SET_MARKUP:\n          setInnerHTML(update.parentNode, update.content);\n          break;\n        case ReactMultiChildUpdateTypes.TEXT_CONTENT:\n          setTextContent(update.parentNode, update.content);\n          break;\n        case ReactMultiChildUpdateTypes.REMOVE_NODE:\n          // Already removed by the for-loop above.\n          break;\n      }\n    }\n  }\n\n};\n\nReactPerf.measureMethods(DOMChildrenOperations, 'DOMChildrenOperations', {\n  updateTextContent: 'updateTextContent'\n});\n\nmodule.exports = DOMChildrenOperations;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/DOMChildrenOperations.js\n ** module id = 72\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule Danger\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n\nvar createNodesFromMarkup = require('fbjs/lib/createNodesFromMarkup');\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar getMarkupWrap = require('fbjs/lib/getMarkupWrap');\nvar invariant = require('fbjs/lib/invariant');\n\nvar OPEN_TAG_NAME_EXP = /^(<[^ \\/>]+)/;\nvar RESULT_INDEX_ATTR = 'data-danger-index';\n\n/**\n * Extracts the `nodeName` from a string of markup.\n *\n * NOTE: Extracting the `nodeName` does not require a regular expression match\n * because we make assumptions about React-generated markup (i.e. there are no\n * spaces surrounding the opening tag and there is at least one attribute).\n *\n * @param {string} markup String of markup.\n * @return {string} Node name of the supplied markup.\n * @see http://jsperf.com/extract-nodename\n */\nfunction getNodeName(markup) {\n  return markup.substring(1, markup.indexOf(' '));\n}\n\nvar Danger = {\n\n  /**\n   * Renders markup into an array of nodes. The markup is expected to render\n   * into a list of root nodes. Also, the length of `resultList` and\n   * `markupList` should be the same.\n   *\n   * @param {array<string>} markupList List of markup strings to render.\n   * @return {array<DOMElement>} List of rendered nodes.\n   * @internal\n   */\n  dangerouslyRenderMarkup: function (markupList) {\n    !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString for server rendering.') : invariant(false) : undefined;\n    var nodeName;\n    var markupByNodeName = {};\n    // Group markup by `nodeName` if a wrap is necessary, else by '*'.\n    for (var i = 0; i < markupList.length; i++) {\n      !markupList[i] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Missing markup.') : invariant(false) : undefined;\n      nodeName = getNodeName(markupList[i]);\n      nodeName = getMarkupWrap(nodeName) ? nodeName : '*';\n      markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];\n      markupByNodeName[nodeName][i] = markupList[i];\n    }\n    var resultList = [];\n    var resultListAssignmentCount = 0;\n    for (nodeName in markupByNodeName) {\n      if (!markupByNodeName.hasOwnProperty(nodeName)) {\n        continue;\n      }\n      var markupListByNodeName = markupByNodeName[nodeName];\n\n      // This for-in loop skips the holes of the sparse array. The order of\n      // iteration should follow the order of assignment, which happens to match\n      // numerical index order, but we don't rely on that.\n      var resultIndex;\n      for (resultIndex in markupListByNodeName) {\n        if (markupListByNodeName.hasOwnProperty(resultIndex)) {\n          var markup = markupListByNodeName[resultIndex];\n\n          // Push the requested markup with an additional RESULT_INDEX_ATTR\n          // attribute.  If the markup does not start with a < character, it\n          // will be discarded below (with an appropriate console.error).\n          markupListByNodeName[resultIndex] = markup.replace(OPEN_TAG_NAME_EXP,\n          // This index will be parsed back out below.\n          '$1 ' + RESULT_INDEX_ATTR + '=\"' + resultIndex + '\" ');\n        }\n      }\n\n      // Render each group of markup with similar wrapping `nodeName`.\n      var renderNodes = createNodesFromMarkup(markupListByNodeName.join(''), emptyFunction // Do nothing special with <script> tags.\n      );\n\n      for (var j = 0; j < renderNodes.length; ++j) {\n        var renderNode = renderNodes[j];\n        if (renderNode.hasAttribute && renderNode.hasAttribute(RESULT_INDEX_ATTR)) {\n\n          resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);\n          renderNode.removeAttribute(RESULT_INDEX_ATTR);\n\n          !!resultList.hasOwnProperty(resultIndex) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Assigning to an already-occupied result index.') : invariant(false) : undefined;\n\n          resultList[resultIndex] = renderNode;\n\n          // This should match resultList.length and markupList.length when\n          // we're done.\n          resultListAssignmentCount += 1;\n        } else if (process.env.NODE_ENV !== 'production') {\n          console.error('Danger: Discarding unexpected node:', renderNode);\n        }\n      }\n    }\n\n    // Although resultList was populated out of order, it should now be a dense\n    // array.\n    !(resultListAssignmentCount === resultList.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Did not assign to every index of resultList.') : invariant(false) : undefined;\n\n    !(resultList.length === markupList.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Expected markup to render %s nodes, but rendered %s.', markupList.length, resultList.length) : invariant(false) : undefined;\n\n    return resultList;\n  },\n\n  /**\n   * Replaces a node with a string of markup at its current position within its\n   * parent. The markup must render into a single root node.\n   *\n   * @param {DOMElement} oldChild Child node to replace.\n   * @param {string} markup Markup to render in place of the child node.\n   * @internal\n   */\n  dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) {\n    !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 'worker thread. Make sure `window` and `document` are available ' + 'globally before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined;\n    !markup ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(false) : undefined;\n    !(oldChild.tagName.toLowerCase() !== 'html') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + '<html> node. This is because browser quirks make this unreliable ' + 'and/or slow. If you want to render to the root you must use ' + 'server rendering. See ReactDOMServer.renderToString().') : invariant(false) : undefined;\n\n    var newChild;\n    if (typeof markup === 'string') {\n      newChild = createNodesFromMarkup(markup, emptyFunction)[0];\n    } else {\n      newChild = markup;\n    }\n    oldChild.parentNode.replaceChild(newChild, oldChild);\n  }\n\n};\n\nmodule.exports = Danger;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/Danger.js\n ** module id = 73\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule createNodesFromMarkup\n * @typechecks\n */\n\n/*eslint-disable fb-www/unsafe-html*/\n\n'use strict';\n\nvar ExecutionEnvironment = require('./ExecutionEnvironment');\n\nvar createArrayFromMixed = require('./createArrayFromMixed');\nvar getMarkupWrap = require('./getMarkupWrap');\nvar invariant = require('./invariant');\n\n/**\n * Dummy container used to render all markup.\n */\nvar dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;\n\n/**\n * Pattern used by `getNodeName`.\n */\nvar nodeNamePattern = /^\\s*<(\\w+)/;\n\n/**\n * Extracts the `nodeName` of the first element in a string of markup.\n *\n * @param {string} markup String of markup.\n * @return {?string} Node name of the supplied markup.\n */\nfunction getNodeName(markup) {\n  var nodeNameMatch = markup.match(nodeNamePattern);\n  return nodeNameMatch && nodeNameMatch[1].toLowerCase();\n}\n\n/**\n * Creates an array containing the nodes rendered from the supplied markup. The\n * optionally supplied `handleScript` function will be invoked once for each\n * <script> element that is rendered. If no `handleScript` function is supplied,\n * an exception is thrown if any <script> elements are rendered.\n *\n * @param {string} markup A string of valid HTML markup.\n * @param {?function} handleScript Invoked once for each rendered <script>.\n * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.\n */\nfunction createNodesFromMarkup(markup, handleScript) {\n  var node = dummyNode;\n  !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : undefined;\n  var nodeName = getNodeName(markup);\n\n  var wrap = nodeName && getMarkupWrap(nodeName);\n  if (wrap) {\n    node.innerHTML = wrap[1] + markup + wrap[2];\n\n    var wrapDepth = wrap[0];\n    while (wrapDepth--) {\n      node = node.lastChild;\n    }\n  } else {\n    node.innerHTML = markup;\n  }\n\n  var scripts = node.getElementsByTagName('script');\n  if (scripts.length) {\n    !handleScript ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : undefined;\n    createArrayFromMixed(scripts).forEach(handleScript);\n  }\n\n  var nodes = createArrayFromMixed(node.childNodes);\n  while (node.lastChild) {\n    node.removeChild(node.lastChild);\n  }\n  return nodes;\n}\n\nmodule.exports = createNodesFromMarkup;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/createNodesFromMarkup.js\n ** module id = 74\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule createArrayFromMixed\n * @typechecks\n */\n\n'use strict';\n\nvar toArray = require('./toArray');\n\n/**\n * Perform a heuristic test to determine if an object is \"array-like\".\n *\n *   A monk asked Joshu, a Zen master, \"Has a dog Buddha nature?\"\n *   Joshu replied: \"Mu.\"\n *\n * This function determines if its argument has \"array nature\": it returns\n * true if the argument is an actual array, an `arguments' object, or an\n * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).\n *\n * It will return false for other array-like objects like Filelist.\n *\n * @param {*} obj\n * @return {boolean}\n */\nfunction hasArrayNature(obj) {\n  return(\n    // not null/false\n    !!obj && (\n    // arrays are objects, NodeLists are functions in Safari\n    typeof obj == 'object' || typeof obj == 'function') &&\n    // quacks like an array\n    'length' in obj &&\n    // not window\n    !('setInterval' in obj) &&\n    // no DOM node should be considered an array-like\n    // a 'select' element has 'length' and 'item' properties on IE8\n    typeof obj.nodeType != 'number' && (\n    // a real array\n    Array.isArray(obj) ||\n    // arguments\n    'callee' in obj ||\n    // HTMLCollection/NodeList\n    'item' in obj)\n  );\n}\n\n/**\n * Ensure that the argument is an array by wrapping it in an array if it is not.\n * Creates a copy of the argument if it is already an array.\n *\n * This is mostly useful idiomatically:\n *\n *   var createArrayFromMixed = require('createArrayFromMixed');\n *\n *   function takesOneOrMoreThings(things) {\n *     things = createArrayFromMixed(things);\n *     ...\n *   }\n *\n * This allows you to treat `things' as an array, but accept scalars in the API.\n *\n * If you need to convert an array-like object, like `arguments`, into an array\n * use toArray instead.\n *\n * @param {*} obj\n * @return {array}\n */\nfunction createArrayFromMixed(obj) {\n  if (!hasArrayNature(obj)) {\n    return [obj];\n  } else if (Array.isArray(obj)) {\n    return obj.slice();\n  } else {\n    return toArray(obj);\n  }\n}\n\nmodule.exports = createArrayFromMixed;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/createArrayFromMixed.js\n ** module id = 75\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule toArray\n * @typechecks\n */\n\n'use strict';\n\nvar invariant = require('./invariant');\n\n/**\n * Convert array-like objects to arrays.\n *\n * This API assumes the caller knows the contents of the data type. For less\n * well defined inputs use createArrayFromMixed.\n *\n * @param {object|function|filelist} obj\n * @return {array}\n */\nfunction toArray(obj) {\n  var length = obj.length;\n\n  // Some browse builtin objects can report typeof 'function' (e.g. NodeList in\n  // old versions of Safari).\n  !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : undefined;\n\n  !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : undefined;\n\n  !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : undefined;\n\n  // Old IE doesn't give collections access to hasOwnProperty. Assume inputs\n  // without method will throw during the slice call and skip straight to the\n  // fallback.\n  if (obj.hasOwnProperty) {\n    try {\n      return Array.prototype.slice.call(obj);\n    } catch (e) {\n      // IE < 9 does not support Array#slice on collections objects\n    }\n  }\n\n  // Fall back to copying key by key. This assumes all keys have a value,\n  // so will not preserve sparsely populated inputs.\n  var ret = Array(length);\n  for (var ii = 0; ii < length; ii++) {\n    ret[ii] = obj[ii];\n  }\n  return ret;\n}\n\nmodule.exports = toArray;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/toArray.js\n ** module id = 76\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getMarkupWrap\n */\n\n/*eslint-disable fb-www/unsafe-html */\n\n'use strict';\n\nvar ExecutionEnvironment = require('./ExecutionEnvironment');\n\nvar invariant = require('./invariant');\n\n/**\n * Dummy container used to detect which wraps are necessary.\n */\nvar dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;\n\n/**\n * Some browsers cannot use `innerHTML` to render certain elements standalone,\n * so we wrap them, render the wrapped nodes, then extract the desired node.\n *\n * In IE8, certain elements cannot render alone, so wrap all elements ('*').\n */\n\nvar shouldWrap = {};\n\nvar selectWrap = [1, '<select multiple=\"true\">', '</select>'];\nvar tableWrap = [1, '<table>', '</table>'];\nvar trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];\n\nvar svgWrap = [1, '<svg xmlns=\"http://www.w3.org/2000/svg\">', '</svg>'];\n\nvar markupWrap = {\n  '*': [1, '?<div>', '</div>'],\n\n  'area': [1, '<map>', '</map>'],\n  'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],\n  'legend': [1, '<fieldset>', '</fieldset>'],\n  'param': [1, '<object>', '</object>'],\n  'tr': [2, '<table><tbody>', '</tbody></table>'],\n\n  'optgroup': selectWrap,\n  'option': selectWrap,\n\n  'caption': tableWrap,\n  'colgroup': tableWrap,\n  'tbody': tableWrap,\n  'tfoot': tableWrap,\n  'thead': tableWrap,\n\n  'td': trWrap,\n  'th': trWrap\n};\n\n// Initialize the SVG elements since we know they'll always need to be wrapped\n// consistently. If they are created inside a <div> they will be initialized in\n// the wrong namespace (and will not display).\nvar svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan'];\nsvgElements.forEach(function (nodeName) {\n  markupWrap[nodeName] = svgWrap;\n  shouldWrap[nodeName] = true;\n});\n\n/**\n * Gets the markup wrap configuration for the supplied `nodeName`.\n *\n * NOTE: This lazily detects which wraps are necessary for the current browser.\n *\n * @param {string} nodeName Lowercase `nodeName`.\n * @return {?array} Markup wrap configuration, if applicable.\n */\nfunction getMarkupWrap(nodeName) {\n  !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : undefined;\n  if (!markupWrap.hasOwnProperty(nodeName)) {\n    nodeName = '*';\n  }\n  if (!shouldWrap.hasOwnProperty(nodeName)) {\n    if (nodeName === '*') {\n      dummyNode.innerHTML = '<link />';\n    } else {\n      dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';\n    }\n    shouldWrap[nodeName] = !dummyNode.firstChild;\n  }\n  return shouldWrap[nodeName] ? markupWrap[nodeName] : null;\n}\n\nmodule.exports = getMarkupWrap;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/getMarkupWrap.js\n ** module id = 77\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactMultiChildUpdateTypes\n */\n\n'use strict';\n\nvar keyMirror = require('fbjs/lib/keyMirror');\n\n/**\n * When a component's children are updated, a series of update configuration\n * objects are created in order to batch and serialize the required changes.\n *\n * Enumerates all the possible types of update configurations.\n *\n * @internal\n */\nvar ReactMultiChildUpdateTypes = keyMirror({\n  INSERT_MARKUP: null,\n  MOVE_EXISTING: null,\n  REMOVE_NODE: null,\n  SET_MARKUP: null,\n  TEXT_CONTENT: null\n});\n\nmodule.exports = ReactMultiChildUpdateTypes;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactMultiChildUpdateTypes.js\n ** module id = 78\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule setTextContent\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar escapeTextContentForBrowser = require('./escapeTextContentForBrowser');\nvar setInnerHTML = require('./setInnerHTML');\n\n/**\n * Set the textContent property of a node, ensuring that whitespace is preserved\n * even in IE8. innerText is a poor substitute for textContent and, among many\n * issues, inserts <br> instead of the literal newline chars. innerHTML behaves\n * as it should.\n *\n * @param {DOMElement} node\n * @param {string} text\n * @internal\n */\nvar setTextContent = function (node, text) {\n  node.textContent = text;\n};\n\nif (ExecutionEnvironment.canUseDOM) {\n  if (!('textContent' in document.documentElement)) {\n    setTextContent = function (node, text) {\n      setInnerHTML(node, escapeTextContentForBrowser(text));\n    };\n  }\n}\n\nmodule.exports = setTextContent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/setTextContent.js\n ** module id = 79\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule escapeTextContentForBrowser\n */\n\n'use strict';\n\nvar ESCAPE_LOOKUP = {\n  '&': '&amp;',\n  '>': '&gt;',\n  '<': '&lt;',\n  '\"': '&quot;',\n  '\\'': '&#x27;'\n};\n\nvar ESCAPE_REGEX = /[&><\"']/g;\n\nfunction escaper(match) {\n  return ESCAPE_LOOKUP[match];\n}\n\n/**\n * Escapes text to prevent scripting attacks.\n *\n * @param {*} text Text value to escape.\n * @return {string} An escaped string.\n */\nfunction escapeTextContentForBrowser(text) {\n  return ('' + text).replace(ESCAPE_REGEX, escaper);\n}\n\nmodule.exports = escapeTextContentForBrowser;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/escapeTextContentForBrowser.js\n ** module id = 80\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule DOMPropertyOperations\n * @typechecks static-only\n */\n\n'use strict';\n\nvar DOMProperty = require('./DOMProperty');\nvar ReactPerf = require('./ReactPerf');\n\nvar quoteAttributeValueForBrowser = require('./quoteAttributeValueForBrowser');\nvar warning = require('fbjs/lib/warning');\n\n// Simplified subset\nvar VALID_ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][\\w\\.\\-]*$/;\nvar illegalAttributeNameCache = {};\nvar validatedAttributeNameCache = {};\n\nfunction isAttributeNameSafe(attributeName) {\n  if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {\n    return true;\n  }\n  if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {\n    return false;\n  }\n  if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {\n    validatedAttributeNameCache[attributeName] = true;\n    return true;\n  }\n  illegalAttributeNameCache[attributeName] = true;\n  process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : undefined;\n  return false;\n}\n\nfunction shouldIgnoreValue(propertyInfo, value) {\n  return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false;\n}\n\nif (process.env.NODE_ENV !== 'production') {\n  var reactProps = {\n    children: true,\n    dangerouslySetInnerHTML: true,\n    key: true,\n    ref: true\n  };\n  var warnedProperties = {};\n\n  var warnUnknownProperty = function (name) {\n    if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {\n      return;\n    }\n\n    warnedProperties[name] = true;\n    var lowerCasedName = name.toLowerCase();\n\n    // data-* attributes should be lowercase; suggest the lowercase version\n    var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null;\n\n    // For now, only warn when we have a suggested correction. This prevents\n    // logging too much when using transferPropsTo.\n    process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName) : undefined;\n  };\n}\n\n/**\n * Operations for dealing with DOM properties.\n */\nvar DOMPropertyOperations = {\n\n  /**\n   * Creates markup for the ID property.\n   *\n   * @param {string} id Unescaped ID.\n   * @return {string} Markup string.\n   */\n  createMarkupForID: function (id) {\n    return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id);\n  },\n\n  setAttributeForID: function (node, id) {\n    node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id);\n  },\n\n  /**\n   * Creates markup for a property.\n   *\n   * @param {string} name\n   * @param {*} value\n   * @return {?string} Markup string, or null if the property was invalid.\n   */\n  createMarkupForProperty: function (name, value) {\n    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;\n    if (propertyInfo) {\n      if (shouldIgnoreValue(propertyInfo, value)) {\n        return '';\n      }\n      var attributeName = propertyInfo.attributeName;\n      if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) {\n        return attributeName + '=\"\"';\n      }\n      return attributeName + '=' + quoteAttributeValueForBrowser(value);\n    } else if (DOMProperty.isCustomAttribute(name)) {\n      if (value == null) {\n        return '';\n      }\n      return name + '=' + quoteAttributeValueForBrowser(value);\n    } else if (process.env.NODE_ENV !== 'production') {\n      warnUnknownProperty(name);\n    }\n    return null;\n  },\n\n  /**\n   * Creates markup for a custom property.\n   *\n   * @param {string} name\n   * @param {*} value\n   * @return {string} Markup string, or empty string if the property was invalid.\n   */\n  createMarkupForCustomAttribute: function (name, value) {\n    if (!isAttributeNameSafe(name) || value == null) {\n      return '';\n    }\n    return name + '=' + quoteAttributeValueForBrowser(value);\n  },\n\n  /**\n   * Sets the value for a property on a node.\n   *\n   * @param {DOMElement} node\n   * @param {string} name\n   * @param {*} value\n   */\n  setValueForProperty: function (node, name, value) {\n    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;\n    if (propertyInfo) {\n      var mutationMethod = propertyInfo.mutationMethod;\n      if (mutationMethod) {\n        mutationMethod(node, value);\n      } else if (shouldIgnoreValue(propertyInfo, value)) {\n        this.deleteValueForProperty(node, name);\n      } else if (propertyInfo.mustUseAttribute) {\n        var attributeName = propertyInfo.attributeName;\n        var namespace = propertyInfo.attributeNamespace;\n        // `setAttribute` with objects becomes only `[object]` in IE8/9,\n        // ('' + value) makes it output the correct toString()-value.\n        if (namespace) {\n          node.setAttributeNS(namespace, attributeName, '' + value);\n        } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) {\n          node.setAttribute(attributeName, '');\n        } else {\n          node.setAttribute(attributeName, '' + value);\n        }\n      } else {\n        var propName = propertyInfo.propertyName;\n        // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the\n        // property type before comparing; only `value` does and is string.\n        if (!propertyInfo.hasSideEffects || '' + node[propName] !== '' + value) {\n          // Contrary to `setAttribute`, object properties are properly\n          // `toString`ed by IE8/9.\n          node[propName] = value;\n        }\n      }\n    } else if (DOMProperty.isCustomAttribute(name)) {\n      DOMPropertyOperations.setValueForAttribute(node, name, value);\n    } else if (process.env.NODE_ENV !== 'production') {\n      warnUnknownProperty(name);\n    }\n  },\n\n  setValueForAttribute: function (node, name, value) {\n    if (!isAttributeNameSafe(name)) {\n      return;\n    }\n    if (value == null) {\n      node.removeAttribute(name);\n    } else {\n      node.setAttribute(name, '' + value);\n    }\n  },\n\n  /**\n   * Deletes the value for a property on a node.\n   *\n   * @param {DOMElement} node\n   * @param {string} name\n   */\n  deleteValueForProperty: function (node, name) {\n    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;\n    if (propertyInfo) {\n      var mutationMethod = propertyInfo.mutationMethod;\n      if (mutationMethod) {\n        mutationMethod(node, undefined);\n      } else if (propertyInfo.mustUseAttribute) {\n        node.removeAttribute(propertyInfo.attributeName);\n      } else {\n        var propName = propertyInfo.propertyName;\n        var defaultValue = DOMProperty.getDefaultValueForProperty(node.nodeName, propName);\n        if (!propertyInfo.hasSideEffects || '' + node[propName] !== defaultValue) {\n          node[propName] = defaultValue;\n        }\n      }\n    } else if (DOMProperty.isCustomAttribute(name)) {\n      node.removeAttribute(name);\n    } else if (process.env.NODE_ENV !== 'production') {\n      warnUnknownProperty(name);\n    }\n  }\n\n};\n\nReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', {\n  setValueForProperty: 'setValueForProperty',\n  setValueForAttribute: 'setValueForAttribute',\n  deleteValueForProperty: 'deleteValueForProperty'\n});\n\nmodule.exports = DOMPropertyOperations;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/DOMPropertyOperations.js\n ** module id = 81\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule quoteAttributeValueForBrowser\n */\n\n'use strict';\n\nvar escapeTextContentForBrowser = require('./escapeTextContentForBrowser');\n\n/**\n * Escapes attribute value to prevent scripting attacks.\n *\n * @param {*} value Value to escape.\n * @return {string} An escaped string.\n */\nfunction quoteAttributeValueForBrowser(value) {\n  return '\"' + escapeTextContentForBrowser(value) + '\"';\n}\n\nmodule.exports = quoteAttributeValueForBrowser;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/quoteAttributeValueForBrowser.js\n ** module id = 82\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactComponentBrowserEnvironment\n */\n\n'use strict';\n\nvar ReactDOMIDOperations = require('./ReactDOMIDOperations');\nvar ReactMount = require('./ReactMount');\n\n/**\n * Abstracts away all functionality of the reconciler that requires knowledge of\n * the browser context. TODO: These callers should be refactored to avoid the\n * need for this injection.\n */\nvar ReactComponentBrowserEnvironment = {\n\n  processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates,\n\n  replaceNodeWithMarkupByID: ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,\n\n  /**\n   * If a particular environment requires that some resources be cleaned up,\n   * specify this in the injected Mixin. In the DOM, we would likely want to\n   * purge any cached node ID lookups.\n   *\n   * @private\n   */\n  unmountIDFromEnvironment: function (rootNodeID) {\n    ReactMount.purgeID(rootNodeID);\n  }\n\n};\n\nmodule.exports = ReactComponentBrowserEnvironment;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactComponentBrowserEnvironment.js\n ** module id = 83\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMIDOperations\n * @typechecks static-only\n */\n\n'use strict';\n\nvar DOMChildrenOperations = require('./DOMChildrenOperations');\nvar DOMPropertyOperations = require('./DOMPropertyOperations');\nvar ReactMount = require('./ReactMount');\nvar ReactPerf = require('./ReactPerf');\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Errors for properties that should not be updated with `updatePropertyByID()`.\n *\n * @type {object}\n * @private\n */\nvar INVALID_PROPERTY_ERRORS = {\n  dangerouslySetInnerHTML: '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',\n  style: '`style` must be set using `updateStylesByID()`.'\n};\n\n/**\n * Operations used to process updates to DOM nodes.\n */\nvar ReactDOMIDOperations = {\n\n  /**\n   * Updates a DOM node with new property values. This should only be used to\n   * update DOM properties in `DOMProperty`.\n   *\n   * @param {string} id ID of the node to update.\n   * @param {string} name A valid property name, see `DOMProperty`.\n   * @param {*} value New value of the property.\n   * @internal\n   */\n  updatePropertyByID: function (id, name, value) {\n    var node = ReactMount.getNode(id);\n    !!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined;\n\n    // If we're updating to null or undefined, we should remove the property\n    // from the DOM node instead of inadvertantly setting to a string. This\n    // brings us in line with the same behavior we have on initial render.\n    if (value != null) {\n      DOMPropertyOperations.setValueForProperty(node, name, value);\n    } else {\n      DOMPropertyOperations.deleteValueForProperty(node, name);\n    }\n  },\n\n  /**\n   * Replaces a DOM node that exists in the document with markup.\n   *\n   * @param {string} id ID of child to be replaced.\n   * @param {string} markup Dangerous markup to inject in place of child.\n   * @internal\n   * @see {Danger.dangerouslyReplaceNodeWithMarkup}\n   */\n  dangerouslyReplaceNodeWithMarkupByID: function (id, markup) {\n    var node = ReactMount.getNode(id);\n    DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);\n  },\n\n  /**\n   * Updates a component's children by processing a series of updates.\n   *\n   * @param {array<object>} updates List of update configurations.\n   * @param {array<string>} markup List of markup strings.\n   * @internal\n   */\n  dangerouslyProcessChildrenUpdates: function (updates, markup) {\n    for (var i = 0; i < updates.length; i++) {\n      updates[i].parentNode = ReactMount.getNode(updates[i].parentID);\n    }\n    DOMChildrenOperations.processUpdates(updates, markup);\n  }\n};\n\nReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {\n  dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID',\n  dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'\n});\n\nmodule.exports = ReactDOMIDOperations;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMIDOperations.js\n ** module id = 84\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDefaultInjection\n */\n\n'use strict';\n\nvar BeforeInputEventPlugin = require('./BeforeInputEventPlugin');\nvar ChangeEventPlugin = require('./ChangeEventPlugin');\nvar ClientReactRootIndex = require('./ClientReactRootIndex');\nvar DefaultEventPluginOrder = require('./DefaultEventPluginOrder');\nvar EnterLeaveEventPlugin = require('./EnterLeaveEventPlugin');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar HTMLDOMPropertyConfig = require('./HTMLDOMPropertyConfig');\nvar ReactBrowserComponentMixin = require('./ReactBrowserComponentMixin');\nvar ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');\nvar ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy');\nvar ReactDOMComponent = require('./ReactDOMComponent');\nvar ReactDOMTextComponent = require('./ReactDOMTextComponent');\nvar ReactEventListener = require('./ReactEventListener');\nvar ReactInjection = require('./ReactInjection');\nvar ReactInstanceHandles = require('./ReactInstanceHandles');\nvar ReactMount = require('./ReactMount');\nvar ReactReconcileTransaction = require('./ReactReconcileTransaction');\nvar SelectEventPlugin = require('./SelectEventPlugin');\nvar ServerReactRootIndex = require('./ServerReactRootIndex');\nvar SimpleEventPlugin = require('./SimpleEventPlugin');\nvar SVGDOMPropertyConfig = require('./SVGDOMPropertyConfig');\n\nvar alreadyInjected = false;\n\nfunction inject() {\n  if (alreadyInjected) {\n    // TODO: This is currently true because these injections are shared between\n    // the client and the server package. They should be built independently\n    // and not share any injection state. Then this problem will be solved.\n    return;\n  }\n  alreadyInjected = true;\n\n  ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener);\n\n  /**\n   * Inject modules for resolving DOM hierarchy and plugin ordering.\n   */\n  ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);\n  ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles);\n  ReactInjection.EventPluginHub.injectMount(ReactMount);\n\n  /**\n   * Some important event plugins included by default (without having to require\n   * them).\n   */\n  ReactInjection.EventPluginHub.injectEventPluginsByName({\n    SimpleEventPlugin: SimpleEventPlugin,\n    EnterLeaveEventPlugin: EnterLeaveEventPlugin,\n    ChangeEventPlugin: ChangeEventPlugin,\n    SelectEventPlugin: SelectEventPlugin,\n    BeforeInputEventPlugin: BeforeInputEventPlugin\n  });\n\n  ReactInjection.NativeComponent.injectGenericComponentClass(ReactDOMComponent);\n\n  ReactInjection.NativeComponent.injectTextComponentClass(ReactDOMTextComponent);\n\n  ReactInjection.Class.injectMixin(ReactBrowserComponentMixin);\n\n  ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);\n  ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);\n\n  ReactInjection.EmptyComponent.injectEmptyComponent('noscript');\n\n  ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction);\n  ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy);\n\n  ReactInjection.RootIndex.injectCreateReactRootIndex(ExecutionEnvironment.canUseDOM ? ClientReactRootIndex.createReactRootIndex : ServerReactRootIndex.createReactRootIndex);\n\n  ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);\n\n  if (process.env.NODE_ENV !== 'production') {\n    var url = ExecutionEnvironment.canUseDOM && window.location.href || '';\n    if (/[?&]react_perf\\b/.test(url)) {\n      var ReactDefaultPerf = require('./ReactDefaultPerf');\n      ReactDefaultPerf.start();\n    }\n  }\n}\n\nmodule.exports = {\n  inject: inject\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDefaultInjection.js\n ** module id = 85\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015 Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule BeforeInputEventPlugin\n * @typechecks static-only\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventPropagators = require('./EventPropagators');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar FallbackCompositionState = require('./FallbackCompositionState');\nvar SyntheticCompositionEvent = require('./SyntheticCompositionEvent');\nvar SyntheticInputEvent = require('./SyntheticInputEvent');\n\nvar keyOf = require('fbjs/lib/keyOf');\n\nvar END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space\nvar START_KEYCODE = 229;\n\nvar canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window;\n\nvar documentMode = null;\nif (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {\n  documentMode = document.documentMode;\n}\n\n// Webkit offers a very useful `textInput` event that can be used to\n// directly represent `beforeInput`. The IE `textinput` event is not as\n// useful, so we don't use it.\nvar canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto();\n\n// In IE9+, we have access to composition events, but the data supplied\n// by the native compositionend event may be incorrect. Japanese ideographic\n// spaces, for instance (\\u3000) are not recorded correctly.\nvar useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);\n\n/**\n * Opera <= 12 includes TextEvent in window, but does not fire\n * text input events. Rely on keypress instead.\n */\nfunction isPresto() {\n  var opera = window.opera;\n  return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12;\n}\n\nvar SPACEBAR_CODE = 32;\nvar SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\n// Events and their corresponding property names.\nvar eventTypes = {\n  beforeInput: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onBeforeInput: null }),\n      captured: keyOf({ onBeforeInputCapture: null })\n    },\n    dependencies: [topLevelTypes.topCompositionEnd, topLevelTypes.topKeyPress, topLevelTypes.topTextInput, topLevelTypes.topPaste]\n  },\n  compositionEnd: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCompositionEnd: null }),\n      captured: keyOf({ onCompositionEndCapture: null })\n    },\n    dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown]\n  },\n  compositionStart: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCompositionStart: null }),\n      captured: keyOf({ onCompositionStartCapture: null })\n    },\n    dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown]\n  },\n  compositionUpdate: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCompositionUpdate: null }),\n      captured: keyOf({ onCompositionUpdateCapture: null })\n    },\n    dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown]\n  }\n};\n\n// Track whether we've ever handled a keypress on the space key.\nvar hasSpaceKeypress = false;\n\n/**\n * Return whether a native keypress event is assumed to be a command.\n * This is required because Firefox fires `keypress` events for key commands\n * (cut, copy, select-all, etc.) even though no character is inserted.\n */\nfunction isKeypressCommand(nativeEvent) {\n  return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&\n  // ctrlKey && altKey is equivalent to AltGr, and is not a command.\n  !(nativeEvent.ctrlKey && nativeEvent.altKey);\n}\n\n/**\n * Translate native top level events into event types.\n *\n * @param {string} topLevelType\n * @return {object}\n */\nfunction getCompositionEventType(topLevelType) {\n  switch (topLevelType) {\n    case topLevelTypes.topCompositionStart:\n      return eventTypes.compositionStart;\n    case topLevelTypes.topCompositionEnd:\n      return eventTypes.compositionEnd;\n    case topLevelTypes.topCompositionUpdate:\n      return eventTypes.compositionUpdate;\n  }\n}\n\n/**\n * Does our fallback best-guess model think this event signifies that\n * composition has begun?\n *\n * @param {string} topLevelType\n * @param {object} nativeEvent\n * @return {boolean}\n */\nfunction isFallbackCompositionStart(topLevelType, nativeEvent) {\n  return topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE;\n}\n\n/**\n * Does our fallback mode think that this event is the end of composition?\n *\n * @param {string} topLevelType\n * @param {object} nativeEvent\n * @return {boolean}\n */\nfunction isFallbackCompositionEnd(topLevelType, nativeEvent) {\n  switch (topLevelType) {\n    case topLevelTypes.topKeyUp:\n      // Command keys insert or clear IME input.\n      return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;\n    case topLevelTypes.topKeyDown:\n      // Expect IME keyCode on each keydown. If we get any other\n      // code we must have exited earlier.\n      return nativeEvent.keyCode !== START_KEYCODE;\n    case topLevelTypes.topKeyPress:\n    case topLevelTypes.topMouseDown:\n    case topLevelTypes.topBlur:\n      // Events are not possible without cancelling IME.\n      return true;\n    default:\n      return false;\n  }\n}\n\n/**\n * Google Input Tools provides composition data via a CustomEvent,\n * with the `data` property populated in the `detail` object. If this\n * is available on the event object, use it. If not, this is a plain\n * composition event and we have nothing special to extract.\n *\n * @param {object} nativeEvent\n * @return {?string}\n */\nfunction getDataFromCustomEvent(nativeEvent) {\n  var detail = nativeEvent.detail;\n  if (typeof detail === 'object' && 'data' in detail) {\n    return detail.data;\n  }\n  return null;\n}\n\n// Track the current IME composition fallback object, if any.\nvar currentComposition = null;\n\n/**\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {DOMEventTarget} topLevelTarget The listening component root node.\n * @param {string} topLevelTargetID ID of `topLevelTarget`.\n * @param {object} nativeEvent Native browser event.\n * @return {?object} A SyntheticCompositionEvent.\n */\nfunction extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n  var eventType;\n  var fallbackData;\n\n  if (canUseCompositionEvent) {\n    eventType = getCompositionEventType(topLevelType);\n  } else if (!currentComposition) {\n    if (isFallbackCompositionStart(topLevelType, nativeEvent)) {\n      eventType = eventTypes.compositionStart;\n    }\n  } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {\n    eventType = eventTypes.compositionEnd;\n  }\n\n  if (!eventType) {\n    return null;\n  }\n\n  if (useFallbackCompositionData) {\n    // The current composition is stored statically and must not be\n    // overwritten while composition continues.\n    if (!currentComposition && eventType === eventTypes.compositionStart) {\n      currentComposition = FallbackCompositionState.getPooled(topLevelTarget);\n    } else if (eventType === eventTypes.compositionEnd) {\n      if (currentComposition) {\n        fallbackData = currentComposition.getData();\n      }\n    }\n  }\n\n  var event = SyntheticCompositionEvent.getPooled(eventType, topLevelTargetID, nativeEvent, nativeEventTarget);\n\n  if (fallbackData) {\n    // Inject data generated from fallback path into the synthetic event.\n    // This matches the property of native CompositionEventInterface.\n    event.data = fallbackData;\n  } else {\n    var customData = getDataFromCustomEvent(nativeEvent);\n    if (customData !== null) {\n      event.data = customData;\n    }\n  }\n\n  EventPropagators.accumulateTwoPhaseDispatches(event);\n  return event;\n}\n\n/**\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {object} nativeEvent Native browser event.\n * @return {?string} The string corresponding to this `beforeInput` event.\n */\nfunction getNativeBeforeInputChars(topLevelType, nativeEvent) {\n  switch (topLevelType) {\n    case topLevelTypes.topCompositionEnd:\n      return getDataFromCustomEvent(nativeEvent);\n    case topLevelTypes.topKeyPress:\n      /**\n       * If native `textInput` events are available, our goal is to make\n       * use of them. However, there is a special case: the spacebar key.\n       * In Webkit, preventing default on a spacebar `textInput` event\n       * cancels character insertion, but it *also* causes the browser\n       * to fall back to its default spacebar behavior of scrolling the\n       * page.\n       *\n       * Tracking at:\n       * https://code.google.com/p/chromium/issues/detail?id=355103\n       *\n       * To avoid this issue, use the keypress event as if no `textInput`\n       * event is available.\n       */\n      var which = nativeEvent.which;\n      if (which !== SPACEBAR_CODE) {\n        return null;\n      }\n\n      hasSpaceKeypress = true;\n      return SPACEBAR_CHAR;\n\n    case topLevelTypes.topTextInput:\n      // Record the characters to be added to the DOM.\n      var chars = nativeEvent.data;\n\n      // If it's a spacebar character, assume that we have already handled\n      // it at the keypress level and bail immediately. Android Chrome\n      // doesn't give us keycodes, so we need to blacklist it.\n      if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {\n        return null;\n      }\n\n      return chars;\n\n    default:\n      // For other native event types, do nothing.\n      return null;\n  }\n}\n\n/**\n * For browsers that do not provide the `textInput` event, extract the\n * appropriate string to use for SyntheticInputEvent.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {object} nativeEvent Native browser event.\n * @return {?string} The fallback string for this `beforeInput` event.\n */\nfunction getFallbackBeforeInputChars(topLevelType, nativeEvent) {\n  // If we are currently composing (IME) and using a fallback to do so,\n  // try to extract the composed characters from the fallback object.\n  if (currentComposition) {\n    if (topLevelType === topLevelTypes.topCompositionEnd || isFallbackCompositionEnd(topLevelType, nativeEvent)) {\n      var chars = currentComposition.getData();\n      FallbackCompositionState.release(currentComposition);\n      currentComposition = null;\n      return chars;\n    }\n    return null;\n  }\n\n  switch (topLevelType) {\n    case topLevelTypes.topPaste:\n      // If a paste event occurs after a keypress, throw out the input\n      // chars. Paste events should not lead to BeforeInput events.\n      return null;\n    case topLevelTypes.topKeyPress:\n      /**\n       * As of v27, Firefox may fire keypress events even when no character\n       * will be inserted. A few possibilities:\n       *\n       * - `which` is `0`. Arrow keys, Esc key, etc.\n       *\n       * - `which` is the pressed key code, but no char is available.\n       *   Ex: 'AltGr + d` in Polish. There is no modified character for\n       *   this key combination and no character is inserted into the\n       *   document, but FF fires the keypress for char code `100` anyway.\n       *   No `input` event will occur.\n       *\n       * - `which` is the pressed key code, but a command combination is\n       *   being used. Ex: `Cmd+C`. No character is inserted, and no\n       *   `input` event will occur.\n       */\n      if (nativeEvent.which && !isKeypressCommand(nativeEvent)) {\n        return String.fromCharCode(nativeEvent.which);\n      }\n      return null;\n    case topLevelTypes.topCompositionEnd:\n      return useFallbackCompositionData ? null : nativeEvent.data;\n    default:\n      return null;\n  }\n}\n\n/**\n * Extract a SyntheticInputEvent for `beforeInput`, based on either native\n * `textInput` or fallback behavior.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {DOMEventTarget} topLevelTarget The listening component root node.\n * @param {string} topLevelTargetID ID of `topLevelTarget`.\n * @param {object} nativeEvent Native browser event.\n * @return {?object} A SyntheticInputEvent.\n */\nfunction extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n  var chars;\n\n  if (canUseTextInputEvent) {\n    chars = getNativeBeforeInputChars(topLevelType, nativeEvent);\n  } else {\n    chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);\n  }\n\n  // If no characters are being inserted, no BeforeInput event should\n  // be fired.\n  if (!chars) {\n    return null;\n  }\n\n  var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, topLevelTargetID, nativeEvent, nativeEventTarget);\n\n  event.data = chars;\n  EventPropagators.accumulateTwoPhaseDispatches(event);\n  return event;\n}\n\n/**\n * Create an `onBeforeInput` event to match\n * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.\n *\n * This event plugin is based on the native `textInput` event\n * available in Chrome, Safari, Opera, and IE. This event fires after\n * `onKeyPress` and `onCompositionEnd`, but before `onInput`.\n *\n * `beforeInput` is spec'd but not implemented in any browsers, and\n * the `input` event does not provide any useful information about what has\n * actually been added, contrary to the spec. Thus, `textInput` is the best\n * available event to identify the characters that have actually been inserted\n * into the target node.\n *\n * This plugin is also responsible for emitting `composition` events, thus\n * allowing us to share composition fallback code for both `beforeInput` and\n * `composition` event types.\n */\nvar BeforeInputEventPlugin = {\n\n  eventTypes: eventTypes,\n\n  /**\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {DOMEventTarget} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native browser event.\n   * @return {*} An accumulation of synthetic events.\n   * @see {EventPluginHub.extractEvents}\n   */\n  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n    return [extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget)];\n  }\n};\n\nmodule.exports = BeforeInputEventPlugin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/BeforeInputEventPlugin.js\n ** module id = 86\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule EventPropagators\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventPluginHub = require('./EventPluginHub');\n\nvar warning = require('fbjs/lib/warning');\n\nvar accumulateInto = require('./accumulateInto');\nvar forEachAccumulated = require('./forEachAccumulated');\n\nvar PropagationPhases = EventConstants.PropagationPhases;\nvar getListener = EventPluginHub.getListener;\n\n/**\n * Some event types have a notion of different registration names for different\n * \"phases\" of propagation. This finds listeners by a given phase.\n */\nfunction listenerAtPhase(id, event, propagationPhase) {\n  var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];\n  return getListener(id, registrationName);\n}\n\n/**\n * Tags a `SyntheticEvent` with dispatched listeners. Creating this function\n * here, allows us to not have to bind or create functions for each event.\n * Mutating the event's members allows us to not have to create a wrapping\n * \"dispatch\" object that pairs the event with the listener.\n */\nfunction accumulateDirectionalDispatches(domID, upwards, event) {\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(domID, 'Dispatching id must not be null') : undefined;\n  }\n  var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;\n  var listener = listenerAtPhase(domID, event, phase);\n  if (listener) {\n    event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n    event._dispatchIDs = accumulateInto(event._dispatchIDs, domID);\n  }\n}\n\n/**\n * Collect dispatches (must be entirely collected before dispatching - see unit\n * tests). Lazily allocate the array to conserve memory.  We must loop through\n * each event and perform the traversal for each one. We cannot perform a\n * single traversal for the entire collection of events because each event may\n * have a different target.\n */\nfunction accumulateTwoPhaseDispatchesSingle(event) {\n  if (event && event.dispatchConfig.phasedRegistrationNames) {\n    EventPluginHub.injection.getInstanceHandle().traverseTwoPhase(event.dispatchMarker, accumulateDirectionalDispatches, event);\n  }\n}\n\n/**\n * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.\n */\nfunction accumulateTwoPhaseDispatchesSingleSkipTarget(event) {\n  if (event && event.dispatchConfig.phasedRegistrationNames) {\n    EventPluginHub.injection.getInstanceHandle().traverseTwoPhaseSkipTarget(event.dispatchMarker, accumulateDirectionalDispatches, event);\n  }\n}\n\n/**\n * Accumulates without regard to direction, does not look for phased\n * registration names. Same as `accumulateDirectDispatchesSingle` but without\n * requiring that the `dispatchMarker` be the same as the dispatched ID.\n */\nfunction accumulateDispatches(id, ignoredDirection, event) {\n  if (event && event.dispatchConfig.registrationName) {\n    var registrationName = event.dispatchConfig.registrationName;\n    var listener = getListener(id, registrationName);\n    if (listener) {\n      event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n      event._dispatchIDs = accumulateInto(event._dispatchIDs, id);\n    }\n  }\n}\n\n/**\n * Accumulates dispatches on an `SyntheticEvent`, but only for the\n * `dispatchMarker`.\n * @param {SyntheticEvent} event\n */\nfunction accumulateDirectDispatchesSingle(event) {\n  if (event && event.dispatchConfig.registrationName) {\n    accumulateDispatches(event.dispatchMarker, null, event);\n  }\n}\n\nfunction accumulateTwoPhaseDispatches(events) {\n  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);\n}\n\nfunction accumulateTwoPhaseDispatchesSkipTarget(events) {\n  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);\n}\n\nfunction accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {\n  EventPluginHub.injection.getInstanceHandle().traverseEnterLeave(fromID, toID, accumulateDispatches, leave, enter);\n}\n\nfunction accumulateDirectDispatches(events) {\n  forEachAccumulated(events, accumulateDirectDispatchesSingle);\n}\n\n/**\n * A small set of propagation patterns, each of which will accept a small amount\n * of information, and generate a set of \"dispatch ready event objects\" - which\n * are sets of events that have already been annotated with a set of dispatched\n * listener functions/ids. The API is designed this way to discourage these\n * propagation strategies from actually executing the dispatches, since we\n * always want to collect the entire set of dispatches before executing event a\n * single one.\n *\n * @constructor EventPropagators\n */\nvar EventPropagators = {\n  accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,\n  accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,\n  accumulateDirectDispatches: accumulateDirectDispatches,\n  accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches\n};\n\nmodule.exports = EventPropagators;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/EventPropagators.js\n ** module id = 87\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule FallbackCompositionState\n * @typechecks static-only\n */\n\n'use strict';\n\nvar PooledClass = require('./PooledClass');\n\nvar assign = require('./Object.assign');\nvar getTextContentAccessor = require('./getTextContentAccessor');\n\n/**\n * This helper class stores information about text content of a target node,\n * allowing comparison of content before and after a given event.\n *\n * Identify the node where selection currently begins, then observe\n * both its text content and its current position in the DOM. Since the\n * browser may natively replace the target node during composition, we can\n * use its position to find its replacement.\n *\n * @param {DOMEventTarget} root\n */\nfunction FallbackCompositionState(root) {\n  this._root = root;\n  this._startText = this.getText();\n  this._fallbackText = null;\n}\n\nassign(FallbackCompositionState.prototype, {\n  destructor: function () {\n    this._root = null;\n    this._startText = null;\n    this._fallbackText = null;\n  },\n\n  /**\n   * Get current text of input.\n   *\n   * @return {string}\n   */\n  getText: function () {\n    if ('value' in this._root) {\n      return this._root.value;\n    }\n    return this._root[getTextContentAccessor()];\n  },\n\n  /**\n   * Determine the differing substring between the initially stored\n   * text content and the current content.\n   *\n   * @return {string}\n   */\n  getData: function () {\n    if (this._fallbackText) {\n      return this._fallbackText;\n    }\n\n    var start;\n    var startValue = this._startText;\n    var startLength = startValue.length;\n    var end;\n    var endValue = this.getText();\n    var endLength = endValue.length;\n\n    for (start = 0; start < startLength; start++) {\n      if (startValue[start] !== endValue[start]) {\n        break;\n      }\n    }\n\n    var minEnd = startLength - start;\n    for (end = 1; end <= minEnd; end++) {\n      if (startValue[startLength - end] !== endValue[endLength - end]) {\n        break;\n      }\n    }\n\n    var sliceTail = end > 1 ? 1 - end : undefined;\n    this._fallbackText = endValue.slice(start, sliceTail);\n    return this._fallbackText;\n  }\n});\n\nPooledClass.addPoolingTo(FallbackCompositionState);\n\nmodule.exports = FallbackCompositionState;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/FallbackCompositionState.js\n ** module id = 88\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getTextContentAccessor\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n\nvar contentKey = null;\n\n/**\n * Gets the key used to access text content on a DOM node.\n *\n * @return {?string} Key used to access text content.\n * @internal\n */\nfunction getTextContentAccessor() {\n  if (!contentKey && ExecutionEnvironment.canUseDOM) {\n    // Prefer textContent to innerText because many browsers support both but\n    // SVG <text> elements don't support innerText even when <div> does.\n    contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';\n  }\n  return contentKey;\n}\n\nmodule.exports = getTextContentAccessor;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getTextContentAccessor.js\n ** module id = 89\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticCompositionEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticEvent = require('./SyntheticEvent');\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents\n */\nvar CompositionEventInterface = {\n  data: null\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface);\n\nmodule.exports = SyntheticCompositionEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticCompositionEvent.js\n ** module id = 90\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar PooledClass = require('./PooledClass');\n\nvar assign = require('./Object.assign');\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar EventInterface = {\n  type: null,\n  // currentTarget is set when dispatching; no use in copying it here\n  currentTarget: emptyFunction.thatReturnsNull,\n  eventPhase: null,\n  bubbles: null,\n  cancelable: null,\n  timeStamp: function (event) {\n    return event.timeStamp || Date.now();\n  },\n  defaultPrevented: null,\n  isTrusted: null\n};\n\n/**\n * Synthetic events are dispatched by event plugins, typically in response to a\n * top-level event delegation handler.\n *\n * These systems should generally use pooling to reduce the frequency of garbage\n * collection. The system should check `isPersistent` to determine whether the\n * event should be released into the pool after being dispatched. Users that\n * need a persisted event should invoke `persist`.\n *\n * Synthetic events (and subclasses) implement the DOM Level 3 Events API by\n * normalizing browser quirks. Subclasses do not necessarily have to implement a\n * DOM interface; custom application-specific events can also subclass this.\n *\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n */\nfunction SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  this.dispatchConfig = dispatchConfig;\n  this.dispatchMarker = dispatchMarker;\n  this.nativeEvent = nativeEvent;\n  this.target = nativeEventTarget;\n  this.currentTarget = nativeEventTarget;\n\n  var Interface = this.constructor.Interface;\n  for (var propName in Interface) {\n    if (!Interface.hasOwnProperty(propName)) {\n      continue;\n    }\n    var normalize = Interface[propName];\n    if (normalize) {\n      this[propName] = normalize(nativeEvent);\n    } else {\n      this[propName] = nativeEvent[propName];\n    }\n  }\n\n  var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;\n  if (defaultPrevented) {\n    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;\n  } else {\n    this.isDefaultPrevented = emptyFunction.thatReturnsFalse;\n  }\n  this.isPropagationStopped = emptyFunction.thatReturnsFalse;\n}\n\nassign(SyntheticEvent.prototype, {\n\n  preventDefault: function () {\n    this.defaultPrevented = true;\n    var event = this.nativeEvent;\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(event, 'This synthetic event is reused for performance reasons. If you\\'re ' + 'seeing this, you\\'re calling `preventDefault` on a ' + 'released/nullified synthetic event. This is a no-op. See ' + 'https://fb.me/react-event-pooling for more information.') : undefined;\n    }\n    if (!event) {\n      return;\n    }\n\n    if (event.preventDefault) {\n      event.preventDefault();\n    } else {\n      event.returnValue = false;\n    }\n    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;\n  },\n\n  stopPropagation: function () {\n    var event = this.nativeEvent;\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(event, 'This synthetic event is reused for performance reasons. If you\\'re ' + 'seeing this, you\\'re calling `stopPropagation` on a ' + 'released/nullified synthetic event. This is a no-op. See ' + 'https://fb.me/react-event-pooling for more information.') : undefined;\n    }\n    if (!event) {\n      return;\n    }\n\n    if (event.stopPropagation) {\n      event.stopPropagation();\n    } else {\n      event.cancelBubble = true;\n    }\n    this.isPropagationStopped = emptyFunction.thatReturnsTrue;\n  },\n\n  /**\n   * We release all dispatched `SyntheticEvent`s after each event loop, adding\n   * them back into the pool. This allows a way to hold onto a reference that\n   * won't be added back into the pool.\n   */\n  persist: function () {\n    this.isPersistent = emptyFunction.thatReturnsTrue;\n  },\n\n  /**\n   * Checks if this event should be released back into the pool.\n   *\n   * @return {boolean} True if this should not be released, false otherwise.\n   */\n  isPersistent: emptyFunction.thatReturnsFalse,\n\n  /**\n   * `PooledClass` looks for `destructor` on each instance it releases.\n   */\n  destructor: function () {\n    var Interface = this.constructor.Interface;\n    for (var propName in Interface) {\n      this[propName] = null;\n    }\n    this.dispatchConfig = null;\n    this.dispatchMarker = null;\n    this.nativeEvent = null;\n  }\n\n});\n\nSyntheticEvent.Interface = EventInterface;\n\n/**\n * Helper to reduce boilerplate when creating subclasses.\n *\n * @param {function} Class\n * @param {?object} Interface\n */\nSyntheticEvent.augmentClass = function (Class, Interface) {\n  var Super = this;\n\n  var prototype = Object.create(Super.prototype);\n  assign(prototype, Class.prototype);\n  Class.prototype = prototype;\n  Class.prototype.constructor = Class;\n\n  Class.Interface = assign({}, Super.Interface, Interface);\n  Class.augmentClass = Super.augmentClass;\n\n  PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler);\n};\n\nPooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler);\n\nmodule.exports = SyntheticEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticEvent.js\n ** module id = 91\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticInputEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticEvent = require('./SyntheticEvent');\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105\n *      /#events-inputevents\n */\nvar InputEventInterface = {\n  data: null\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface);\n\nmodule.exports = SyntheticInputEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticInputEvent.js\n ** module id = 92\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule keyOf\n */\n\n/**\n * Allows extraction of a minified key. Let's the build system minify keys\n * without losing the ability to dynamically use key strings as values\n * themselves. Pass in an object with a single key/val pair and it will return\n * you the string key of that single record. Suppose you want to grab the\n * value for a key 'className' inside of an object. Key/val minification may\n * have aliased that key to be 'xa12'. keyOf({className: null}) will return\n * 'xa12' in that case. Resolve keys you want to use once at startup time, then\n * reuse those resolutions.\n */\n\"use strict\";\n\nvar keyOf = function (oneKeyObj) {\n  var key;\n  for (key in oneKeyObj) {\n    if (!oneKeyObj.hasOwnProperty(key)) {\n      continue;\n    }\n    return key;\n  }\n  return null;\n};\n\nmodule.exports = keyOf;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/keyOf.js\n ** module id = 93\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ChangeEventPlugin\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventPluginHub = require('./EventPluginHub');\nvar EventPropagators = require('./EventPropagators');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar ReactUpdates = require('./ReactUpdates');\nvar SyntheticEvent = require('./SyntheticEvent');\n\nvar getEventTarget = require('./getEventTarget');\nvar isEventSupported = require('./isEventSupported');\nvar isTextInputElement = require('./isTextInputElement');\nvar keyOf = require('fbjs/lib/keyOf');\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\nvar eventTypes = {\n  change: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onChange: null }),\n      captured: keyOf({ onChangeCapture: null })\n    },\n    dependencies: [topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange]\n  }\n};\n\n/**\n * For IE shims\n */\nvar activeElement = null;\nvar activeElementID = null;\nvar activeElementValue = null;\nvar activeElementValueProp = null;\n\n/**\n * SECTION: handle `change` event\n */\nfunction shouldUseChangeEvent(elem) {\n  var nodeName = elem.nodeName && elem.nodeName.toLowerCase();\n  return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';\n}\n\nvar doesChangeEventBubble = false;\nif (ExecutionEnvironment.canUseDOM) {\n  // See `handleChange` comment below\n  doesChangeEventBubble = isEventSupported('change') && (!('documentMode' in document) || document.documentMode > 8);\n}\n\nfunction manualDispatchChangeEvent(nativeEvent) {\n  var event = SyntheticEvent.getPooled(eventTypes.change, activeElementID, nativeEvent, getEventTarget(nativeEvent));\n  EventPropagators.accumulateTwoPhaseDispatches(event);\n\n  // If change and propertychange bubbled, we'd just bind to it like all the\n  // other events and have it go through ReactBrowserEventEmitter. Since it\n  // doesn't, we manually listen for the events and so we have to enqueue and\n  // process the abstract event manually.\n  //\n  // Batching is necessary here in order to ensure that all event handlers run\n  // before the next rerender (including event handlers attached to ancestor\n  // elements instead of directly on the input). Without this, controlled\n  // components don't work properly in conjunction with event bubbling because\n  // the component is rerendered and the value reverted before all the event\n  // handlers can run. See https://github.com/facebook/react/issues/708.\n  ReactUpdates.batchedUpdates(runEventInBatch, event);\n}\n\nfunction runEventInBatch(event) {\n  EventPluginHub.enqueueEvents(event);\n  EventPluginHub.processEventQueue(false);\n}\n\nfunction startWatchingForChangeEventIE8(target, targetID) {\n  activeElement = target;\n  activeElementID = targetID;\n  activeElement.attachEvent('onchange', manualDispatchChangeEvent);\n}\n\nfunction stopWatchingForChangeEventIE8() {\n  if (!activeElement) {\n    return;\n  }\n  activeElement.detachEvent('onchange', manualDispatchChangeEvent);\n  activeElement = null;\n  activeElementID = null;\n}\n\nfunction getTargetIDForChangeEvent(topLevelType, topLevelTarget, topLevelTargetID) {\n  if (topLevelType === topLevelTypes.topChange) {\n    return topLevelTargetID;\n  }\n}\nfunction handleEventsForChangeEventIE8(topLevelType, topLevelTarget, topLevelTargetID) {\n  if (topLevelType === topLevelTypes.topFocus) {\n    // stopWatching() should be a noop here but we call it just in case we\n    // missed a blur event somehow.\n    stopWatchingForChangeEventIE8();\n    startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);\n  } else if (topLevelType === topLevelTypes.topBlur) {\n    stopWatchingForChangeEventIE8();\n  }\n}\n\n/**\n * SECTION: handle `input` event\n */\nvar isInputEventSupported = false;\nif (ExecutionEnvironment.canUseDOM) {\n  // IE9 claims to support the input event but fails to trigger it when\n  // deleting text, so we ignore its input events\n  isInputEventSupported = isEventSupported('input') && (!('documentMode' in document) || document.documentMode > 9);\n}\n\n/**\n * (For old IE.) Replacement getter/setter for the `value` property that gets\n * set on the active element.\n */\nvar newValueProp = {\n  get: function () {\n    return activeElementValueProp.get.call(this);\n  },\n  set: function (val) {\n    // Cast to a string so we can do equality checks.\n    activeElementValue = '' + val;\n    activeElementValueProp.set.call(this, val);\n  }\n};\n\n/**\n * (For old IE.) Starts tracking propertychange events on the passed-in element\n * and override the value property so that we can distinguish user events from\n * value changes in JS.\n */\nfunction startWatchingForValueChange(target, targetID) {\n  activeElement = target;\n  activeElementID = targetID;\n  activeElementValue = target.value;\n  activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value');\n\n  // Not guarded in a canDefineProperty check: IE8 supports defineProperty only\n  // on DOM elements\n  Object.defineProperty(activeElement, 'value', newValueProp);\n  activeElement.attachEvent('onpropertychange', handlePropertyChange);\n}\n\n/**\n * (For old IE.) Removes the event listeners from the currently-tracked element,\n * if any exists.\n */\nfunction stopWatchingForValueChange() {\n  if (!activeElement) {\n    return;\n  }\n\n  // delete restores the original property definition\n  delete activeElement.value;\n  activeElement.detachEvent('onpropertychange', handlePropertyChange);\n\n  activeElement = null;\n  activeElementID = null;\n  activeElementValue = null;\n  activeElementValueProp = null;\n}\n\n/**\n * (For old IE.) Handles a propertychange event, sending a `change` event if\n * the value of the active element has changed.\n */\nfunction handlePropertyChange(nativeEvent) {\n  if (nativeEvent.propertyName !== 'value') {\n    return;\n  }\n  var value = nativeEvent.srcElement.value;\n  if (value === activeElementValue) {\n    return;\n  }\n  activeElementValue = value;\n\n  manualDispatchChangeEvent(nativeEvent);\n}\n\n/**\n * If a `change` event should be fired, returns the target's ID.\n */\nfunction getTargetIDForInputEvent(topLevelType, topLevelTarget, topLevelTargetID) {\n  if (topLevelType === topLevelTypes.topInput) {\n    // In modern browsers (i.e., not IE8 or IE9), the input event is exactly\n    // what we want so fall through here and trigger an abstract event\n    return topLevelTargetID;\n  }\n}\n\n// For IE8 and IE9.\nfunction handleEventsForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) {\n  if (topLevelType === topLevelTypes.topFocus) {\n    // In IE8, we can capture almost all .value changes by adding a\n    // propertychange handler and looking for events with propertyName\n    // equal to 'value'\n    // In IE9, propertychange fires for most input events but is buggy and\n    // doesn't fire when text is deleted, but conveniently, selectionchange\n    // appears to fire in all of the remaining cases so we catch those and\n    // forward the event if the value has changed\n    // In either case, we don't want to call the event handler if the value\n    // is changed from JS so we redefine a setter for `.value` that updates\n    // our activeElementValue variable, allowing us to ignore those changes\n    //\n    // stopWatching() should be a noop here but we call it just in case we\n    // missed a blur event somehow.\n    stopWatchingForValueChange();\n    startWatchingForValueChange(topLevelTarget, topLevelTargetID);\n  } else if (topLevelType === topLevelTypes.topBlur) {\n    stopWatchingForValueChange();\n  }\n}\n\n// For IE8 and IE9.\nfunction getTargetIDForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) {\n  if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) {\n    // On the selectionchange event, the target is just document which isn't\n    // helpful for us so just check activeElement instead.\n    //\n    // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire\n    // propertychange on the first input event after setting `value` from a\n    // script and fires only keydown, keypress, keyup. Catching keyup usually\n    // gets it and catching keydown lets us fire an event for the first\n    // keystroke if user does a key repeat (it'll be a little delayed: right\n    // before the second keystroke). Other input methods (e.g., paste) seem to\n    // fire selectionchange normally.\n    if (activeElement && activeElement.value !== activeElementValue) {\n      activeElementValue = activeElement.value;\n      return activeElementID;\n    }\n  }\n}\n\n/**\n * SECTION: handle `click` event\n */\nfunction shouldUseClickEvent(elem) {\n  // Use the `click` event to detect changes to checkbox and radio inputs.\n  // This approach works across all browsers, whereas `change` does not fire\n  // until `blur` in IE8.\n  return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');\n}\n\nfunction getTargetIDForClickEvent(topLevelType, topLevelTarget, topLevelTargetID) {\n  if (topLevelType === topLevelTypes.topClick) {\n    return topLevelTargetID;\n  }\n}\n\n/**\n * This plugin creates an `onChange` event that normalizes change events\n * across form elements. This event fires at a time when it's possible to\n * change the element's value without seeing a flicker.\n *\n * Supported elements are:\n * - input (see `isTextInputElement`)\n * - textarea\n * - select\n */\nvar ChangeEventPlugin = {\n\n  eventTypes: eventTypes,\n\n  /**\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {DOMEventTarget} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native browser event.\n   * @return {*} An accumulation of synthetic events.\n   * @see {EventPluginHub.extractEvents}\n   */\n  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n\n    var getTargetIDFunc, handleEventFunc;\n    if (shouldUseChangeEvent(topLevelTarget)) {\n      if (doesChangeEventBubble) {\n        getTargetIDFunc = getTargetIDForChangeEvent;\n      } else {\n        handleEventFunc = handleEventsForChangeEventIE8;\n      }\n    } else if (isTextInputElement(topLevelTarget)) {\n      if (isInputEventSupported) {\n        getTargetIDFunc = getTargetIDForInputEvent;\n      } else {\n        getTargetIDFunc = getTargetIDForInputEventIE;\n        handleEventFunc = handleEventsForInputEventIE;\n      }\n    } else if (shouldUseClickEvent(topLevelTarget)) {\n      getTargetIDFunc = getTargetIDForClickEvent;\n    }\n\n    if (getTargetIDFunc) {\n      var targetID = getTargetIDFunc(topLevelType, topLevelTarget, topLevelTargetID);\n      if (targetID) {\n        var event = SyntheticEvent.getPooled(eventTypes.change, targetID, nativeEvent, nativeEventTarget);\n        event.type = 'change';\n        EventPropagators.accumulateTwoPhaseDispatches(event);\n        return event;\n      }\n    }\n\n    if (handleEventFunc) {\n      handleEventFunc(topLevelType, topLevelTarget, topLevelTargetID);\n    }\n  }\n\n};\n\nmodule.exports = ChangeEventPlugin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ChangeEventPlugin.js\n ** module id = 94\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getEventTarget\n * @typechecks static-only\n */\n\n'use strict';\n\n/**\n * Gets the target node from a native browser event by accounting for\n * inconsistencies in browser DOM APIs.\n *\n * @param {object} nativeEvent Native browser event.\n * @return {DOMEventTarget} Target node.\n */\nfunction getEventTarget(nativeEvent) {\n  var target = nativeEvent.target || nativeEvent.srcElement || window;\n  // Safari may fire events on text nodes (Node.TEXT_NODE is 3).\n  // @see http://www.quirksmode.org/js/events_properties.html\n  return target.nodeType === 3 ? target.parentNode : target;\n}\n\nmodule.exports = getEventTarget;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getEventTarget.js\n ** module id = 95\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule isTextInputElement\n */\n\n'use strict';\n\n/**\n * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary\n */\nvar supportedInputTypes = {\n  'color': true,\n  'date': true,\n  'datetime': true,\n  'datetime-local': true,\n  'email': true,\n  'month': true,\n  'number': true,\n  'password': true,\n  'range': true,\n  'search': true,\n  'tel': true,\n  'text': true,\n  'time': true,\n  'url': true,\n  'week': true\n};\n\nfunction isTextInputElement(elem) {\n  var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n  return nodeName && (nodeName === 'input' && supportedInputTypes[elem.type] || nodeName === 'textarea');\n}\n\nmodule.exports = isTextInputElement;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/isTextInputElement.js\n ** module id = 96\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ClientReactRootIndex\n * @typechecks\n */\n\n'use strict';\n\nvar nextReactRootIndex = 0;\n\nvar ClientReactRootIndex = {\n  createReactRootIndex: function () {\n    return nextReactRootIndex++;\n  }\n};\n\nmodule.exports = ClientReactRootIndex;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ClientReactRootIndex.js\n ** module id = 97\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule DefaultEventPluginOrder\n */\n\n'use strict';\n\nvar keyOf = require('fbjs/lib/keyOf');\n\n/**\n * Module that is injectable into `EventPluginHub`, that specifies a\n * deterministic ordering of `EventPlugin`s. A convenient way to reason about\n * plugins, without having to package every one of them. This is better than\n * having plugins be ordered in the same order that they are injected because\n * that ordering would be influenced by the packaging order.\n * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that\n * preventing default on events is convenient in `SimpleEventPlugin` handlers.\n */\nvar DefaultEventPluginOrder = [keyOf({ ResponderEventPlugin: null }), keyOf({ SimpleEventPlugin: null }), keyOf({ TapEventPlugin: null }), keyOf({ EnterLeaveEventPlugin: null }), keyOf({ ChangeEventPlugin: null }), keyOf({ SelectEventPlugin: null }), keyOf({ BeforeInputEventPlugin: null })];\n\nmodule.exports = DefaultEventPluginOrder;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/DefaultEventPluginOrder.js\n ** module id = 98\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule EnterLeaveEventPlugin\n * @typechecks static-only\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventPropagators = require('./EventPropagators');\nvar SyntheticMouseEvent = require('./SyntheticMouseEvent');\n\nvar ReactMount = require('./ReactMount');\nvar keyOf = require('fbjs/lib/keyOf');\n\nvar topLevelTypes = EventConstants.topLevelTypes;\nvar getFirstReactDOM = ReactMount.getFirstReactDOM;\n\nvar eventTypes = {\n  mouseEnter: {\n    registrationName: keyOf({ onMouseEnter: null }),\n    dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver]\n  },\n  mouseLeave: {\n    registrationName: keyOf({ onMouseLeave: null }),\n    dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver]\n  }\n};\n\nvar extractedEvents = [null, null];\n\nvar EnterLeaveEventPlugin = {\n\n  eventTypes: eventTypes,\n\n  /**\n   * For almost every interaction we care about, there will be both a top-level\n   * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that\n   * we do not extract duplicate events. However, moving the mouse into the\n   * browser from outside will not fire a `mouseout` event. In this case, we use\n   * the `mouseover` top-level event.\n   *\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {DOMEventTarget} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native browser event.\n   * @return {*} An accumulation of synthetic events.\n   * @see {EventPluginHub.extractEvents}\n   */\n  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n    if (topLevelType === topLevelTypes.topMouseOver && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {\n      return null;\n    }\n    if (topLevelType !== topLevelTypes.topMouseOut && topLevelType !== topLevelTypes.topMouseOver) {\n      // Must not be a mouse in or mouse out - ignoring.\n      return null;\n    }\n\n    var win;\n    if (topLevelTarget.window === topLevelTarget) {\n      // `topLevelTarget` is probably a window object.\n      win = topLevelTarget;\n    } else {\n      // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.\n      var doc = topLevelTarget.ownerDocument;\n      if (doc) {\n        win = doc.defaultView || doc.parentWindow;\n      } else {\n        win = window;\n      }\n    }\n\n    var from;\n    var to;\n    var fromID = '';\n    var toID = '';\n    if (topLevelType === topLevelTypes.topMouseOut) {\n      from = topLevelTarget;\n      fromID = topLevelTargetID;\n      to = getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement);\n      if (to) {\n        toID = ReactMount.getID(to);\n      } else {\n        to = win;\n      }\n      to = to || win;\n    } else {\n      from = win;\n      to = topLevelTarget;\n      toID = topLevelTargetID;\n    }\n\n    if (from === to) {\n      // Nothing pertains to our managed components.\n      return null;\n    }\n\n    var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, fromID, nativeEvent, nativeEventTarget);\n    leave.type = 'mouseleave';\n    leave.target = from;\n    leave.relatedTarget = to;\n\n    var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, toID, nativeEvent, nativeEventTarget);\n    enter.type = 'mouseenter';\n    enter.target = to;\n    enter.relatedTarget = from;\n\n    EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);\n\n    extractedEvents[0] = leave;\n    extractedEvents[1] = enter;\n\n    return extractedEvents;\n  }\n\n};\n\nmodule.exports = EnterLeaveEventPlugin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/EnterLeaveEventPlugin.js\n ** module id = 99\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticMouseEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticUIEvent = require('./SyntheticUIEvent');\nvar ViewportMetrics = require('./ViewportMetrics');\n\nvar getEventModifierState = require('./getEventModifierState');\n\n/**\n * @interface MouseEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar MouseEventInterface = {\n  screenX: null,\n  screenY: null,\n  clientX: null,\n  clientY: null,\n  ctrlKey: null,\n  shiftKey: null,\n  altKey: null,\n  metaKey: null,\n  getModifierState: getEventModifierState,\n  button: function (event) {\n    // Webkit, Firefox, IE9+\n    // which:  1 2 3\n    // button: 0 1 2 (standard)\n    var button = event.button;\n    if ('which' in event) {\n      return button;\n    }\n    // IE<9\n    // which:  undefined\n    // button: 0 0 0\n    // button: 1 4 2 (onmouseup)\n    return button === 2 ? 2 : button === 4 ? 1 : 0;\n  },\n  buttons: null,\n  relatedTarget: function (event) {\n    return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);\n  },\n  // \"Proprietary\" Interface.\n  pageX: function (event) {\n    return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft;\n  },\n  pageY: function (event) {\n    return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop;\n  }\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);\n\nmodule.exports = SyntheticMouseEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticMouseEvent.js\n ** module id = 100\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticUIEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticEvent = require('./SyntheticEvent');\n\nvar getEventTarget = require('./getEventTarget');\n\n/**\n * @interface UIEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar UIEventInterface = {\n  view: function (event) {\n    if (event.view) {\n      return event.view;\n    }\n\n    var target = getEventTarget(event);\n    if (target != null && target.window === target) {\n      // target is a window object\n      return target;\n    }\n\n    var doc = target.ownerDocument;\n    // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.\n    if (doc) {\n      return doc.defaultView || doc.parentWindow;\n    } else {\n      return window;\n    }\n  },\n  detail: function (event) {\n    return event.detail || 0;\n  }\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticEvent}\n */\nfunction SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);\n\nmodule.exports = SyntheticUIEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticUIEvent.js\n ** module id = 101\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getEventModifierState\n * @typechecks static-only\n */\n\n'use strict';\n\n/**\n * Translation from modifier key to the associated property in the event.\n * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers\n */\n\nvar modifierKeyToProp = {\n  'Alt': 'altKey',\n  'Control': 'ctrlKey',\n  'Meta': 'metaKey',\n  'Shift': 'shiftKey'\n};\n\n// IE8 does not implement getModifierState so we simply map it to the only\n// modifier keys exposed by the event itself, does not support Lock-keys.\n// Currently, all major browsers except Chrome seems to support Lock-keys.\nfunction modifierStateGetter(keyArg) {\n  var syntheticEvent = this;\n  var nativeEvent = syntheticEvent.nativeEvent;\n  if (nativeEvent.getModifierState) {\n    return nativeEvent.getModifierState(keyArg);\n  }\n  var keyProp = modifierKeyToProp[keyArg];\n  return keyProp ? !!nativeEvent[keyProp] : false;\n}\n\nfunction getEventModifierState(nativeEvent) {\n  return modifierStateGetter;\n}\n\nmodule.exports = getEventModifierState;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getEventModifierState.js\n ** module id = 102\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule HTMLDOMPropertyConfig\n */\n\n'use strict';\n\nvar DOMProperty = require('./DOMProperty');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n\nvar MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;\nvar MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;\nvar HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;\nvar HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS;\nvar HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE;\nvar HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;\nvar HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;\n\nvar hasSVG;\nif (ExecutionEnvironment.canUseDOM) {\n  var implementation = document.implementation;\n  hasSVG = implementation && implementation.hasFeature && implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1');\n}\n\nvar HTMLDOMPropertyConfig = {\n  isCustomAttribute: RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\\d_.\\-]*$/),\n  Properties: {\n    /**\n     * Standard Properties\n     */\n    accept: null,\n    acceptCharset: null,\n    accessKey: null,\n    action: null,\n    allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,\n    allowTransparency: MUST_USE_ATTRIBUTE,\n    alt: null,\n    async: HAS_BOOLEAN_VALUE,\n    autoComplete: null,\n    // autoFocus is polyfilled/normalized by AutoFocusUtils\n    // autoFocus: HAS_BOOLEAN_VALUE,\n    autoPlay: HAS_BOOLEAN_VALUE,\n    capture: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,\n    cellPadding: null,\n    cellSpacing: null,\n    charSet: MUST_USE_ATTRIBUTE,\n    challenge: MUST_USE_ATTRIBUTE,\n    checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    classID: MUST_USE_ATTRIBUTE,\n    // To set className on SVG elements, it's necessary to use .setAttribute;\n    // this works on HTML elements too in all browsers except IE8. Conveniently,\n    // IE8 doesn't support SVG and so we can simply use the attribute in\n    // browsers that support SVG and the property in browsers that don't,\n    // regardless of whether the element is HTML or SVG.\n    className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY,\n    cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,\n    colSpan: null,\n    content: null,\n    contentEditable: null,\n    contextMenu: MUST_USE_ATTRIBUTE,\n    controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    coords: null,\n    crossOrigin: null,\n    data: null, // For `<object />` acts as `src`.\n    dateTime: MUST_USE_ATTRIBUTE,\n    'default': HAS_BOOLEAN_VALUE,\n    defer: HAS_BOOLEAN_VALUE,\n    dir: null,\n    disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,\n    download: HAS_OVERLOADED_BOOLEAN_VALUE,\n    draggable: null,\n    encType: null,\n    form: MUST_USE_ATTRIBUTE,\n    formAction: MUST_USE_ATTRIBUTE,\n    formEncType: MUST_USE_ATTRIBUTE,\n    formMethod: MUST_USE_ATTRIBUTE,\n    formNoValidate: HAS_BOOLEAN_VALUE,\n    formTarget: MUST_USE_ATTRIBUTE,\n    frameBorder: MUST_USE_ATTRIBUTE,\n    headers: null,\n    height: MUST_USE_ATTRIBUTE,\n    hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,\n    high: null,\n    href: null,\n    hrefLang: null,\n    htmlFor: null,\n    httpEquiv: null,\n    icon: null,\n    id: MUST_USE_PROPERTY,\n    inputMode: MUST_USE_ATTRIBUTE,\n    integrity: null,\n    is: MUST_USE_ATTRIBUTE,\n    keyParams: MUST_USE_ATTRIBUTE,\n    keyType: MUST_USE_ATTRIBUTE,\n    kind: null,\n    label: null,\n    lang: null,\n    list: MUST_USE_ATTRIBUTE,\n    loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    low: null,\n    manifest: MUST_USE_ATTRIBUTE,\n    marginHeight: null,\n    marginWidth: null,\n    max: null,\n    maxLength: MUST_USE_ATTRIBUTE,\n    media: MUST_USE_ATTRIBUTE,\n    mediaGroup: null,\n    method: null,\n    min: null,\n    minLength: MUST_USE_ATTRIBUTE,\n    multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    name: null,\n    nonce: MUST_USE_ATTRIBUTE,\n    noValidate: HAS_BOOLEAN_VALUE,\n    open: HAS_BOOLEAN_VALUE,\n    optimum: null,\n    pattern: null,\n    placeholder: null,\n    poster: null,\n    preload: null,\n    radioGroup: null,\n    readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    rel: null,\n    required: HAS_BOOLEAN_VALUE,\n    reversed: HAS_BOOLEAN_VALUE,\n    role: MUST_USE_ATTRIBUTE,\n    rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,\n    rowSpan: null,\n    sandbox: null,\n    scope: null,\n    scoped: HAS_BOOLEAN_VALUE,\n    scrolling: null,\n    seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,\n    selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,\n    shape: null,\n    size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,\n    sizes: MUST_USE_ATTRIBUTE,\n    span: HAS_POSITIVE_NUMERIC_VALUE,\n    spellCheck: null,\n    src: null,\n    srcDoc: MUST_USE_PROPERTY,\n    srcLang: null,\n    srcSet: MUST_USE_ATTRIBUTE,\n    start: HAS_NUMERIC_VALUE,\n    step: null,\n    style: null,\n    summary: null,\n    tabIndex: null,\n    target: null,\n    title: null,\n    type: null,\n    useMap: null,\n    value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS,\n    width: MUST_USE_ATTRIBUTE,\n    wmode: MUST_USE_ATTRIBUTE,\n    wrap: null,\n\n    /**\n     * RDFa Properties\n     */\n    about: MUST_USE_ATTRIBUTE,\n    datatype: MUST_USE_ATTRIBUTE,\n    inlist: MUST_USE_ATTRIBUTE,\n    prefix: MUST_USE_ATTRIBUTE,\n    // property is also supported for OpenGraph in meta tags.\n    property: MUST_USE_ATTRIBUTE,\n    resource: MUST_USE_ATTRIBUTE,\n    'typeof': MUST_USE_ATTRIBUTE,\n    vocab: MUST_USE_ATTRIBUTE,\n\n    /**\n     * Non-standard Properties\n     */\n    // autoCapitalize and autoCorrect are supported in Mobile Safari for\n    // keyboard hints.\n    autoCapitalize: null,\n    autoCorrect: null,\n    // autoSave allows WebKit/Blink to persist values of input fields on page reloads\n    autoSave: null,\n    // color is for Safari mask-icon link\n    color: null,\n    // itemProp, itemScope, itemType are for\n    // Microdata support. See http://schema.org/docs/gs.html\n    itemProp: MUST_USE_ATTRIBUTE,\n    itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,\n    itemType: MUST_USE_ATTRIBUTE,\n    // itemID and itemRef are for Microdata support as well but\n    // only specified in the the WHATWG spec document. See\n    // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api\n    itemID: MUST_USE_ATTRIBUTE,\n    itemRef: MUST_USE_ATTRIBUTE,\n    // results show looking glass icon and recent searches on input\n    // search fields in WebKit/Blink\n    results: null,\n    // IE-only attribute that specifies security restrictions on an iframe\n    // as an alternative to the sandbox attribute on IE<10\n    security: MUST_USE_ATTRIBUTE,\n    // IE-only attribute that controls focus behavior\n    unselectable: MUST_USE_ATTRIBUTE\n  },\n  DOMAttributeNames: {\n    acceptCharset: 'accept-charset',\n    className: 'class',\n    htmlFor: 'for',\n    httpEquiv: 'http-equiv'\n  },\n  DOMPropertyNames: {\n    autoCapitalize: 'autocapitalize',\n    autoComplete: 'autocomplete',\n    autoCorrect: 'autocorrect',\n    autoFocus: 'autofocus',\n    autoPlay: 'autoplay',\n    autoSave: 'autosave',\n    // `encoding` is equivalent to `enctype`, IE8 lacks an `enctype` setter.\n    // http://www.w3.org/TR/html5/forms.html#dom-fs-encoding\n    encType: 'encoding',\n    hrefLang: 'hreflang',\n    radioGroup: 'radiogroup',\n    spellCheck: 'spellcheck',\n    srcDoc: 'srcdoc',\n    srcSet: 'srcset'\n  }\n};\n\nmodule.exports = HTMLDOMPropertyConfig;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/HTMLDOMPropertyConfig.js\n ** module id = 103\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactBrowserComponentMixin\n */\n\n'use strict';\n\nvar ReactInstanceMap = require('./ReactInstanceMap');\n\nvar findDOMNode = require('./findDOMNode');\nvar warning = require('fbjs/lib/warning');\n\nvar didWarnKey = '_getDOMNodeDidWarn';\n\nvar ReactBrowserComponentMixin = {\n  /**\n   * Returns the DOM node rendered by this component.\n   *\n   * @return {DOMElement} The root node of this component.\n   * @final\n   * @protected\n   */\n  getDOMNode: function () {\n    process.env.NODE_ENV !== 'production' ? warning(this.constructor[didWarnKey], '%s.getDOMNode(...) is deprecated. Please use ' + 'ReactDOM.findDOMNode(instance) instead.', ReactInstanceMap.get(this).getName() || this.tagName || 'Unknown') : undefined;\n    this.constructor[didWarnKey] = true;\n    return findDOMNode(this);\n  }\n};\n\nmodule.exports = ReactBrowserComponentMixin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactBrowserComponentMixin.js\n ** module id = 104\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule findDOMNode\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactInstanceMap = require('./ReactInstanceMap');\nvar ReactMount = require('./ReactMount');\n\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * Returns the DOM node rendered by this element.\n *\n * @param {ReactComponent|DOMElement} componentOrElement\n * @return {?DOMElement} The root node of this element.\n */\nfunction findDOMNode(componentOrElement) {\n  if (process.env.NODE_ENV !== 'production') {\n    var owner = ReactCurrentOwner.current;\n    if (owner !== null) {\n      process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing getDOMNode or findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : undefined;\n      owner._warnedAboutRefsInRender = true;\n    }\n  }\n  if (componentOrElement == null) {\n    return null;\n  }\n  if (componentOrElement.nodeType === 1) {\n    return componentOrElement;\n  }\n  if (ReactInstanceMap.has(componentOrElement)) {\n    return ReactMount.getNodeFromInstance(componentOrElement);\n  }\n  !(componentOrElement.render == null || typeof componentOrElement.render !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findDOMNode was called on an unmounted component.') : invariant(false) : undefined;\n  !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : invariant(false) : undefined;\n}\n\nmodule.exports = findDOMNode;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/findDOMNode.js\n ** module id = 105\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDefaultBatchingStrategy\n */\n\n'use strict';\n\nvar ReactUpdates = require('./ReactUpdates');\nvar Transaction = require('./Transaction');\n\nvar assign = require('./Object.assign');\nvar emptyFunction = require('fbjs/lib/emptyFunction');\n\nvar RESET_BATCHED_UPDATES = {\n  initialize: emptyFunction,\n  close: function () {\n    ReactDefaultBatchingStrategy.isBatchingUpdates = false;\n  }\n};\n\nvar FLUSH_BATCHED_UPDATES = {\n  initialize: emptyFunction,\n  close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)\n};\n\nvar TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];\n\nfunction ReactDefaultBatchingStrategyTransaction() {\n  this.reinitializeTransaction();\n}\n\nassign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction.Mixin, {\n  getTransactionWrappers: function () {\n    return TRANSACTION_WRAPPERS;\n  }\n});\n\nvar transaction = new ReactDefaultBatchingStrategyTransaction();\n\nvar ReactDefaultBatchingStrategy = {\n  isBatchingUpdates: false,\n\n  /**\n   * Call the provided function in a context within which calls to `setState`\n   * and friends are batched such that components aren't updated unnecessarily.\n   */\n  batchedUpdates: function (callback, a, b, c, d, e) {\n    var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;\n\n    ReactDefaultBatchingStrategy.isBatchingUpdates = true;\n\n    // The code is written this way to avoid extra allocations\n    if (alreadyBatchingUpdates) {\n      callback(a, b, c, d, e);\n    } else {\n      transaction.perform(callback, null, a, b, c, d, e);\n    }\n  }\n};\n\nmodule.exports = ReactDefaultBatchingStrategy;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDefaultBatchingStrategy.js\n ** module id = 106\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMComponent\n * @typechecks static-only\n */\n\n/* global hasOwnProperty:true */\n\n'use strict';\n\nvar AutoFocusUtils = require('./AutoFocusUtils');\nvar CSSPropertyOperations = require('./CSSPropertyOperations');\nvar DOMProperty = require('./DOMProperty');\nvar DOMPropertyOperations = require('./DOMPropertyOperations');\nvar EventConstants = require('./EventConstants');\nvar ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');\nvar ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');\nvar ReactDOMButton = require('./ReactDOMButton');\nvar ReactDOMInput = require('./ReactDOMInput');\nvar ReactDOMOption = require('./ReactDOMOption');\nvar ReactDOMSelect = require('./ReactDOMSelect');\nvar ReactDOMTextarea = require('./ReactDOMTextarea');\nvar ReactMount = require('./ReactMount');\nvar ReactMultiChild = require('./ReactMultiChild');\nvar ReactPerf = require('./ReactPerf');\nvar ReactUpdateQueue = require('./ReactUpdateQueue');\n\nvar assign = require('./Object.assign');\nvar canDefineProperty = require('./canDefineProperty');\nvar escapeTextContentForBrowser = require('./escapeTextContentForBrowser');\nvar invariant = require('fbjs/lib/invariant');\nvar isEventSupported = require('./isEventSupported');\nvar keyOf = require('fbjs/lib/keyOf');\nvar setInnerHTML = require('./setInnerHTML');\nvar setTextContent = require('./setTextContent');\nvar shallowEqual = require('fbjs/lib/shallowEqual');\nvar validateDOMNesting = require('./validateDOMNesting');\nvar warning = require('fbjs/lib/warning');\n\nvar deleteListener = ReactBrowserEventEmitter.deleteListener;\nvar listenTo = ReactBrowserEventEmitter.listenTo;\nvar registrationNameModules = ReactBrowserEventEmitter.registrationNameModules;\n\n// For quickly matching children type, to test if can be treated as content.\nvar CONTENT_TYPES = { 'string': true, 'number': true };\n\nvar CHILDREN = keyOf({ children: null });\nvar STYLE = keyOf({ style: null });\nvar HTML = keyOf({ __html: null });\n\nvar ELEMENT_NODE_TYPE = 1;\n\nfunction getDeclarationErrorAddendum(internalInstance) {\n  if (internalInstance) {\n    var owner = internalInstance._currentElement._owner || null;\n    if (owner) {\n      var name = owner.getName();\n      if (name) {\n        return ' This DOM node was rendered by `' + name + '`.';\n      }\n    }\n  }\n  return '';\n}\n\nvar legacyPropsDescriptor;\nif (process.env.NODE_ENV !== 'production') {\n  legacyPropsDescriptor = {\n    props: {\n      enumerable: false,\n      get: function () {\n        var component = this._reactInternalComponent;\n        process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .props of a DOM node; instead, ' + 'recreate the props as `render` did originally or read the DOM ' + 'properties/attributes directly from this node (e.g., ' + 'this.refs.box.className).%s', getDeclarationErrorAddendum(component)) : undefined;\n        return component._currentElement.props;\n      }\n    }\n  };\n}\n\nfunction legacyGetDOMNode() {\n  if (process.env.NODE_ENV !== 'production') {\n    var component = this._reactInternalComponent;\n    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .getDOMNode() of a DOM node; ' + 'instead, use the node directly.%s', getDeclarationErrorAddendum(component)) : undefined;\n  }\n  return this;\n}\n\nfunction legacyIsMounted() {\n  var component = this._reactInternalComponent;\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .isMounted() of a DOM node.%s', getDeclarationErrorAddendum(component)) : undefined;\n  }\n  return !!component;\n}\n\nfunction legacySetStateEtc() {\n  if (process.env.NODE_ENV !== 'production') {\n    var component = this._reactInternalComponent;\n    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setState(), .replaceState(), or ' + '.forceUpdate() of a DOM node. This is a no-op.%s', getDeclarationErrorAddendum(component)) : undefined;\n  }\n}\n\nfunction legacySetProps(partialProps, callback) {\n  var component = this._reactInternalComponent;\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;\n  }\n  if (!component) {\n    return;\n  }\n  ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps);\n  if (callback) {\n    ReactUpdateQueue.enqueueCallbackInternal(component, callback);\n  }\n}\n\nfunction legacyReplaceProps(partialProps, callback) {\n  var component = this._reactInternalComponent;\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;\n  }\n  if (!component) {\n    return;\n  }\n  ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps);\n  if (callback) {\n    ReactUpdateQueue.enqueueCallbackInternal(component, callback);\n  }\n}\n\nfunction friendlyStringify(obj) {\n  if (typeof obj === 'object') {\n    if (Array.isArray(obj)) {\n      return '[' + obj.map(friendlyStringify).join(', ') + ']';\n    } else {\n      var pairs = [];\n      for (var key in obj) {\n        if (Object.prototype.hasOwnProperty.call(obj, key)) {\n          var keyEscaped = /^[a-z$_][\\w$_]*$/i.test(key) ? key : JSON.stringify(key);\n          pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key]));\n        }\n      }\n      return '{' + pairs.join(', ') + '}';\n    }\n  } else if (typeof obj === 'string') {\n    return JSON.stringify(obj);\n  } else if (typeof obj === 'function') {\n    return '[function object]';\n  }\n  // Differs from JSON.stringify in that undefined becauses undefined and that\n  // inf and nan don't become null\n  return String(obj);\n}\n\nvar styleMutationWarning = {};\n\nfunction checkAndWarnForMutatedStyle(style1, style2, component) {\n  if (style1 == null || style2 == null) {\n    return;\n  }\n  if (shallowEqual(style1, style2)) {\n    return;\n  }\n\n  var componentName = component._tag;\n  var owner = component._currentElement._owner;\n  var ownerName;\n  if (owner) {\n    ownerName = owner.getName();\n  }\n\n  var hash = ownerName + '|' + componentName;\n\n  if (styleMutationWarning.hasOwnProperty(hash)) {\n    return;\n  }\n\n  styleMutationWarning[hash] = true;\n\n  process.env.NODE_ENV !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : undefined;\n}\n\n/**\n * @param {object} component\n * @param {?object} props\n */\nfunction assertValidProps(component, props) {\n  if (!props) {\n    return;\n  }\n  // Note the use of `==` which checks for null or undefined.\n  if (process.env.NODE_ENV !== 'production') {\n    if (voidElementTags[component._tag]) {\n      process.env.NODE_ENV !== 'production' ? warning(props.children == null && props.dangerouslySetInnerHTML == null, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : undefined;\n    }\n  }\n  if (props.dangerouslySetInnerHTML != null) {\n    !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined;\n    !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : undefined;\n  }\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined;\n    process.env.NODE_ENV !== 'production' ? warning(!props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : undefined;\n  }\n  !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, ' + 'not a string. For example, style={{marginRight: spacing + \\'em\\'}} when ' + 'using JSX.%s', getDeclarationErrorAddendum(component)) : invariant(false) : undefined;\n}\n\nfunction enqueuePutListener(id, registrationName, listener, transaction) {\n  if (process.env.NODE_ENV !== 'production') {\n    // IE8 has no API for event capturing and the `onScroll` event doesn't\n    // bubble.\n    process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\\'t support the `onScroll` event') : undefined;\n  }\n  var container = ReactMount.findReactContainerForID(id);\n  if (container) {\n    var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container;\n    listenTo(registrationName, doc);\n  }\n  transaction.getReactMountReady().enqueue(putListener, {\n    id: id,\n    registrationName: registrationName,\n    listener: listener\n  });\n}\n\nfunction putListener() {\n  var listenerToPut = this;\n  ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener);\n}\n\n// There are so many media events, it makes sense to just\n// maintain a list rather than create a `trapBubbledEvent` for each\nvar mediaEvents = {\n  topAbort: 'abort',\n  topCanPlay: 'canplay',\n  topCanPlayThrough: 'canplaythrough',\n  topDurationChange: 'durationchange',\n  topEmptied: 'emptied',\n  topEncrypted: 'encrypted',\n  topEnded: 'ended',\n  topError: 'error',\n  topLoadedData: 'loadeddata',\n  topLoadedMetadata: 'loadedmetadata',\n  topLoadStart: 'loadstart',\n  topPause: 'pause',\n  topPlay: 'play',\n  topPlaying: 'playing',\n  topProgress: 'progress',\n  topRateChange: 'ratechange',\n  topSeeked: 'seeked',\n  topSeeking: 'seeking',\n  topStalled: 'stalled',\n  topSuspend: 'suspend',\n  topTimeUpdate: 'timeupdate',\n  topVolumeChange: 'volumechange',\n  topWaiting: 'waiting'\n};\n\nfunction trapBubbledEventsLocal() {\n  var inst = this;\n  // If a component renders to null or if another component fatals and causes\n  // the state of the tree to be corrupted, `node` here can be null.\n  !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined;\n  var node = ReactMount.getNode(inst._rootNodeID);\n  !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined;\n\n  switch (inst._tag) {\n    case 'iframe':\n      inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];\n      break;\n    case 'video':\n    case 'audio':\n\n      inst._wrapperState.listeners = [];\n      // create listener for each media event\n      for (var event in mediaEvents) {\n        if (mediaEvents.hasOwnProperty(event)) {\n          inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node));\n        }\n      }\n\n      break;\n    case 'img':\n      inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];\n      break;\n    case 'form':\n      inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)];\n      break;\n  }\n}\n\nfunction mountReadyInputWrapper() {\n  ReactDOMInput.mountReadyWrapper(this);\n}\n\nfunction postUpdateSelectWrapper() {\n  ReactDOMSelect.postUpdateWrapper(this);\n}\n\n// For HTML, certain tags should omit their close tag. We keep a whitelist for\n// those special cased tags.\n\nvar omittedCloseTags = {\n  'area': true,\n  'base': true,\n  'br': true,\n  'col': true,\n  'embed': true,\n  'hr': true,\n  'img': true,\n  'input': true,\n  'keygen': true,\n  'link': true,\n  'meta': true,\n  'param': true,\n  'source': true,\n  'track': true,\n  'wbr': true\n};\n\n// NOTE: menuitem's close tag should be omitted, but that causes problems.\nvar newlineEatingTags = {\n  'listing': true,\n  'pre': true,\n  'textarea': true\n};\n\n// For HTML, certain tags cannot have children. This has the same purpose as\n// `omittedCloseTags` except that `menuitem` should still have its closing tag.\n\nvar voidElementTags = assign({\n  'menuitem': true\n}, omittedCloseTags);\n\n// We accept any tag to be rendered but since this gets injected into arbitrary\n// HTML, we want to make sure that it's a safe tag.\n// http://www.w3.org/TR/REC-xml/#NT-Name\n\nvar VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\\.\\-\\d]*$/; // Simplified subset\nvar validatedTagCache = {};\nvar hasOwnProperty = ({}).hasOwnProperty;\n\nfunction validateDangerousTag(tag) {\n  if (!hasOwnProperty.call(validatedTagCache, tag)) {\n    !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined;\n    validatedTagCache[tag] = true;\n  }\n}\n\nfunction processChildContextDev(context, inst) {\n  // Pass down our tag name to child components for validation purposes\n  context = assign({}, context);\n  var info = context[validateDOMNesting.ancestorInfoContextKey];\n  context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(info, inst._tag, inst);\n  return context;\n}\n\nfunction isCustomComponent(tagName, props) {\n  return tagName.indexOf('-') >= 0 || props.is != null;\n}\n\n/**\n * Creates a new React class that is idempotent and capable of containing other\n * React components. It accepts event listeners and DOM properties that are\n * valid according to `DOMProperty`.\n *\n *  - Event listeners: `onClick`, `onMouseDown`, etc.\n *  - DOM properties: `className`, `name`, `title`, etc.\n *\n * The `style` property functions differently from the DOM API. It accepts an\n * object mapping of style properties to values.\n *\n * @constructor ReactDOMComponent\n * @extends ReactMultiChild\n */\nfunction ReactDOMComponent(tag) {\n  validateDangerousTag(tag);\n  this._tag = tag.toLowerCase();\n  this._renderedChildren = null;\n  this._previousStyle = null;\n  this._previousStyleCopy = null;\n  this._rootNodeID = null;\n  this._wrapperState = null;\n  this._topLevelWrapper = null;\n  this._nodeWithLegacyProperties = null;\n  if (process.env.NODE_ENV !== 'production') {\n    this._unprocessedContextDev = null;\n    this._processedContextDev = null;\n  }\n}\n\nReactDOMComponent.displayName = 'ReactDOMComponent';\n\nReactDOMComponent.Mixin = {\n\n  construct: function (element) {\n    this._currentElement = element;\n  },\n\n  /**\n   * Generates root tag markup then recurses. This method has side effects and\n   * is not idempotent.\n   *\n   * @internal\n   * @param {string} rootID The root DOM ID for this node.\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @param {object} context\n   * @return {string} The computed markup.\n   */\n  mountComponent: function (rootID, transaction, context) {\n    this._rootNodeID = rootID;\n\n    var props = this._currentElement.props;\n\n    switch (this._tag) {\n      case 'iframe':\n      case 'img':\n      case 'form':\n      case 'video':\n      case 'audio':\n        this._wrapperState = {\n          listeners: null\n        };\n        transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);\n        break;\n      case 'button':\n        props = ReactDOMButton.getNativeProps(this, props, context);\n        break;\n      case 'input':\n        ReactDOMInput.mountWrapper(this, props, context);\n        props = ReactDOMInput.getNativeProps(this, props, context);\n        break;\n      case 'option':\n        ReactDOMOption.mountWrapper(this, props, context);\n        props = ReactDOMOption.getNativeProps(this, props, context);\n        break;\n      case 'select':\n        ReactDOMSelect.mountWrapper(this, props, context);\n        props = ReactDOMSelect.getNativeProps(this, props, context);\n        context = ReactDOMSelect.processChildContext(this, props, context);\n        break;\n      case 'textarea':\n        ReactDOMTextarea.mountWrapper(this, props, context);\n        props = ReactDOMTextarea.getNativeProps(this, props, context);\n        break;\n    }\n\n    assertValidProps(this, props);\n    if (process.env.NODE_ENV !== 'production') {\n      if (context[validateDOMNesting.ancestorInfoContextKey]) {\n        validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]);\n      }\n    }\n\n    if (process.env.NODE_ENV !== 'production') {\n      this._unprocessedContextDev = context;\n      this._processedContextDev = processChildContextDev(context, this);\n      context = this._processedContextDev;\n    }\n\n    var mountImage;\n    if (transaction.useCreateElement) {\n      var ownerDocument = context[ReactMount.ownerDocumentContextKey];\n      var el = ownerDocument.createElement(this._currentElement.type);\n      DOMPropertyOperations.setAttributeForID(el, this._rootNodeID);\n      // Populate node cache\n      ReactMount.getID(el);\n      this._updateDOMProperties({}, props, transaction, el);\n      this._createInitialChildren(transaction, props, context, el);\n      mountImage = el;\n    } else {\n      var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props);\n      var tagContent = this._createContentMarkup(transaction, props, context);\n      if (!tagContent && omittedCloseTags[this._tag]) {\n        mountImage = tagOpen + '/>';\n      } else {\n        mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>';\n      }\n    }\n\n    switch (this._tag) {\n      case 'input':\n        transaction.getReactMountReady().enqueue(mountReadyInputWrapper, this);\n      // falls through\n      case 'button':\n      case 'select':\n      case 'textarea':\n        if (props.autoFocus) {\n          transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);\n        }\n        break;\n    }\n\n    return mountImage;\n  },\n\n  /**\n   * Creates markup for the open tag and all attributes.\n   *\n   * This method has side effects because events get registered.\n   *\n   * Iterating over object properties is faster than iterating over arrays.\n   * @see http://jsperf.com/obj-vs-arr-iteration\n   *\n   * @private\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @param {object} props\n   * @return {string} Markup of opening tag.\n   */\n  _createOpenTagMarkupAndPutListeners: function (transaction, props) {\n    var ret = '<' + this._currentElement.type;\n\n    for (var propKey in props) {\n      if (!props.hasOwnProperty(propKey)) {\n        continue;\n      }\n      var propValue = props[propKey];\n      if (propValue == null) {\n        continue;\n      }\n      if (registrationNameModules.hasOwnProperty(propKey)) {\n        if (propValue) {\n          enqueuePutListener(this._rootNodeID, propKey, propValue, transaction);\n        }\n      } else {\n        if (propKey === STYLE) {\n          if (propValue) {\n            if (process.env.NODE_ENV !== 'production') {\n              // See `_updateDOMProperties`. style block\n              this._previousStyle = propValue;\n            }\n            propValue = this._previousStyleCopy = assign({}, props.style);\n          }\n          propValue = CSSPropertyOperations.createMarkupForStyles(propValue);\n        }\n        var markup = null;\n        if (this._tag != null && isCustomComponent(this._tag, props)) {\n          if (propKey !== CHILDREN) {\n            markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);\n          }\n        } else {\n          markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);\n        }\n        if (markup) {\n          ret += ' ' + markup;\n        }\n      }\n    }\n\n    // For static pages, no need to put React ID and checksum. Saves lots of\n    // bytes.\n    if (transaction.renderToStaticMarkup) {\n      return ret;\n    }\n\n    var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID);\n    return ret + ' ' + markupForID;\n  },\n\n  /**\n   * Creates markup for the content between the tags.\n   *\n   * @private\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @param {object} props\n   * @param {object} context\n   * @return {string} Content markup.\n   */\n  _createContentMarkup: function (transaction, props, context) {\n    var ret = '';\n\n    // Intentional use of != to avoid catching zero/false.\n    var innerHTML = props.dangerouslySetInnerHTML;\n    if (innerHTML != null) {\n      if (innerHTML.__html != null) {\n        ret = innerHTML.__html;\n      }\n    } else {\n      var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;\n      var childrenToUse = contentToUse != null ? null : props.children;\n      if (contentToUse != null) {\n        // TODO: Validate that text is allowed as a child of this node\n        ret = escapeTextContentForBrowser(contentToUse);\n      } else if (childrenToUse != null) {\n        var mountImages = this.mountChildren(childrenToUse, transaction, context);\n        ret = mountImages.join('');\n      }\n    }\n    if (newlineEatingTags[this._tag] && ret.charAt(0) === '\\n') {\n      // text/html ignores the first character in these tags if it's a newline\n      // Prefer to break application/xml over text/html (for now) by adding\n      // a newline specifically to get eaten by the parser. (Alternately for\n      // textareas, replacing \"^\\n\" with \"\\r\\n\" doesn't get eaten, and the first\n      // \\r is normalized out by HTMLTextAreaElement#value.)\n      // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre>\n      // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions>\n      // See: <http://www.w3.org/TR/html5/syntax.html#newlines>\n      // See: Parsing of \"textarea\" \"listing\" and \"pre\" elements\n      //  from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody>\n      return '\\n' + ret;\n    } else {\n      return ret;\n    }\n  },\n\n  _createInitialChildren: function (transaction, props, context, el) {\n    // Intentional use of != to avoid catching zero/false.\n    var innerHTML = props.dangerouslySetInnerHTML;\n    if (innerHTML != null) {\n      if (innerHTML.__html != null) {\n        setInnerHTML(el, innerHTML.__html);\n      }\n    } else {\n      var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;\n      var childrenToUse = contentToUse != null ? null : props.children;\n      if (contentToUse != null) {\n        // TODO: Validate that text is allowed as a child of this node\n        setTextContent(el, contentToUse);\n      } else if (childrenToUse != null) {\n        var mountImages = this.mountChildren(childrenToUse, transaction, context);\n        for (var i = 0; i < mountImages.length; i++) {\n          el.appendChild(mountImages[i]);\n        }\n      }\n    }\n  },\n\n  /**\n   * Receives a next element and updates the component.\n   *\n   * @internal\n   * @param {ReactElement} nextElement\n   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n   * @param {object} context\n   */\n  receiveComponent: function (nextElement, transaction, context) {\n    var prevElement = this._currentElement;\n    this._currentElement = nextElement;\n    this.updateComponent(transaction, prevElement, nextElement, context);\n  },\n\n  /**\n   * Updates a native DOM component after it has already been allocated and\n   * attached to the DOM. Reconciles the root DOM node, then recurses.\n   *\n   * @param {ReactReconcileTransaction} transaction\n   * @param {ReactElement} prevElement\n   * @param {ReactElement} nextElement\n   * @internal\n   * @overridable\n   */\n  updateComponent: function (transaction, prevElement, nextElement, context) {\n    var lastProps = prevElement.props;\n    var nextProps = this._currentElement.props;\n\n    switch (this._tag) {\n      case 'button':\n        lastProps = ReactDOMButton.getNativeProps(this, lastProps);\n        nextProps = ReactDOMButton.getNativeProps(this, nextProps);\n        break;\n      case 'input':\n        ReactDOMInput.updateWrapper(this);\n        lastProps = ReactDOMInput.getNativeProps(this, lastProps);\n        nextProps = ReactDOMInput.getNativeProps(this, nextProps);\n        break;\n      case 'option':\n        lastProps = ReactDOMOption.getNativeProps(this, lastProps);\n        nextProps = ReactDOMOption.getNativeProps(this, nextProps);\n        break;\n      case 'select':\n        lastProps = ReactDOMSelect.getNativeProps(this, lastProps);\n        nextProps = ReactDOMSelect.getNativeProps(this, nextProps);\n        break;\n      case 'textarea':\n        ReactDOMTextarea.updateWrapper(this);\n        lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);\n        nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);\n        break;\n    }\n\n    if (process.env.NODE_ENV !== 'production') {\n      // If the context is reference-equal to the old one, pass down the same\n      // processed object so the update bailout in ReactReconciler behaves\n      // correctly (and identically in dev and prod). See #5005.\n      if (this._unprocessedContextDev !== context) {\n        this._unprocessedContextDev = context;\n        this._processedContextDev = processChildContextDev(context, this);\n      }\n      context = this._processedContextDev;\n    }\n\n    assertValidProps(this, nextProps);\n    this._updateDOMProperties(lastProps, nextProps, transaction, null);\n    this._updateDOMChildren(lastProps, nextProps, transaction, context);\n\n    if (!canDefineProperty && this._nodeWithLegacyProperties) {\n      this._nodeWithLegacyProperties.props = nextProps;\n    }\n\n    if (this._tag === 'select') {\n      // <select> value update needs to occur after <option> children\n      // reconciliation\n      transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);\n    }\n  },\n\n  /**\n   * Reconciles the properties by detecting differences in property values and\n   * updating the DOM as necessary. This function is probably the single most\n   * critical path for performance optimization.\n   *\n   * TODO: Benchmark whether checking for changed values in memory actually\n   *       improves performance (especially statically positioned elements).\n   * TODO: Benchmark the effects of putting this at the top since 99% of props\n   *       do not change for a given reconciliation.\n   * TODO: Benchmark areas that can be improved with caching.\n   *\n   * @private\n   * @param {object} lastProps\n   * @param {object} nextProps\n   * @param {ReactReconcileTransaction} transaction\n   * @param {?DOMElement} node\n   */\n  _updateDOMProperties: function (lastProps, nextProps, transaction, node) {\n    var propKey;\n    var styleName;\n    var styleUpdates;\n    for (propKey in lastProps) {\n      if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey)) {\n        continue;\n      }\n      if (propKey === STYLE) {\n        var lastStyle = this._previousStyleCopy;\n        for (styleName in lastStyle) {\n          if (lastStyle.hasOwnProperty(styleName)) {\n            styleUpdates = styleUpdates || {};\n            styleUpdates[styleName] = '';\n          }\n        }\n        this._previousStyleCopy = null;\n      } else if (registrationNameModules.hasOwnProperty(propKey)) {\n        if (lastProps[propKey]) {\n          // Only call deleteListener if there was a listener previously or\n          // else willDeleteListener gets called when there wasn't actually a\n          // listener (e.g., onClick={null})\n          deleteListener(this._rootNodeID, propKey);\n        }\n      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {\n        if (!node) {\n          node = ReactMount.getNode(this._rootNodeID);\n        }\n        DOMPropertyOperations.deleteValueForProperty(node, propKey);\n      }\n    }\n    for (propKey in nextProps) {\n      var nextProp = nextProps[propKey];\n      var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps[propKey];\n      if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {\n        continue;\n      }\n      if (propKey === STYLE) {\n        if (nextProp) {\n          if (process.env.NODE_ENV !== 'production') {\n            checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);\n            this._previousStyle = nextProp;\n          }\n          nextProp = this._previousStyleCopy = assign({}, nextProp);\n        } else {\n          this._previousStyleCopy = null;\n        }\n        if (lastProp) {\n          // Unset styles on `lastProp` but not on `nextProp`.\n          for (styleName in lastProp) {\n            if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {\n              styleUpdates = styleUpdates || {};\n              styleUpdates[styleName] = '';\n            }\n          }\n          // Update styles that changed since `lastProp`.\n          for (styleName in nextProp) {\n            if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {\n              styleUpdates = styleUpdates || {};\n              styleUpdates[styleName] = nextProp[styleName];\n            }\n          }\n        } else {\n          // Relies on `updateStylesByID` not mutating `styleUpdates`.\n          styleUpdates = nextProp;\n        }\n      } else if (registrationNameModules.hasOwnProperty(propKey)) {\n        if (nextProp) {\n          enqueuePutListener(this._rootNodeID, propKey, nextProp, transaction);\n        } else if (lastProp) {\n          deleteListener(this._rootNodeID, propKey);\n        }\n      } else if (isCustomComponent(this._tag, nextProps)) {\n        if (!node) {\n          node = ReactMount.getNode(this._rootNodeID);\n        }\n        if (propKey === CHILDREN) {\n          nextProp = null;\n        }\n        DOMPropertyOperations.setValueForAttribute(node, propKey, nextProp);\n      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {\n        if (!node) {\n          node = ReactMount.getNode(this._rootNodeID);\n        }\n        // If we're updating to null or undefined, we should remove the property\n        // from the DOM node instead of inadvertantly setting to a string. This\n        // brings us in line with the same behavior we have on initial render.\n        if (nextProp != null) {\n          DOMPropertyOperations.setValueForProperty(node, propKey, nextProp);\n        } else {\n          DOMPropertyOperations.deleteValueForProperty(node, propKey);\n        }\n      }\n    }\n    if (styleUpdates) {\n      if (!node) {\n        node = ReactMount.getNode(this._rootNodeID);\n      }\n      CSSPropertyOperations.setValueForStyles(node, styleUpdates);\n    }\n  },\n\n  /**\n   * Reconciles the children with the various properties that affect the\n   * children content.\n   *\n   * @param {object} lastProps\n   * @param {object} nextProps\n   * @param {ReactReconcileTransaction} transaction\n   * @param {object} context\n   */\n  _updateDOMChildren: function (lastProps, nextProps, transaction, context) {\n    var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;\n    var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;\n\n    var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html;\n    var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html;\n\n    // Note the use of `!=` which checks for null or undefined.\n    var lastChildren = lastContent != null ? null : lastProps.children;\n    var nextChildren = nextContent != null ? null : nextProps.children;\n\n    // If we're switching from children to content/html or vice versa, remove\n    // the old content\n    var lastHasContentOrHtml = lastContent != null || lastHtml != null;\n    var nextHasContentOrHtml = nextContent != null || nextHtml != null;\n    if (lastChildren != null && nextChildren == null) {\n      this.updateChildren(null, transaction, context);\n    } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {\n      this.updateTextContent('');\n    }\n\n    if (nextContent != null) {\n      if (lastContent !== nextContent) {\n        this.updateTextContent('' + nextContent);\n      }\n    } else if (nextHtml != null) {\n      if (lastHtml !== nextHtml) {\n        this.updateMarkup('' + nextHtml);\n      }\n    } else if (nextChildren != null) {\n      this.updateChildren(nextChildren, transaction, context);\n    }\n  },\n\n  /**\n   * Destroys all event registrations for this instance. Does not remove from\n   * the DOM. That must be done by the parent.\n   *\n   * @internal\n   */\n  unmountComponent: function () {\n    switch (this._tag) {\n      case 'iframe':\n      case 'img':\n      case 'form':\n      case 'video':\n      case 'audio':\n        var listeners = this._wrapperState.listeners;\n        if (listeners) {\n          for (var i = 0; i < listeners.length; i++) {\n            listeners[i].remove();\n          }\n        }\n        break;\n      case 'input':\n        ReactDOMInput.unmountWrapper(this);\n        break;\n      case 'html':\n      case 'head':\n      case 'body':\n        /**\n         * Components like <html> <head> and <body> can't be removed or added\n         * easily in a cross-browser way, however it's valuable to be able to\n         * take advantage of React's reconciliation for styling and <title>\n         * management. So we just document it and throw in dangerous cases.\n         */\n        !false ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is ' + 'impossible to unmount some top-level components (eg <html>, ' + '<head>, and <body>) reliably and efficiently. To fix this, have a ' + 'single top-level component that never unmounts render these ' + 'elements.', this._tag) : invariant(false) : undefined;\n        break;\n    }\n\n    this.unmountChildren();\n    ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);\n    ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);\n    this._rootNodeID = null;\n    this._wrapperState = null;\n    if (this._nodeWithLegacyProperties) {\n      var node = this._nodeWithLegacyProperties;\n      node._reactInternalComponent = null;\n      this._nodeWithLegacyProperties = null;\n    }\n  },\n\n  getPublicInstance: function () {\n    if (!this._nodeWithLegacyProperties) {\n      var node = ReactMount.getNode(this._rootNodeID);\n\n      node._reactInternalComponent = this;\n      node.getDOMNode = legacyGetDOMNode;\n      node.isMounted = legacyIsMounted;\n      node.setState = legacySetStateEtc;\n      node.replaceState = legacySetStateEtc;\n      node.forceUpdate = legacySetStateEtc;\n      node.setProps = legacySetProps;\n      node.replaceProps = legacyReplaceProps;\n\n      if (process.env.NODE_ENV !== 'production') {\n        if (canDefineProperty) {\n          Object.defineProperties(node, legacyPropsDescriptor);\n        } else {\n          // updateComponent will update this property on subsequent renders\n          node.props = this._currentElement.props;\n        }\n      } else {\n        // updateComponent will update this property on subsequent renders\n        node.props = this._currentElement.props;\n      }\n\n      this._nodeWithLegacyProperties = node;\n    }\n    return this._nodeWithLegacyProperties;\n  }\n\n};\n\nReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {\n  mountComponent: 'mountComponent',\n  updateComponent: 'updateComponent'\n});\n\nassign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin);\n\nmodule.exports = ReactDOMComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMComponent.js\n ** module id = 107\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule AutoFocusUtils\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactMount = require('./ReactMount');\n\nvar findDOMNode = require('./findDOMNode');\nvar focusNode = require('fbjs/lib/focusNode');\n\nvar Mixin = {\n  componentDidMount: function () {\n    if (this.props.autoFocus) {\n      focusNode(findDOMNode(this));\n    }\n  }\n};\n\nvar AutoFocusUtils = {\n  Mixin: Mixin,\n\n  focusDOMComponent: function () {\n    focusNode(ReactMount.getNode(this._rootNodeID));\n  }\n};\n\nmodule.exports = AutoFocusUtils;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/AutoFocusUtils.js\n ** module id = 108\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule focusNode\n */\n\n'use strict';\n\n/**\n * @param {DOMElement} node input/textarea to focus\n */\nfunction focusNode(node) {\n  // IE8 can throw \"Can't move focus to the control because it is invisible,\n  // not enabled, or of a type that does not accept the focus.\" for all kinds of\n  // reasons that are too expensive and fragile to test.\n  try {\n    node.focus();\n  } catch (e) {}\n}\n\nmodule.exports = focusNode;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/focusNode.js\n ** module id = 109\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule CSSPropertyOperations\n * @typechecks static-only\n */\n\n'use strict';\n\nvar CSSProperty = require('./CSSProperty');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar ReactPerf = require('./ReactPerf');\n\nvar camelizeStyleName = require('fbjs/lib/camelizeStyleName');\nvar dangerousStyleValue = require('./dangerousStyleValue');\nvar hyphenateStyleName = require('fbjs/lib/hyphenateStyleName');\nvar memoizeStringOnly = require('fbjs/lib/memoizeStringOnly');\nvar warning = require('fbjs/lib/warning');\n\nvar processStyleName = memoizeStringOnly(function (styleName) {\n  return hyphenateStyleName(styleName);\n});\n\nvar hasShorthandPropertyBug = false;\nvar styleFloatAccessor = 'cssFloat';\nif (ExecutionEnvironment.canUseDOM) {\n  var tempStyle = document.createElement('div').style;\n  try {\n    // IE8 throws \"Invalid argument.\" if resetting shorthand style properties.\n    tempStyle.font = '';\n  } catch (e) {\n    hasShorthandPropertyBug = true;\n  }\n  // IE8 only supports accessing cssFloat (standard) as styleFloat\n  if (document.documentElement.style.cssFloat === undefined) {\n    styleFloatAccessor = 'styleFloat';\n  }\n}\n\nif (process.env.NODE_ENV !== 'production') {\n  // 'msTransform' is correct, but the other prefixes should be capitalized\n  var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;\n\n  // style values shouldn't contain a semicolon\n  var badStyleValueWithSemicolonPattern = /;\\s*$/;\n\n  var warnedStyleNames = {};\n  var warnedStyleValues = {};\n\n  var warnHyphenatedStyleName = function (name) {\n    if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {\n      return;\n    }\n\n    warnedStyleNames[name] = true;\n    process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?', name, camelizeStyleName(name)) : undefined;\n  };\n\n  var warnBadVendoredStyleName = function (name) {\n    if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {\n      return;\n    }\n\n    warnedStyleNames[name] = true;\n    process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)) : undefined;\n  };\n\n  var warnStyleValueWithSemicolon = function (name, value) {\n    if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {\n      return;\n    }\n\n    warnedStyleValues[value] = true;\n    process.env.NODE_ENV !== 'production' ? warning(false, 'Style property values shouldn\\'t contain a semicolon. ' + 'Try \"%s: %s\" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')) : undefined;\n  };\n\n  /**\n   * @param {string} name\n   * @param {*} value\n   */\n  var warnValidStyle = function (name, value) {\n    if (name.indexOf('-') > -1) {\n      warnHyphenatedStyleName(name);\n    } else if (badVendoredStyleNamePattern.test(name)) {\n      warnBadVendoredStyleName(name);\n    } else if (badStyleValueWithSemicolonPattern.test(value)) {\n      warnStyleValueWithSemicolon(name, value);\n    }\n  };\n}\n\n/**\n * Operations for dealing with CSS properties.\n */\nvar CSSPropertyOperations = {\n\n  /**\n   * Serializes a mapping of style properties for use as inline styles:\n   *\n   *   > createMarkupForStyles({width: '200px', height: 0})\n   *   \"width:200px;height:0;\"\n   *\n   * Undefined values are ignored so that declarative programming is easier.\n   * The result should be HTML-escaped before insertion into the DOM.\n   *\n   * @param {object} styles\n   * @return {?string}\n   */\n  createMarkupForStyles: function (styles) {\n    var serialized = '';\n    for (var styleName in styles) {\n      if (!styles.hasOwnProperty(styleName)) {\n        continue;\n      }\n      var styleValue = styles[styleName];\n      if (process.env.NODE_ENV !== 'production') {\n        warnValidStyle(styleName, styleValue);\n      }\n      if (styleValue != null) {\n        serialized += processStyleName(styleName) + ':';\n        serialized += dangerousStyleValue(styleName, styleValue) + ';';\n      }\n    }\n    return serialized || null;\n  },\n\n  /**\n   * Sets the value for multiple styles on a node.  If a value is specified as\n   * '' (empty string), the corresponding style property will be unset.\n   *\n   * @param {DOMElement} node\n   * @param {object} styles\n   */\n  setValueForStyles: function (node, styles) {\n    var style = node.style;\n    for (var styleName in styles) {\n      if (!styles.hasOwnProperty(styleName)) {\n        continue;\n      }\n      if (process.env.NODE_ENV !== 'production') {\n        warnValidStyle(styleName, styles[styleName]);\n      }\n      var styleValue = dangerousStyleValue(styleName, styles[styleName]);\n      if (styleName === 'float') {\n        styleName = styleFloatAccessor;\n      }\n      if (styleValue) {\n        style[styleName] = styleValue;\n      } else {\n        var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName];\n        if (expansion) {\n          // Shorthand property that IE8 won't like unsetting, so unset each\n          // component to placate it\n          for (var individualStyleName in expansion) {\n            style[individualStyleName] = '';\n          }\n        } else {\n          style[styleName] = '';\n        }\n      }\n    }\n  }\n\n};\n\nReactPerf.measureMethods(CSSPropertyOperations, 'CSSPropertyOperations', {\n  setValueForStyles: 'setValueForStyles'\n});\n\nmodule.exports = CSSPropertyOperations;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/CSSPropertyOperations.js\n ** module id = 110\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule CSSProperty\n */\n\n'use strict';\n\n/**\n * CSS properties which accept numbers but are not in units of \"px\".\n */\nvar isUnitlessNumber = {\n  animationIterationCount: true,\n  boxFlex: true,\n  boxFlexGroup: true,\n  boxOrdinalGroup: true,\n  columnCount: true,\n  flex: true,\n  flexGrow: true,\n  flexPositive: true,\n  flexShrink: true,\n  flexNegative: true,\n  flexOrder: true,\n  fontWeight: true,\n  lineClamp: true,\n  lineHeight: true,\n  opacity: true,\n  order: true,\n  orphans: true,\n  tabSize: true,\n  widows: true,\n  zIndex: true,\n  zoom: true,\n\n  // SVG-related properties\n  fillOpacity: true,\n  stopOpacity: true,\n  strokeDashoffset: true,\n  strokeOpacity: true,\n  strokeWidth: true\n};\n\n/**\n * @param {string} prefix vendor-specific prefix, eg: Webkit\n * @param {string} key style name, eg: transitionDuration\n * @return {string} style name prefixed with `prefix`, properly camelCased, eg:\n * WebkitTransitionDuration\n */\nfunction prefixKey(prefix, key) {\n  return prefix + key.charAt(0).toUpperCase() + key.substring(1);\n}\n\n/**\n * Support style names that may come passed in prefixed by adding permutations\n * of vendor prefixes.\n */\nvar prefixes = ['Webkit', 'ms', 'Moz', 'O'];\n\n// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an\n// infinite loop, because it iterates over the newly added props too.\nObject.keys(isUnitlessNumber).forEach(function (prop) {\n  prefixes.forEach(function (prefix) {\n    isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];\n  });\n});\n\n/**\n * Most style properties can be unset by doing .style[prop] = '' but IE8\n * doesn't like doing that with shorthand properties so for the properties that\n * IE8 breaks on, which are listed here, we instead unset each of the\n * individual properties. See http://bugs.jquery.com/ticket/12385.\n * The 4-value 'clock' properties like margin, padding, border-width seem to\n * behave without any problems. Curiously, list-style works too without any\n * special prodding.\n */\nvar shorthandPropertyExpansions = {\n  background: {\n    backgroundAttachment: true,\n    backgroundColor: true,\n    backgroundImage: true,\n    backgroundPositionX: true,\n    backgroundPositionY: true,\n    backgroundRepeat: true\n  },\n  backgroundPosition: {\n    backgroundPositionX: true,\n    backgroundPositionY: true\n  },\n  border: {\n    borderWidth: true,\n    borderStyle: true,\n    borderColor: true\n  },\n  borderBottom: {\n    borderBottomWidth: true,\n    borderBottomStyle: true,\n    borderBottomColor: true\n  },\n  borderLeft: {\n    borderLeftWidth: true,\n    borderLeftStyle: true,\n    borderLeftColor: true\n  },\n  borderRight: {\n    borderRightWidth: true,\n    borderRightStyle: true,\n    borderRightColor: true\n  },\n  borderTop: {\n    borderTopWidth: true,\n    borderTopStyle: true,\n    borderTopColor: true\n  },\n  font: {\n    fontStyle: true,\n    fontVariant: true,\n    fontWeight: true,\n    fontSize: true,\n    lineHeight: true,\n    fontFamily: true\n  },\n  outline: {\n    outlineWidth: true,\n    outlineStyle: true,\n    outlineColor: true\n  }\n};\n\nvar CSSProperty = {\n  isUnitlessNumber: isUnitlessNumber,\n  shorthandPropertyExpansions: shorthandPropertyExpansions\n};\n\nmodule.exports = CSSProperty;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/CSSProperty.js\n ** module id = 111\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule camelizeStyleName\n * @typechecks\n */\n\n'use strict';\n\nvar camelize = require('./camelize');\n\nvar msPattern = /^-ms-/;\n\n/**\n * Camelcases a hyphenated CSS property name, for example:\n *\n *   > camelizeStyleName('background-color')\n *   < \"backgroundColor\"\n *   > camelizeStyleName('-moz-transition')\n *   < \"MozTransition\"\n *   > camelizeStyleName('-ms-transition')\n *   < \"msTransition\"\n *\n * As Andi Smith suggests\n * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix\n * is converted to lowercase `ms`.\n *\n * @param {string} string\n * @return {string}\n */\nfunction camelizeStyleName(string) {\n  return camelize(string.replace(msPattern, 'ms-'));\n}\n\nmodule.exports = camelizeStyleName;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/camelizeStyleName.js\n ** module id = 112\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule camelize\n * @typechecks\n */\n\n\"use strict\";\n\nvar _hyphenPattern = /-(.)/g;\n\n/**\n * Camelcases a hyphenated string, for example:\n *\n *   > camelize('background-color')\n *   < \"backgroundColor\"\n *\n * @param {string} string\n * @return {string}\n */\nfunction camelize(string) {\n  return string.replace(_hyphenPattern, function (_, character) {\n    return character.toUpperCase();\n  });\n}\n\nmodule.exports = camelize;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/camelize.js\n ** module id = 113\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule dangerousStyleValue\n * @typechecks static-only\n */\n\n'use strict';\n\nvar CSSProperty = require('./CSSProperty');\n\nvar isUnitlessNumber = CSSProperty.isUnitlessNumber;\n\n/**\n * Convert a value into the proper css writable value. The style name `name`\n * should be logical (no hyphens), as specified\n * in `CSSProperty.isUnitlessNumber`.\n *\n * @param {string} name CSS property name such as `topMargin`.\n * @param {*} value CSS property value such as `10px`.\n * @return {string} Normalized style value with dimensions applied.\n */\nfunction dangerousStyleValue(name, value) {\n  // Note that we've removed escapeTextForBrowser() calls here since the\n  // whole string will be escaped when the attribute is injected into\n  // the markup. If you provide unsafe user data here they can inject\n  // arbitrary CSS which may be problematic (I couldn't repro this):\n  // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet\n  // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/\n  // This is not an XSS hole but instead a potential CSS injection issue\n  // which has lead to a greater discussion about how we're going to\n  // trust URLs moving forward. See #2115901\n\n  var isEmpty = value == null || typeof value === 'boolean' || value === '';\n  if (isEmpty) {\n    return '';\n  }\n\n  var isNonNumeric = isNaN(value);\n  if (isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) {\n    return '' + value; // cast to string\n  }\n\n  if (typeof value === 'string') {\n    value = value.trim();\n  }\n  return value + 'px';\n}\n\nmodule.exports = dangerousStyleValue;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/dangerousStyleValue.js\n ** module id = 114\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule hyphenateStyleName\n * @typechecks\n */\n\n'use strict';\n\nvar hyphenate = require('./hyphenate');\n\nvar msPattern = /^ms-/;\n\n/**\n * Hyphenates a camelcased CSS property name, for example:\n *\n *   > hyphenateStyleName('backgroundColor')\n *   < \"background-color\"\n *   > hyphenateStyleName('MozTransition')\n *   < \"-moz-transition\"\n *   > hyphenateStyleName('msTransition')\n *   < \"-ms-transition\"\n *\n * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix\n * is converted to `-ms-`.\n *\n * @param {string} string\n * @return {string}\n */\nfunction hyphenateStyleName(string) {\n  return hyphenate(string).replace(msPattern, '-ms-');\n}\n\nmodule.exports = hyphenateStyleName;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/hyphenateStyleName.js\n ** module id = 115\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule hyphenate\n * @typechecks\n */\n\n'use strict';\n\nvar _uppercasePattern = /([A-Z])/g;\n\n/**\n * Hyphenates a camelcased string, for example:\n *\n *   > hyphenate('backgroundColor')\n *   < \"background-color\"\n *\n * For CSS style names, use `hyphenateStyleName` instead which works properly\n * with all vendor prefixes, including `ms`.\n *\n * @param {string} string\n * @return {string}\n */\nfunction hyphenate(string) {\n  return string.replace(_uppercasePattern, '-$1').toLowerCase();\n}\n\nmodule.exports = hyphenate;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/hyphenate.js\n ** module id = 116\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule memoizeStringOnly\n * @typechecks static-only\n */\n\n'use strict';\n\n/**\n * Memoizes the return value of a function that accepts one string argument.\n *\n * @param {function} callback\n * @return {function}\n */\nfunction memoizeStringOnly(callback) {\n  var cache = {};\n  return function (string) {\n    if (!cache.hasOwnProperty(string)) {\n      cache[string] = callback.call(this, string);\n    }\n    return cache[string];\n  };\n}\n\nmodule.exports = memoizeStringOnly;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/memoizeStringOnly.js\n ** module id = 117\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMButton\n */\n\n'use strict';\n\nvar mouseListenerNames = {\n  onClick: true,\n  onDoubleClick: true,\n  onMouseDown: true,\n  onMouseMove: true,\n  onMouseUp: true,\n\n  onClickCapture: true,\n  onDoubleClickCapture: true,\n  onMouseDownCapture: true,\n  onMouseMoveCapture: true,\n  onMouseUpCapture: true\n};\n\n/**\n * Implements a <button> native component that does not receive mouse events\n * when `disabled` is set.\n */\nvar ReactDOMButton = {\n  getNativeProps: function (inst, props, context) {\n    if (!props.disabled) {\n      return props;\n    }\n\n    // Copy the props, except the mouse listeners\n    var nativeProps = {};\n    for (var key in props) {\n      if (props.hasOwnProperty(key) && !mouseListenerNames[key]) {\n        nativeProps[key] = props[key];\n      }\n    }\n\n    return nativeProps;\n  }\n};\n\nmodule.exports = ReactDOMButton;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMButton.js\n ** module id = 118\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMInput\n */\n\n'use strict';\n\nvar ReactDOMIDOperations = require('./ReactDOMIDOperations');\nvar LinkedValueUtils = require('./LinkedValueUtils');\nvar ReactMount = require('./ReactMount');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\n\nvar instancesByReactID = {};\n\nfunction forceUpdateIfMounted() {\n  if (this._rootNodeID) {\n    // DOM component is still mounted; update\n    ReactDOMInput.updateWrapper(this);\n  }\n}\n\n/**\n * Implements an <input> native component that allows setting these optional\n * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.\n *\n * If `checked` or `value` are not supplied (or null/undefined), user actions\n * that affect the checked state or value will trigger updates to the element.\n *\n * If they are supplied (and not null/undefined), the rendered element will not\n * trigger updates to the element. Instead, the props must change in order for\n * the rendered element to be updated.\n *\n * The rendered element will be initialized as unchecked (or `defaultChecked`)\n * with an empty value (or `defaultValue`).\n *\n * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html\n */\nvar ReactDOMInput = {\n  getNativeProps: function (inst, props, context) {\n    var value = LinkedValueUtils.getValue(props);\n    var checked = LinkedValueUtils.getChecked(props);\n\n    var nativeProps = assign({}, props, {\n      defaultChecked: undefined,\n      defaultValue: undefined,\n      value: value != null ? value : inst._wrapperState.initialValue,\n      checked: checked != null ? checked : inst._wrapperState.initialChecked,\n      onChange: inst._wrapperState.onChange\n    });\n\n    return nativeProps;\n  },\n\n  mountWrapper: function (inst, props) {\n    if (process.env.NODE_ENV !== 'production') {\n      LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner);\n    }\n\n    var defaultValue = props.defaultValue;\n    inst._wrapperState = {\n      initialChecked: props.defaultChecked || false,\n      initialValue: defaultValue != null ? defaultValue : null,\n      onChange: _handleChange.bind(inst)\n    };\n  },\n\n  mountReadyWrapper: function (inst) {\n    // Can't be in mountWrapper or else server rendering leaks.\n    instancesByReactID[inst._rootNodeID] = inst;\n  },\n\n  unmountWrapper: function (inst) {\n    delete instancesByReactID[inst._rootNodeID];\n  },\n\n  updateWrapper: function (inst) {\n    var props = inst._currentElement.props;\n\n    // TODO: Shouldn't this be getChecked(props)?\n    var checked = props.checked;\n    if (checked != null) {\n      ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'checked', checked || false);\n    }\n\n    var value = LinkedValueUtils.getValue(props);\n    if (value != null) {\n      // Cast `value` to a string to ensure the value is set correctly. While\n      // browsers typically do this as necessary, jsdom doesn't.\n      ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);\n    }\n  }\n};\n\nfunction _handleChange(event) {\n  var props = this._currentElement.props;\n\n  var returnValue = LinkedValueUtils.executeOnChange(props, event);\n\n  // Here we use asap to wait until all updates have propagated, which\n  // is important when using controlled components within layers:\n  // https://github.com/facebook/react/issues/1698\n  ReactUpdates.asap(forceUpdateIfMounted, this);\n\n  var name = props.name;\n  if (props.type === 'radio' && name != null) {\n    var rootNode = ReactMount.getNode(this._rootNodeID);\n    var queryRoot = rootNode;\n\n    while (queryRoot.parentNode) {\n      queryRoot = queryRoot.parentNode;\n    }\n\n    // If `rootNode.form` was non-null, then we could try `form.elements`,\n    // but that sometimes behaves strangely in IE8. We could also try using\n    // `form.getElementsByName`, but that will only return direct children\n    // and won't include inputs that use the HTML5 `form=` attribute. Since\n    // the input might not even be in a form, let's just use the global\n    // `querySelectorAll` to ensure we don't miss anything.\n    var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type=\"radio\"]');\n\n    for (var i = 0; i < group.length; i++) {\n      var otherNode = group[i];\n      if (otherNode === rootNode || otherNode.form !== rootNode.form) {\n        continue;\n      }\n      // This will throw if radio buttons rendered by different copies of React\n      // and the same name are rendered into the same form (same as #1939).\n      // That's probably okay; we don't support it just as we don't support\n      // mixing React with non-React.\n      var otherID = ReactMount.getID(otherNode);\n      !otherID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : undefined;\n      var otherInstance = instancesByReactID[otherID];\n      !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined;\n      // If this is a controlled radio button group, forcing the input that\n      // was previously checked to update will cause it to be come re-checked\n      // as appropriate.\n      ReactUpdates.asap(forceUpdateIfMounted, otherInstance);\n    }\n  }\n\n  return returnValue;\n}\n\nmodule.exports = ReactDOMInput;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMInput.js\n ** module id = 119\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule LinkedValueUtils\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactPropTypes = require('./ReactPropTypes');\nvar ReactPropTypeLocations = require('./ReactPropTypeLocations');\n\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\nvar hasReadOnlyValue = {\n  'button': true,\n  'checkbox': true,\n  'image': true,\n  'hidden': true,\n  'radio': true,\n  'reset': true,\n  'submit': true\n};\n\nfunction _assertSingleLink(inputProps) {\n  !(inputProps.checkedLink == null || inputProps.valueLink == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use ' + 'checkedLink, you probably don\\'t want to use valueLink and vice versa.') : invariant(false) : undefined;\n}\nfunction _assertValueLink(inputProps) {\n  _assertSingleLink(inputProps);\n  !(inputProps.value == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want ' + 'to use value or onChange, you probably don\\'t want to use valueLink.') : invariant(false) : undefined;\n}\n\nfunction _assertCheckedLink(inputProps) {\n  _assertSingleLink(inputProps);\n  !(inputProps.checked == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. ' + 'If you want to use checked or onChange, you probably don\\'t want to ' + 'use checkedLink') : invariant(false) : undefined;\n}\n\nvar propTypes = {\n  value: function (props, propName, componentName) {\n    if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {\n      return null;\n    }\n    return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');\n  },\n  checked: function (props, propName, componentName) {\n    if (!props[propName] || props.onChange || props.readOnly || props.disabled) {\n      return null;\n    }\n    return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');\n  },\n  onChange: ReactPropTypes.func\n};\n\nvar loggedTypeFailures = {};\nfunction getDeclarationErrorAddendum(owner) {\n  if (owner) {\n    var name = owner.getName();\n    if (name) {\n      return ' Check the render method of `' + name + '`.';\n    }\n  }\n  return '';\n}\n\n/**\n * Provide a linked `value` attribute for controlled forms. You should not use\n * this outside of the ReactDOM controlled form components.\n */\nvar LinkedValueUtils = {\n  checkPropTypes: function (tagName, props, owner) {\n    for (var propName in propTypes) {\n      if (propTypes.hasOwnProperty(propName)) {\n        var error = propTypes[propName](props, propName, tagName, ReactPropTypeLocations.prop);\n      }\n      if (error instanceof Error && !(error.message in loggedTypeFailures)) {\n        // Only monitor this failure once because there tends to be a lot of the\n        // same error.\n        loggedTypeFailures[error.message] = true;\n\n        var addendum = getDeclarationErrorAddendum(owner);\n        process.env.NODE_ENV !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : undefined;\n      }\n    }\n  },\n\n  /**\n   * @param {object} inputProps Props for form component\n   * @return {*} current value of the input either from value prop or link.\n   */\n  getValue: function (inputProps) {\n    if (inputProps.valueLink) {\n      _assertValueLink(inputProps);\n      return inputProps.valueLink.value;\n    }\n    return inputProps.value;\n  },\n\n  /**\n   * @param {object} inputProps Props for form component\n   * @return {*} current checked status of the input either from checked prop\n   *             or link.\n   */\n  getChecked: function (inputProps) {\n    if (inputProps.checkedLink) {\n      _assertCheckedLink(inputProps);\n      return inputProps.checkedLink.value;\n    }\n    return inputProps.checked;\n  },\n\n  /**\n   * @param {object} inputProps Props for form component\n   * @param {SyntheticEvent} event change event to handle\n   */\n  executeOnChange: function (inputProps, event) {\n    if (inputProps.valueLink) {\n      _assertValueLink(inputProps);\n      return inputProps.valueLink.requestChange(event.target.value);\n    } else if (inputProps.checkedLink) {\n      _assertCheckedLink(inputProps);\n      return inputProps.checkedLink.requestChange(event.target.checked);\n    } else if (inputProps.onChange) {\n      return inputProps.onChange.call(undefined, event);\n    }\n  }\n};\n\nmodule.exports = LinkedValueUtils;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/LinkedValueUtils.js\n ** module id = 120\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactPropTypes\n */\n\n'use strict';\n\nvar ReactElement = require('./ReactElement');\nvar ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');\n\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar getIteratorFn = require('./getIteratorFn');\n\n/**\n * Collection of methods that allow declaration and validation of props that are\n * supplied to React components. Example usage:\n *\n *   var Props = require('ReactPropTypes');\n *   var MyArticle = React.createClass({\n *     propTypes: {\n *       // An optional string prop named \"description\".\n *       description: Props.string,\n *\n *       // A required enum prop named \"category\".\n *       category: Props.oneOf(['News','Photos']).isRequired,\n *\n *       // A prop named \"dialog\" that requires an instance of Dialog.\n *       dialog: Props.instanceOf(Dialog).isRequired\n *     },\n *     render: function() { ... }\n *   });\n *\n * A more formal specification of how these methods are used:\n *\n *   type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)\n *   decl := ReactPropTypes.{type}(.isRequired)?\n *\n * Each and every declaration produces a function with the same signature. This\n * allows the creation of custom validation functions. For example:\n *\n *  var MyLink = React.createClass({\n *    propTypes: {\n *      // An optional string or URI prop named \"href\".\n *      href: function(props, propName, componentName) {\n *        var propValue = props[propName];\n *        if (propValue != null && typeof propValue !== 'string' &&\n *            !(propValue instanceof URI)) {\n *          return new Error(\n *            'Expected a string or an URI for ' + propName + ' in ' +\n *            componentName\n *          );\n *        }\n *      }\n *    },\n *    render: function() {...}\n *  });\n *\n * @internal\n */\n\nvar ANONYMOUS = '<<anonymous>>';\n\nvar ReactPropTypes = {\n  array: createPrimitiveTypeChecker('array'),\n  bool: createPrimitiveTypeChecker('boolean'),\n  func: createPrimitiveTypeChecker('function'),\n  number: createPrimitiveTypeChecker('number'),\n  object: createPrimitiveTypeChecker('object'),\n  string: createPrimitiveTypeChecker('string'),\n\n  any: createAnyTypeChecker(),\n  arrayOf: createArrayOfTypeChecker,\n  element: createElementTypeChecker(),\n  instanceOf: createInstanceTypeChecker,\n  node: createNodeChecker(),\n  objectOf: createObjectOfTypeChecker,\n  oneOf: createEnumTypeChecker,\n  oneOfType: createUnionTypeChecker,\n  shape: createShapeTypeChecker\n};\n\nfunction createChainableTypeChecker(validate) {\n  function checkType(isRequired, props, propName, componentName, location, propFullName) {\n    componentName = componentName || ANONYMOUS;\n    propFullName = propFullName || propName;\n    if (props[propName] == null) {\n      var locationName = ReactPropTypeLocationNames[location];\n      if (isRequired) {\n        return new Error('Required ' + locationName + ' `' + propFullName + '` was not specified in ' + ('`' + componentName + '`.'));\n      }\n      return null;\n    } else {\n      return validate(props, propName, componentName, location, propFullName);\n    }\n  }\n\n  var chainedCheckType = checkType.bind(null, false);\n  chainedCheckType.isRequired = checkType.bind(null, true);\n\n  return chainedCheckType;\n}\n\nfunction createPrimitiveTypeChecker(expectedType) {\n  function validate(props, propName, componentName, location, propFullName) {\n    var propValue = props[propName];\n    var propType = getPropType(propValue);\n    if (propType !== expectedType) {\n      var locationName = ReactPropTypeLocationNames[location];\n      // `propValue` being instance of, say, date/regexp, pass the 'object'\n      // check, but we can offer a more precise error message here rather than\n      // 'of type `object`'.\n      var preciseType = getPreciseType(propValue);\n\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'));\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createAnyTypeChecker() {\n  return createChainableTypeChecker(emptyFunction.thatReturns(null));\n}\n\nfunction createArrayOfTypeChecker(typeChecker) {\n  function validate(props, propName, componentName, location, propFullName) {\n    var propValue = props[propName];\n    if (!Array.isArray(propValue)) {\n      var locationName = ReactPropTypeLocationNames[location];\n      var propType = getPropType(propValue);\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));\n    }\n    for (var i = 0; i < propValue.length; i++) {\n      var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']');\n      if (error instanceof Error) {\n        return error;\n      }\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createElementTypeChecker() {\n  function validate(props, propName, componentName, location, propFullName) {\n    if (!ReactElement.isValidElement(props[propName])) {\n      var locationName = ReactPropTypeLocationNames[location];\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a single ReactElement.'));\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createInstanceTypeChecker(expectedClass) {\n  function validate(props, propName, componentName, location, propFullName) {\n    if (!(props[propName] instanceof expectedClass)) {\n      var locationName = ReactPropTypeLocationNames[location];\n      var expectedClassName = expectedClass.name || ANONYMOUS;\n      var actualClassName = getClassName(props[propName]);\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createEnumTypeChecker(expectedValues) {\n  if (!Array.isArray(expectedValues)) {\n    return createChainableTypeChecker(function () {\n      return new Error('Invalid argument supplied to oneOf, expected an instance of array.');\n    });\n  }\n\n  function validate(props, propName, componentName, location, propFullName) {\n    var propValue = props[propName];\n    for (var i = 0; i < expectedValues.length; i++) {\n      if (propValue === expectedValues[i]) {\n        return null;\n      }\n    }\n\n    var locationName = ReactPropTypeLocationNames[location];\n    var valuesString = JSON.stringify(expectedValues);\n    return new Error('Invalid ' + locationName + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createObjectOfTypeChecker(typeChecker) {\n  function validate(props, propName, componentName, location, propFullName) {\n    var propValue = props[propName];\n    var propType = getPropType(propValue);\n    if (propType !== 'object') {\n      var locationName = ReactPropTypeLocationNames[location];\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));\n    }\n    for (var key in propValue) {\n      if (propValue.hasOwnProperty(key)) {\n        var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key);\n        if (error instanceof Error) {\n          return error;\n        }\n      }\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createUnionTypeChecker(arrayOfTypeCheckers) {\n  if (!Array.isArray(arrayOfTypeCheckers)) {\n    return createChainableTypeChecker(function () {\n      return new Error('Invalid argument supplied to oneOfType, expected an instance of array.');\n    });\n  }\n\n  function validate(props, propName, componentName, location, propFullName) {\n    for (var i = 0; i < arrayOfTypeCheckers.length; i++) {\n      var checker = arrayOfTypeCheckers[i];\n      if (checker(props, propName, componentName, location, propFullName) == null) {\n        return null;\n      }\n    }\n\n    var locationName = ReactPropTypeLocationNames[location];\n    return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createNodeChecker() {\n  function validate(props, propName, componentName, location, propFullName) {\n    if (!isNode(props[propName])) {\n      var locationName = ReactPropTypeLocationNames[location];\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction createShapeTypeChecker(shapeTypes) {\n  function validate(props, propName, componentName, location, propFullName) {\n    var propValue = props[propName];\n    var propType = getPropType(propValue);\n    if (propType !== 'object') {\n      var locationName = ReactPropTypeLocationNames[location];\n      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));\n    }\n    for (var key in shapeTypes) {\n      var checker = shapeTypes[key];\n      if (!checker) {\n        continue;\n      }\n      var error = checker(propValue, key, componentName, location, propFullName + '.' + key);\n      if (error) {\n        return error;\n      }\n    }\n    return null;\n  }\n  return createChainableTypeChecker(validate);\n}\n\nfunction isNode(propValue) {\n  switch (typeof propValue) {\n    case 'number':\n    case 'string':\n    case 'undefined':\n      return true;\n    case 'boolean':\n      return !propValue;\n    case 'object':\n      if (Array.isArray(propValue)) {\n        return propValue.every(isNode);\n      }\n      if (propValue === null || ReactElement.isValidElement(propValue)) {\n        return true;\n      }\n\n      var iteratorFn = getIteratorFn(propValue);\n      if (iteratorFn) {\n        var iterator = iteratorFn.call(propValue);\n        var step;\n        if (iteratorFn !== propValue.entries) {\n          while (!(step = iterator.next()).done) {\n            if (!isNode(step.value)) {\n              return false;\n            }\n          }\n        } else {\n          // Iterator will provide entry [k,v] tuples rather than values.\n          while (!(step = iterator.next()).done) {\n            var entry = step.value;\n            if (entry) {\n              if (!isNode(entry[1])) {\n                return false;\n              }\n            }\n          }\n        }\n      } else {\n        return false;\n      }\n\n      return true;\n    default:\n      return false;\n  }\n}\n\n// Equivalent of `typeof` but with special handling for array and regexp.\nfunction getPropType(propValue) {\n  var propType = typeof propValue;\n  if (Array.isArray(propValue)) {\n    return 'array';\n  }\n  if (propValue instanceof RegExp) {\n    // Old webkits (at least until Android 4.0) return 'function' rather than\n    // 'object' for typeof a RegExp. We'll normalize this here so that /bla/\n    // passes PropTypes.object.\n    return 'object';\n  }\n  return propType;\n}\n\n// This handles more types than `getPropType`. Only used for error messages.\n// See `createPrimitiveTypeChecker`.\nfunction getPreciseType(propValue) {\n  var propType = getPropType(propValue);\n  if (propType === 'object') {\n    if (propValue instanceof Date) {\n      return 'date';\n    } else if (propValue instanceof RegExp) {\n      return 'regexp';\n    }\n  }\n  return propType;\n}\n\n// Returns class name of the object, if any.\nfunction getClassName(propValue) {\n  if (!propValue.constructor || !propValue.constructor.name) {\n    return '<<anonymous>>';\n  }\n  return propValue.constructor.name;\n}\n\nmodule.exports = ReactPropTypes;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactPropTypes.js\n ** module id = 121\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getIteratorFn\n * @typechecks static-only\n */\n\n'use strict';\n\n/* global Symbol */\nvar ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\nvar FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.\n\n/**\n * Returns the iterator method function contained on the iterable object.\n *\n * Be sure to invoke the function with the iterable as context:\n *\n *     var iteratorFn = getIteratorFn(myIterable);\n *     if (iteratorFn) {\n *       var iterator = iteratorFn.call(myIterable);\n *       ...\n *     }\n *\n * @param {?object} maybeIterable\n * @return {?function}\n */\nfunction getIteratorFn(maybeIterable) {\n  var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);\n  if (typeof iteratorFn === 'function') {\n    return iteratorFn;\n  }\n}\n\nmodule.exports = getIteratorFn;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getIteratorFn.js\n ** module id = 122\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMOption\n */\n\n'use strict';\n\nvar ReactChildren = require('./ReactChildren');\nvar ReactDOMSelect = require('./ReactDOMSelect');\n\nvar assign = require('./Object.assign');\nvar warning = require('fbjs/lib/warning');\n\nvar valueContextKey = ReactDOMSelect.valueContextKey;\n\n/**\n * Implements an <option> native component that warns when `selected` is set.\n */\nvar ReactDOMOption = {\n  mountWrapper: function (inst, props, context) {\n    // TODO (yungsters): Remove support for `selected` in <option>.\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : undefined;\n    }\n\n    // Look up whether this option is 'selected' via context\n    var selectValue = context[valueContextKey];\n\n    // If context key is null (e.g., no specified value or after initial mount)\n    // or missing (e.g., for <datalist>), we don't change props.selected\n    var selected = null;\n    if (selectValue != null) {\n      selected = false;\n      if (Array.isArray(selectValue)) {\n        // multiple\n        for (var i = 0; i < selectValue.length; i++) {\n          if ('' + selectValue[i] === '' + props.value) {\n            selected = true;\n            break;\n          }\n        }\n      } else {\n        selected = '' + selectValue === '' + props.value;\n      }\n    }\n\n    inst._wrapperState = { selected: selected };\n  },\n\n  getNativeProps: function (inst, props, context) {\n    var nativeProps = assign({ selected: undefined, children: undefined }, props);\n\n    // Read state only from initial mount because <select> updates value\n    // manually; we need the initial state only for server rendering\n    if (inst._wrapperState.selected != null) {\n      nativeProps.selected = inst._wrapperState.selected;\n    }\n\n    var content = '';\n\n    // Flatten children and warn if they aren't strings or numbers;\n    // invalid types are ignored.\n    ReactChildren.forEach(props.children, function (child) {\n      if (child == null) {\n        return;\n      }\n      if (typeof child === 'string' || typeof child === 'number') {\n        content += child;\n      } else {\n        process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : undefined;\n      }\n    });\n\n    nativeProps.children = content;\n    return nativeProps;\n  }\n\n};\n\nmodule.exports = ReactDOMOption;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMOption.js\n ** module id = 123\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactChildren\n */\n\n'use strict';\n\nvar PooledClass = require('./PooledClass');\nvar ReactElement = require('./ReactElement');\n\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar traverseAllChildren = require('./traverseAllChildren');\n\nvar twoArgumentPooler = PooledClass.twoArgumentPooler;\nvar fourArgumentPooler = PooledClass.fourArgumentPooler;\n\nvar userProvidedKeyEscapeRegex = /\\/(?!\\/)/g;\nfunction escapeUserProvidedKey(text) {\n  return ('' + text).replace(userProvidedKeyEscapeRegex, '//');\n}\n\n/**\n * PooledClass representing the bookkeeping associated with performing a child\n * traversal. Allows avoiding binding callbacks.\n *\n * @constructor ForEachBookKeeping\n * @param {!function} forEachFunction Function to perform traversal with.\n * @param {?*} forEachContext Context to perform context with.\n */\nfunction ForEachBookKeeping(forEachFunction, forEachContext) {\n  this.func = forEachFunction;\n  this.context = forEachContext;\n  this.count = 0;\n}\nForEachBookKeeping.prototype.destructor = function () {\n  this.func = null;\n  this.context = null;\n  this.count = 0;\n};\nPooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);\n\nfunction forEachSingleChild(bookKeeping, child, name) {\n  var func = bookKeeping.func;\n  var context = bookKeeping.context;\n\n  func.call(context, child, bookKeeping.count++);\n}\n\n/**\n * Iterates through children that are typically specified as `props.children`.\n *\n * The provided forEachFunc(child, index) will be called for each\n * leaf child.\n *\n * @param {?*} children Children tree container.\n * @param {function(*, int)} forEachFunc\n * @param {*} forEachContext Context for forEachContext.\n */\nfunction forEachChildren(children, forEachFunc, forEachContext) {\n  if (children == null) {\n    return children;\n  }\n  var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext);\n  traverseAllChildren(children, forEachSingleChild, traverseContext);\n  ForEachBookKeeping.release(traverseContext);\n}\n\n/**\n * PooledClass representing the bookkeeping associated with performing a child\n * mapping. Allows avoiding binding callbacks.\n *\n * @constructor MapBookKeeping\n * @param {!*} mapResult Object containing the ordered map of results.\n * @param {!function} mapFunction Function to perform mapping with.\n * @param {?*} mapContext Context to perform mapping with.\n */\nfunction MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) {\n  this.result = mapResult;\n  this.keyPrefix = keyPrefix;\n  this.func = mapFunction;\n  this.context = mapContext;\n  this.count = 0;\n}\nMapBookKeeping.prototype.destructor = function () {\n  this.result = null;\n  this.keyPrefix = null;\n  this.func = null;\n  this.context = null;\n  this.count = 0;\n};\nPooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler);\n\nfunction mapSingleChildIntoContext(bookKeeping, child, childKey) {\n  var result = bookKeeping.result;\n  var keyPrefix = bookKeeping.keyPrefix;\n  var func = bookKeeping.func;\n  var context = bookKeeping.context;\n\n  var mappedChild = func.call(context, child, bookKeeping.count++);\n  if (Array.isArray(mappedChild)) {\n    mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument);\n  } else if (mappedChild != null) {\n    if (ReactElement.isValidElement(mappedChild)) {\n      mappedChild = ReactElement.cloneAndReplaceKey(mappedChild,\n      // Keep both the (mapped) and old keys if they differ, just as\n      // traverseAllChildren used to do for objects as children\n      keyPrefix + (mappedChild !== child ? escapeUserProvidedKey(mappedChild.key || '') + '/' : '') + childKey);\n    }\n    result.push(mappedChild);\n  }\n}\n\nfunction mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {\n  var escapedPrefix = '';\n  if (prefix != null) {\n    escapedPrefix = escapeUserProvidedKey(prefix) + '/';\n  }\n  var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context);\n  traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);\n  MapBookKeeping.release(traverseContext);\n}\n\n/**\n * Maps children that are typically specified as `props.children`.\n *\n * The provided mapFunction(child, key, index) will be called for each\n * leaf child.\n *\n * @param {?*} children Children tree container.\n * @param {function(*, int)} func The map function.\n * @param {*} context Context for mapFunction.\n * @return {object} Object containing the ordered map of results.\n */\nfunction mapChildren(children, func, context) {\n  if (children == null) {\n    return children;\n  }\n  var result = [];\n  mapIntoWithKeyPrefixInternal(children, result, null, func, context);\n  return result;\n}\n\nfunction forEachSingleChildDummy(traverseContext, child, name) {\n  return null;\n}\n\n/**\n * Count the number of children that are typically specified as\n * `props.children`.\n *\n * @param {?*} children Children tree container.\n * @return {number} The number of children.\n */\nfunction countChildren(children, context) {\n  return traverseAllChildren(children, forEachSingleChildDummy, null);\n}\n\n/**\n * Flatten a children object (typically specified as `props.children`) and\n * return an array with appropriately re-keyed children.\n */\nfunction toArray(children) {\n  var result = [];\n  mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument);\n  return result;\n}\n\nvar ReactChildren = {\n  forEach: forEachChildren,\n  map: mapChildren,\n  mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal,\n  count: countChildren,\n  toArray: toArray\n};\n\nmodule.exports = ReactChildren;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactChildren.js\n ** module id = 124\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule traverseAllChildren\n */\n\n'use strict';\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactElement = require('./ReactElement');\nvar ReactInstanceHandles = require('./ReactInstanceHandles');\n\nvar getIteratorFn = require('./getIteratorFn');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\nvar SEPARATOR = ReactInstanceHandles.SEPARATOR;\nvar SUBSEPARATOR = ':';\n\n/**\n * TODO: Test that a single child and an array with one item have the same key\n * pattern.\n */\n\nvar userProvidedKeyEscaperLookup = {\n  '=': '=0',\n  '.': '=1',\n  ':': '=2'\n};\n\nvar userProvidedKeyEscapeRegex = /[=.:]/g;\n\nvar didWarnAboutMaps = false;\n\nfunction userProvidedKeyEscaper(match) {\n  return userProvidedKeyEscaperLookup[match];\n}\n\n/**\n * Generate a key string that identifies a component within a set.\n *\n * @param {*} component A component that could contain a manual key.\n * @param {number} index Index that is used if a manual key is not provided.\n * @return {string}\n */\nfunction getComponentKey(component, index) {\n  if (component && component.key != null) {\n    // Explicit key\n    return wrapUserProvidedKey(component.key);\n  }\n  // Implicit key determined by the index in the set\n  return index.toString(36);\n}\n\n/**\n * Escape a component key so that it is safe to use in a reactid.\n *\n * @param {*} text Component key to be escaped.\n * @return {string} An escaped string.\n */\nfunction escapeUserProvidedKey(text) {\n  return ('' + text).replace(userProvidedKeyEscapeRegex, userProvidedKeyEscaper);\n}\n\n/**\n * Wrap a `key` value explicitly provided by the user to distinguish it from\n * implicitly-generated keys generated by a component's index in its parent.\n *\n * @param {string} key Value of a user-provided `key` attribute\n * @return {string}\n */\nfunction wrapUserProvidedKey(key) {\n  return '$' + escapeUserProvidedKey(key);\n}\n\n/**\n * @param {?*} children Children tree container.\n * @param {!string} nameSoFar Name of the key path so far.\n * @param {!function} callback Callback to invoke with each child found.\n * @param {?*} traverseContext Used to pass information throughout the traversal\n * process.\n * @return {!number} The number of children in this subtree.\n */\nfunction traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {\n  var type = typeof children;\n\n  if (type === 'undefined' || type === 'boolean') {\n    // All of the above are perceived as null.\n    children = null;\n  }\n\n  if (children === null || type === 'string' || type === 'number' || ReactElement.isValidElement(children)) {\n    callback(traverseContext, children,\n    // If it's the only child, treat the name as if it was wrapped in an array\n    // so that it's consistent if the number of children grows.\n    nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);\n    return 1;\n  }\n\n  var child;\n  var nextName;\n  var subtreeCount = 0; // Count of children found in the current subtree.\n  var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;\n\n  if (Array.isArray(children)) {\n    for (var i = 0; i < children.length; i++) {\n      child = children[i];\n      nextName = nextNamePrefix + getComponentKey(child, i);\n      subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);\n    }\n  } else {\n    var iteratorFn = getIteratorFn(children);\n    if (iteratorFn) {\n      var iterator = iteratorFn.call(children);\n      var step;\n      if (iteratorFn !== children.entries) {\n        var ii = 0;\n        while (!(step = iterator.next()).done) {\n          child = step.value;\n          nextName = nextNamePrefix + getComponentKey(child, ii++);\n          subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);\n        }\n      } else {\n        if (process.env.NODE_ENV !== 'production') {\n          process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.') : undefined;\n          didWarnAboutMaps = true;\n        }\n        // Iterator will provide entry [k,v] tuples rather than values.\n        while (!(step = iterator.next()).done) {\n          var entry = step.value;\n          if (entry) {\n            child = entry[1];\n            nextName = nextNamePrefix + wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0);\n            subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);\n          }\n        }\n      }\n    } else if (type === 'object') {\n      var addendum = '';\n      if (process.env.NODE_ENV !== 'production') {\n        addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.';\n        if (children._isReactElement) {\n          addendum = ' It looks like you\\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.';\n        }\n        if (ReactCurrentOwner.current) {\n          var name = ReactCurrentOwner.current.getName();\n          if (name) {\n            addendum += ' Check the render method of `' + name + '`.';\n          }\n        }\n      }\n      var childrenString = String(children);\n      !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : invariant(false) : undefined;\n    }\n  }\n\n  return subtreeCount;\n}\n\n/**\n * Traverses children that are typically specified as `props.children`, but\n * might also be specified through attributes:\n *\n * - `traverseAllChildren(this.props.children, ...)`\n * - `traverseAllChildren(this.props.leftPanelChildren, ...)`\n *\n * The `traverseContext` is an optional argument that is passed through the\n * entire traversal. It can be used to store accumulations or anything else that\n * the callback might find relevant.\n *\n * @param {?*} children Children tree object.\n * @param {!function} callback To invoke upon traversing each child.\n * @param {?*} traverseContext Context for traversal.\n * @return {!number} The number of children in this subtree.\n */\nfunction traverseAllChildren(children, callback, traverseContext) {\n  if (children == null) {\n    return 0;\n  }\n\n  return traverseAllChildrenImpl(children, '', callback, traverseContext);\n}\n\nmodule.exports = traverseAllChildren;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/traverseAllChildren.js\n ** module id = 125\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMSelect\n */\n\n'use strict';\n\nvar LinkedValueUtils = require('./LinkedValueUtils');\nvar ReactMount = require('./ReactMount');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar assign = require('./Object.assign');\nvar warning = require('fbjs/lib/warning');\n\nvar valueContextKey = '__ReactDOMSelect_value$' + Math.random().toString(36).slice(2);\n\nfunction updateOptionsIfPendingUpdateAndMounted() {\n  if (this._rootNodeID && this._wrapperState.pendingUpdate) {\n    this._wrapperState.pendingUpdate = false;\n\n    var props = this._currentElement.props;\n    var value = LinkedValueUtils.getValue(props);\n\n    if (value != null) {\n      updateOptions(this, props, value);\n    }\n  }\n}\n\nfunction getDeclarationErrorAddendum(owner) {\n  if (owner) {\n    var name = owner.getName();\n    if (name) {\n      return ' Check the render method of `' + name + '`.';\n    }\n  }\n  return '';\n}\n\nvar valuePropNames = ['value', 'defaultValue'];\n\n/**\n * Validation function for `value` and `defaultValue`.\n * @private\n */\nfunction checkSelectPropTypes(inst, props) {\n  var owner = inst._currentElement._owner;\n  LinkedValueUtils.checkPropTypes('select', props, owner);\n\n  for (var i = 0; i < valuePropNames.length; i++) {\n    var propName = valuePropNames[i];\n    if (props[propName] == null) {\n      continue;\n    }\n    if (props.multiple) {\n      process.env.NODE_ENV !== 'production' ? warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;\n    } else {\n      process.env.NODE_ENV !== 'production' ? warning(!Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;\n    }\n  }\n}\n\n/**\n * @param {ReactDOMComponent} inst\n * @param {boolean} multiple\n * @param {*} propValue A stringable (with `multiple`, a list of stringables).\n * @private\n */\nfunction updateOptions(inst, multiple, propValue) {\n  var selectedValue, i;\n  var options = ReactMount.getNode(inst._rootNodeID).options;\n\n  if (multiple) {\n    selectedValue = {};\n    for (i = 0; i < propValue.length; i++) {\n      selectedValue['' + propValue[i]] = true;\n    }\n    for (i = 0; i < options.length; i++) {\n      var selected = selectedValue.hasOwnProperty(options[i].value);\n      if (options[i].selected !== selected) {\n        options[i].selected = selected;\n      }\n    }\n  } else {\n    // Do not set `select.value` as exact behavior isn't consistent across all\n    // browsers for all cases.\n    selectedValue = '' + propValue;\n    for (i = 0; i < options.length; i++) {\n      if (options[i].value === selectedValue) {\n        options[i].selected = true;\n        return;\n      }\n    }\n    if (options.length) {\n      options[0].selected = true;\n    }\n  }\n}\n\n/**\n * Implements a <select> native component that allows optionally setting the\n * props `value` and `defaultValue`. If `multiple` is false, the prop must be a\n * stringable. If `multiple` is true, the prop must be an array of stringables.\n *\n * If `value` is not supplied (or null/undefined), user actions that change the\n * selected option will trigger updates to the rendered options.\n *\n * If it is supplied (and not null/undefined), the rendered options will not\n * update in response to user actions. Instead, the `value` prop must change in\n * order for the rendered options to update.\n *\n * If `defaultValue` is provided, any options with the supplied values will be\n * selected.\n */\nvar ReactDOMSelect = {\n  valueContextKey: valueContextKey,\n\n  getNativeProps: function (inst, props, context) {\n    return assign({}, props, {\n      onChange: inst._wrapperState.onChange,\n      value: undefined\n    });\n  },\n\n  mountWrapper: function (inst, props) {\n    if (process.env.NODE_ENV !== 'production') {\n      checkSelectPropTypes(inst, props);\n    }\n\n    var value = LinkedValueUtils.getValue(props);\n    inst._wrapperState = {\n      pendingUpdate: false,\n      initialValue: value != null ? value : props.defaultValue,\n      onChange: _handleChange.bind(inst),\n      wasMultiple: Boolean(props.multiple)\n    };\n  },\n\n  processChildContext: function (inst, props, context) {\n    // Pass down initial value so initial generated markup has correct\n    // `selected` attributes\n    var childContext = assign({}, context);\n    childContext[valueContextKey] = inst._wrapperState.initialValue;\n    return childContext;\n  },\n\n  postUpdateWrapper: function (inst) {\n    var props = inst._currentElement.props;\n\n    // After the initial mount, we control selected-ness manually so don't pass\n    // the context value down\n    inst._wrapperState.initialValue = undefined;\n\n    var wasMultiple = inst._wrapperState.wasMultiple;\n    inst._wrapperState.wasMultiple = Boolean(props.multiple);\n\n    var value = LinkedValueUtils.getValue(props);\n    if (value != null) {\n      inst._wrapperState.pendingUpdate = false;\n      updateOptions(inst, Boolean(props.multiple), value);\n    } else if (wasMultiple !== Boolean(props.multiple)) {\n      // For simplicity, reapply `defaultValue` if `multiple` is toggled.\n      if (props.defaultValue != null) {\n        updateOptions(inst, Boolean(props.multiple), props.defaultValue);\n      } else {\n        // Revert the select back to its default unselected state.\n        updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : '');\n      }\n    }\n  }\n};\n\nfunction _handleChange(event) {\n  var props = this._currentElement.props;\n  var returnValue = LinkedValueUtils.executeOnChange(props, event);\n\n  this._wrapperState.pendingUpdate = true;\n  ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);\n  return returnValue;\n}\n\nmodule.exports = ReactDOMSelect;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMSelect.js\n ** module id = 126\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMTextarea\n */\n\n'use strict';\n\nvar LinkedValueUtils = require('./LinkedValueUtils');\nvar ReactDOMIDOperations = require('./ReactDOMIDOperations');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar assign = require('./Object.assign');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\nfunction forceUpdateIfMounted() {\n  if (this._rootNodeID) {\n    // DOM component is still mounted; update\n    ReactDOMTextarea.updateWrapper(this);\n  }\n}\n\n/**\n * Implements a <textarea> native component that allows setting `value`, and\n * `defaultValue`. This differs from the traditional DOM API because value is\n * usually set as PCDATA children.\n *\n * If `value` is not supplied (or null/undefined), user actions that affect the\n * value will trigger updates to the element.\n *\n * If `value` is supplied (and not null/undefined), the rendered element will\n * not trigger updates to the element. Instead, the `value` prop must change in\n * order for the rendered element to be updated.\n *\n * The rendered element will be initialized with an empty value, the prop\n * `defaultValue` if specified, or the children content (deprecated).\n */\nvar ReactDOMTextarea = {\n  getNativeProps: function (inst, props, context) {\n    !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined;\n\n    // Always set children to the same thing. In IE9, the selection range will\n    // get reset if `textContent` is mutated.\n    var nativeProps = assign({}, props, {\n      defaultValue: undefined,\n      value: undefined,\n      children: inst._wrapperState.initialValue,\n      onChange: inst._wrapperState.onChange\n    });\n\n    return nativeProps;\n  },\n\n  mountWrapper: function (inst, props) {\n    if (process.env.NODE_ENV !== 'production') {\n      LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner);\n    }\n\n    var defaultValue = props.defaultValue;\n    // TODO (yungsters): Remove support for children content in <textarea>.\n    var children = props.children;\n    if (children != null) {\n      if (process.env.NODE_ENV !== 'production') {\n        process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : undefined;\n      }\n      !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : invariant(false) : undefined;\n      if (Array.isArray(children)) {\n        !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : invariant(false) : undefined;\n        children = children[0];\n      }\n\n      defaultValue = '' + children;\n    }\n    if (defaultValue == null) {\n      defaultValue = '';\n    }\n    var value = LinkedValueUtils.getValue(props);\n\n    inst._wrapperState = {\n      // We save the initial value so that `ReactDOMComponent` doesn't update\n      // `textContent` (unnecessary since we update value).\n      // The initial value can be a boolean or object so that's why it's\n      // forced to be a string.\n      initialValue: '' + (value != null ? value : defaultValue),\n      onChange: _handleChange.bind(inst)\n    };\n  },\n\n  updateWrapper: function (inst) {\n    var props = inst._currentElement.props;\n    var value = LinkedValueUtils.getValue(props);\n    if (value != null) {\n      // Cast `value` to a string to ensure the value is set correctly. While\n      // browsers typically do this as necessary, jsdom doesn't.\n      ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);\n    }\n  }\n};\n\nfunction _handleChange(event) {\n  var props = this._currentElement.props;\n  var returnValue = LinkedValueUtils.executeOnChange(props, event);\n  ReactUpdates.asap(forceUpdateIfMounted, this);\n  return returnValue;\n}\n\nmodule.exports = ReactDOMTextarea;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMTextarea.js\n ** module id = 127\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactMultiChild\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactComponentEnvironment = require('./ReactComponentEnvironment');\nvar ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes');\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\nvar ReactReconciler = require('./ReactReconciler');\nvar ReactChildReconciler = require('./ReactChildReconciler');\n\nvar flattenChildren = require('./flattenChildren');\n\n/**\n * Updating children of a component may trigger recursive updates. The depth is\n * used to batch recursive updates to render markup more efficiently.\n *\n * @type {number}\n * @private\n */\nvar updateDepth = 0;\n\n/**\n * Queue of update configuration objects.\n *\n * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.\n *\n * @type {array<object>}\n * @private\n */\nvar updateQueue = [];\n\n/**\n * Queue of markup to be rendered.\n *\n * @type {array<string>}\n * @private\n */\nvar markupQueue = [];\n\n/**\n * Enqueues markup to be rendered and inserted at a supplied index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} markup Markup that renders into an element.\n * @param {number} toIndex Destination index.\n * @private\n */\nfunction enqueueInsertMarkup(parentID, markup, toIndex) {\n  // NOTE: Null values reduce hidden classes.\n  updateQueue.push({\n    parentID: parentID,\n    parentNode: null,\n    type: ReactMultiChildUpdateTypes.INSERT_MARKUP,\n    markupIndex: markupQueue.push(markup) - 1,\n    content: null,\n    fromIndex: null,\n    toIndex: toIndex\n  });\n}\n\n/**\n * Enqueues moving an existing element to another index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {number} fromIndex Source index of the existing element.\n * @param {number} toIndex Destination index of the element.\n * @private\n */\nfunction enqueueMove(parentID, fromIndex, toIndex) {\n  // NOTE: Null values reduce hidden classes.\n  updateQueue.push({\n    parentID: parentID,\n    parentNode: null,\n    type: ReactMultiChildUpdateTypes.MOVE_EXISTING,\n    markupIndex: null,\n    content: null,\n    fromIndex: fromIndex,\n    toIndex: toIndex\n  });\n}\n\n/**\n * Enqueues removing an element at an index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {number} fromIndex Index of the element to remove.\n * @private\n */\nfunction enqueueRemove(parentID, fromIndex) {\n  // NOTE: Null values reduce hidden classes.\n  updateQueue.push({\n    parentID: parentID,\n    parentNode: null,\n    type: ReactMultiChildUpdateTypes.REMOVE_NODE,\n    markupIndex: null,\n    content: null,\n    fromIndex: fromIndex,\n    toIndex: null\n  });\n}\n\n/**\n * Enqueues setting the markup of a node.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} markup Markup that renders into an element.\n * @private\n */\nfunction enqueueSetMarkup(parentID, markup) {\n  // NOTE: Null values reduce hidden classes.\n  updateQueue.push({\n    parentID: parentID,\n    parentNode: null,\n    type: ReactMultiChildUpdateTypes.SET_MARKUP,\n    markupIndex: null,\n    content: markup,\n    fromIndex: null,\n    toIndex: null\n  });\n}\n\n/**\n * Enqueues setting the text content.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} textContent Text content to set.\n * @private\n */\nfunction enqueueTextContent(parentID, textContent) {\n  // NOTE: Null values reduce hidden classes.\n  updateQueue.push({\n    parentID: parentID,\n    parentNode: null,\n    type: ReactMultiChildUpdateTypes.TEXT_CONTENT,\n    markupIndex: null,\n    content: textContent,\n    fromIndex: null,\n    toIndex: null\n  });\n}\n\n/**\n * Processes any enqueued updates.\n *\n * @private\n */\nfunction processQueue() {\n  if (updateQueue.length) {\n    ReactComponentEnvironment.processChildrenUpdates(updateQueue, markupQueue);\n    clearQueue();\n  }\n}\n\n/**\n * Clears any enqueued updates.\n *\n * @private\n */\nfunction clearQueue() {\n  updateQueue.length = 0;\n  markupQueue.length = 0;\n}\n\n/**\n * ReactMultiChild are capable of reconciling multiple children.\n *\n * @class ReactMultiChild\n * @internal\n */\nvar ReactMultiChild = {\n\n  /**\n   * Provides common functionality for components that must reconcile multiple\n   * children. This is used by `ReactDOMComponent` to mount, update, and\n   * unmount child components.\n   *\n   * @lends {ReactMultiChild.prototype}\n   */\n  Mixin: {\n\n    _reconcilerInstantiateChildren: function (nestedChildren, transaction, context) {\n      if (process.env.NODE_ENV !== 'production') {\n        if (this._currentElement) {\n          try {\n            ReactCurrentOwner.current = this._currentElement._owner;\n            return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context);\n          } finally {\n            ReactCurrentOwner.current = null;\n          }\n        }\n      }\n      return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context);\n    },\n\n    _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, transaction, context) {\n      var nextChildren;\n      if (process.env.NODE_ENV !== 'production') {\n        if (this._currentElement) {\n          try {\n            ReactCurrentOwner.current = this._currentElement._owner;\n            nextChildren = flattenChildren(nextNestedChildrenElements);\n          } finally {\n            ReactCurrentOwner.current = null;\n          }\n          return ReactChildReconciler.updateChildren(prevChildren, nextChildren, transaction, context);\n        }\n      }\n      nextChildren = flattenChildren(nextNestedChildrenElements);\n      return ReactChildReconciler.updateChildren(prevChildren, nextChildren, transaction, context);\n    },\n\n    /**\n     * Generates a \"mount image\" for each of the supplied children. In the case\n     * of `ReactDOMComponent`, a mount image is a string of markup.\n     *\n     * @param {?object} nestedChildren Nested child maps.\n     * @return {array} An array of mounted representations.\n     * @internal\n     */\n    mountChildren: function (nestedChildren, transaction, context) {\n      var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context);\n      this._renderedChildren = children;\n      var mountImages = [];\n      var index = 0;\n      for (var name in children) {\n        if (children.hasOwnProperty(name)) {\n          var child = children[name];\n          // Inlined for performance, see `ReactInstanceHandles.createReactID`.\n          var rootID = this._rootNodeID + name;\n          var mountImage = ReactReconciler.mountComponent(child, rootID, transaction, context);\n          child._mountIndex = index++;\n          mountImages.push(mountImage);\n        }\n      }\n      return mountImages;\n    },\n\n    /**\n     * Replaces any rendered children with a text content string.\n     *\n     * @param {string} nextContent String of content.\n     * @internal\n     */\n    updateTextContent: function (nextContent) {\n      updateDepth++;\n      var errorThrown = true;\n      try {\n        var prevChildren = this._renderedChildren;\n        // Remove any rendered children.\n        ReactChildReconciler.unmountChildren(prevChildren);\n        // TODO: The setTextContent operation should be enough\n        for (var name in prevChildren) {\n          if (prevChildren.hasOwnProperty(name)) {\n            this._unmountChild(prevChildren[name]);\n          }\n        }\n        // Set new text content.\n        this.setTextContent(nextContent);\n        errorThrown = false;\n      } finally {\n        updateDepth--;\n        if (!updateDepth) {\n          if (errorThrown) {\n            clearQueue();\n          } else {\n            processQueue();\n          }\n        }\n      }\n    },\n\n    /**\n     * Replaces any rendered children with a markup string.\n     *\n     * @param {string} nextMarkup String of markup.\n     * @internal\n     */\n    updateMarkup: function (nextMarkup) {\n      updateDepth++;\n      var errorThrown = true;\n      try {\n        var prevChildren = this._renderedChildren;\n        // Remove any rendered children.\n        ReactChildReconciler.unmountChildren(prevChildren);\n        for (var name in prevChildren) {\n          if (prevChildren.hasOwnProperty(name)) {\n            this._unmountChildByName(prevChildren[name], name);\n          }\n        }\n        this.setMarkup(nextMarkup);\n        errorThrown = false;\n      } finally {\n        updateDepth--;\n        if (!updateDepth) {\n          if (errorThrown) {\n            clearQueue();\n          } else {\n            processQueue();\n          }\n        }\n      }\n    },\n\n    /**\n     * Updates the rendered children with new children.\n     *\n     * @param {?object} nextNestedChildrenElements Nested child element maps.\n     * @param {ReactReconcileTransaction} transaction\n     * @internal\n     */\n    updateChildren: function (nextNestedChildrenElements, transaction, context) {\n      updateDepth++;\n      var errorThrown = true;\n      try {\n        this._updateChildren(nextNestedChildrenElements, transaction, context);\n        errorThrown = false;\n      } finally {\n        updateDepth--;\n        if (!updateDepth) {\n          if (errorThrown) {\n            clearQueue();\n          } else {\n            processQueue();\n          }\n        }\n      }\n    },\n\n    /**\n     * Improve performance by isolating this hot code path from the try/catch\n     * block in `updateChildren`.\n     *\n     * @param {?object} nextNestedChildrenElements Nested child element maps.\n     * @param {ReactReconcileTransaction} transaction\n     * @final\n     * @protected\n     */\n    _updateChildren: function (nextNestedChildrenElements, transaction, context) {\n      var prevChildren = this._renderedChildren;\n      var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, transaction, context);\n      this._renderedChildren = nextChildren;\n      if (!nextChildren && !prevChildren) {\n        return;\n      }\n      var name;\n      // `nextIndex` will increment for each child in `nextChildren`, but\n      // `lastIndex` will be the last index visited in `prevChildren`.\n      var lastIndex = 0;\n      var nextIndex = 0;\n      for (name in nextChildren) {\n        if (!nextChildren.hasOwnProperty(name)) {\n          continue;\n        }\n        var prevChild = prevChildren && prevChildren[name];\n        var nextChild = nextChildren[name];\n        if (prevChild === nextChild) {\n          this.moveChild(prevChild, nextIndex, lastIndex);\n          lastIndex = Math.max(prevChild._mountIndex, lastIndex);\n          prevChild._mountIndex = nextIndex;\n        } else {\n          if (prevChild) {\n            // Update `lastIndex` before `_mountIndex` gets unset by unmounting.\n            lastIndex = Math.max(prevChild._mountIndex, lastIndex);\n            this._unmountChild(prevChild);\n          }\n          // The child must be instantiated before it's mounted.\n          this._mountChildByNameAtIndex(nextChild, name, nextIndex, transaction, context);\n        }\n        nextIndex++;\n      }\n      // Remove children that are no longer present.\n      for (name in prevChildren) {\n        if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {\n          this._unmountChild(prevChildren[name]);\n        }\n      }\n    },\n\n    /**\n     * Unmounts all rendered children. This should be used to clean up children\n     * when this component is unmounted.\n     *\n     * @internal\n     */\n    unmountChildren: function () {\n      var renderedChildren = this._renderedChildren;\n      ReactChildReconciler.unmountChildren(renderedChildren);\n      this._renderedChildren = null;\n    },\n\n    /**\n     * Moves a child component to the supplied index.\n     *\n     * @param {ReactComponent} child Component to move.\n     * @param {number} toIndex Destination index of the element.\n     * @param {number} lastIndex Last index visited of the siblings of `child`.\n     * @protected\n     */\n    moveChild: function (child, toIndex, lastIndex) {\n      // If the index of `child` is less than `lastIndex`, then it needs to\n      // be moved. Otherwise, we do not need to move it because a child will be\n      // inserted or moved before `child`.\n      if (child._mountIndex < lastIndex) {\n        enqueueMove(this._rootNodeID, child._mountIndex, toIndex);\n      }\n    },\n\n    /**\n     * Creates a child component.\n     *\n     * @param {ReactComponent} child Component to create.\n     * @param {string} mountImage Markup to insert.\n     * @protected\n     */\n    createChild: function (child, mountImage) {\n      enqueueInsertMarkup(this._rootNodeID, mountImage, child._mountIndex);\n    },\n\n    /**\n     * Removes a child component.\n     *\n     * @param {ReactComponent} child Child to remove.\n     * @protected\n     */\n    removeChild: function (child) {\n      enqueueRemove(this._rootNodeID, child._mountIndex);\n    },\n\n    /**\n     * Sets this text content string.\n     *\n     * @param {string} textContent Text content to set.\n     * @protected\n     */\n    setTextContent: function (textContent) {\n      enqueueTextContent(this._rootNodeID, textContent);\n    },\n\n    /**\n     * Sets this markup string.\n     *\n     * @param {string} markup Markup to set.\n     * @protected\n     */\n    setMarkup: function (markup) {\n      enqueueSetMarkup(this._rootNodeID, markup);\n    },\n\n    /**\n     * Mounts a child with the supplied name.\n     *\n     * NOTE: This is part of `updateChildren` and is here for readability.\n     *\n     * @param {ReactComponent} child Component to mount.\n     * @param {string} name Name of the child.\n     * @param {number} index Index at which to insert the child.\n     * @param {ReactReconcileTransaction} transaction\n     * @private\n     */\n    _mountChildByNameAtIndex: function (child, name, index, transaction, context) {\n      // Inlined for performance, see `ReactInstanceHandles.createReactID`.\n      var rootID = this._rootNodeID + name;\n      var mountImage = ReactReconciler.mountComponent(child, rootID, transaction, context);\n      child._mountIndex = index;\n      this.createChild(child, mountImage);\n    },\n\n    /**\n     * Unmounts a rendered child.\n     *\n     * NOTE: This is part of `updateChildren` and is here for readability.\n     *\n     * @param {ReactComponent} child Component to unmount.\n     * @private\n     */\n    _unmountChild: function (child) {\n      this.removeChild(child);\n      child._mountIndex = null;\n    }\n\n  }\n\n};\n\nmodule.exports = ReactMultiChild;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactMultiChild.js\n ** module id = 128\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactChildReconciler\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactReconciler = require('./ReactReconciler');\n\nvar instantiateReactComponent = require('./instantiateReactComponent');\nvar shouldUpdateReactComponent = require('./shouldUpdateReactComponent');\nvar traverseAllChildren = require('./traverseAllChildren');\nvar warning = require('fbjs/lib/warning');\n\nfunction instantiateChild(childInstances, child, name) {\n  // We found a component instance.\n  var keyUnique = childInstances[name] === undefined;\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(keyUnique, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.', name) : undefined;\n  }\n  if (child != null && keyUnique) {\n    childInstances[name] = instantiateReactComponent(child, null);\n  }\n}\n\n/**\n * ReactChildReconciler provides helpers for initializing or updating a set of\n * children. Its output is suitable for passing it onto ReactMultiChild which\n * does diffed reordering and insertion.\n */\nvar ReactChildReconciler = {\n  /**\n   * Generates a \"mount image\" for each of the supplied children. In the case\n   * of `ReactDOMComponent`, a mount image is a string of markup.\n   *\n   * @param {?object} nestedChildNodes Nested child maps.\n   * @return {?object} A set of child instances.\n   * @internal\n   */\n  instantiateChildren: function (nestedChildNodes, transaction, context) {\n    if (nestedChildNodes == null) {\n      return null;\n    }\n    var childInstances = {};\n    traverseAllChildren(nestedChildNodes, instantiateChild, childInstances);\n    return childInstances;\n  },\n\n  /**\n   * Updates the rendered children and returns a new set of children.\n   *\n   * @param {?object} prevChildren Previously initialized set of children.\n   * @param {?object} nextChildren Flat child element maps.\n   * @param {ReactReconcileTransaction} transaction\n   * @param {object} context\n   * @return {?object} A new set of child instances.\n   * @internal\n   */\n  updateChildren: function (prevChildren, nextChildren, transaction, context) {\n    // We currently don't have a way to track moves here but if we use iterators\n    // instead of for..in we can zip the iterators and check if an item has\n    // moved.\n    // TODO: If nothing has changed, return the prevChildren object so that we\n    // can quickly bailout if nothing has changed.\n    if (!nextChildren && !prevChildren) {\n      return null;\n    }\n    var name;\n    for (name in nextChildren) {\n      if (!nextChildren.hasOwnProperty(name)) {\n        continue;\n      }\n      var prevChild = prevChildren && prevChildren[name];\n      var prevElement = prevChild && prevChild._currentElement;\n      var nextElement = nextChildren[name];\n      if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) {\n        ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context);\n        nextChildren[name] = prevChild;\n      } else {\n        if (prevChild) {\n          ReactReconciler.unmountComponent(prevChild, name);\n        }\n        // The child must be instantiated before it's mounted.\n        var nextChildInstance = instantiateReactComponent(nextElement, null);\n        nextChildren[name] = nextChildInstance;\n      }\n    }\n    // Unmount children that are no longer present.\n    for (name in prevChildren) {\n      if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {\n        ReactReconciler.unmountComponent(prevChildren[name]);\n      }\n    }\n    return nextChildren;\n  },\n\n  /**\n   * Unmounts all rendered children. This should be used to clean up children\n   * when this component is unmounted.\n   *\n   * @param {?object} renderedChildren Previously initialized set of children.\n   * @internal\n   */\n  unmountChildren: function (renderedChildren) {\n    for (var name in renderedChildren) {\n      if (renderedChildren.hasOwnProperty(name)) {\n        var renderedChild = renderedChildren[name];\n        ReactReconciler.unmountComponent(renderedChild);\n      }\n    }\n  }\n\n};\n\nmodule.exports = ReactChildReconciler;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactChildReconciler.js\n ** module id = 129\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule flattenChildren\n */\n\n'use strict';\n\nvar traverseAllChildren = require('./traverseAllChildren');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * @param {function} traverseContext Context passed through traversal.\n * @param {?ReactComponent} child React child component.\n * @param {!string} name String name of key path to child.\n */\nfunction flattenSingleChildIntoContext(traverseContext, child, name) {\n  // We found a component instance.\n  var result = traverseContext;\n  var keyUnique = result[name] === undefined;\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(keyUnique, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.', name) : undefined;\n  }\n  if (keyUnique && child != null) {\n    result[name] = child;\n  }\n}\n\n/**\n * Flattens children that are typically specified as `props.children`. Any null\n * children will not be included in the resulting object.\n * @return {!object} flattened children keyed by name.\n */\nfunction flattenChildren(children) {\n  if (children == null) {\n    return children;\n  }\n  var result = {};\n  traverseAllChildren(children, flattenSingleChildIntoContext, result);\n  return result;\n}\n\nmodule.exports = flattenChildren;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/flattenChildren.js\n ** module id = 130\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule shallowEqual\n * @typechecks\n * \n */\n\n'use strict';\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n/**\n * Performs equality by iterating through keys on an object and returning false\n * when any key has values which are not strictly equal between the arguments.\n * Returns true when the values of all keys are strictly equal.\n */\nfunction shallowEqual(objA, objB) {\n  if (objA === objB) {\n    return true;\n  }\n\n  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {\n    return false;\n  }\n\n  var keysA = Object.keys(objA);\n  var keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n\n  // Test for A's keys different from B.\n  var bHasOwnProperty = hasOwnProperty.bind(objB);\n  for (var i = 0; i < keysA.length; i++) {\n    if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nmodule.exports = shallowEqual;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/shallowEqual.js\n ** module id = 131\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactEventListener\n * @typechecks static-only\n */\n\n'use strict';\n\nvar EventListener = require('fbjs/lib/EventListener');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar PooledClass = require('./PooledClass');\nvar ReactInstanceHandles = require('./ReactInstanceHandles');\nvar ReactMount = require('./ReactMount');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar assign = require('./Object.assign');\nvar getEventTarget = require('./getEventTarget');\nvar getUnboundedScrollPosition = require('fbjs/lib/getUnboundedScrollPosition');\n\nvar DOCUMENT_FRAGMENT_NODE_TYPE = 11;\n\n/**\n * Finds the parent React component of `node`.\n *\n * @param {*} node\n * @return {?DOMEventTarget} Parent container, or `null` if the specified node\n *                           is not nested.\n */\nfunction findParent(node) {\n  // TODO: It may be a good idea to cache this to prevent unnecessary DOM\n  // traversal, but caching is difficult to do correctly without using a\n  // mutation observer to listen for all DOM changes.\n  var nodeID = ReactMount.getID(node);\n  var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);\n  var container = ReactMount.findReactContainerForID(rootID);\n  var parent = ReactMount.getFirstReactDOM(container);\n  return parent;\n}\n\n// Used to store ancestor hierarchy in top level callback\nfunction TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {\n  this.topLevelType = topLevelType;\n  this.nativeEvent = nativeEvent;\n  this.ancestors = [];\n}\nassign(TopLevelCallbackBookKeeping.prototype, {\n  destructor: function () {\n    this.topLevelType = null;\n    this.nativeEvent = null;\n    this.ancestors.length = 0;\n  }\n});\nPooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler);\n\nfunction handleTopLevelImpl(bookKeeping) {\n  // TODO: Re-enable event.path handling\n  //\n  // if (bookKeeping.nativeEvent.path && bookKeeping.nativeEvent.path.length > 1) {\n  //   // New browsers have a path attribute on native events\n  //   handleTopLevelWithPath(bookKeeping);\n  // } else {\n  //   // Legacy browsers don't have a path attribute on native events\n  //   handleTopLevelWithoutPath(bookKeeping);\n  // }\n\n  void handleTopLevelWithPath; // temporarily unused\n  handleTopLevelWithoutPath(bookKeeping);\n}\n\n// Legacy browsers don't have a path attribute on native events\nfunction handleTopLevelWithoutPath(bookKeeping) {\n  var topLevelTarget = ReactMount.getFirstReactDOM(getEventTarget(bookKeeping.nativeEvent)) || window;\n\n  // Loop through the hierarchy, in case there's any nested components.\n  // It's important that we build the array of ancestors before calling any\n  // event handlers, because event handlers can modify the DOM, leading to\n  // inconsistencies with ReactMount's node cache. See #1105.\n  var ancestor = topLevelTarget;\n  while (ancestor) {\n    bookKeeping.ancestors.push(ancestor);\n    ancestor = findParent(ancestor);\n  }\n\n  for (var i = 0; i < bookKeeping.ancestors.length; i++) {\n    topLevelTarget = bookKeeping.ancestors[i];\n    var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';\n    ReactEventListener._handleTopLevel(bookKeeping.topLevelType, topLevelTarget, topLevelTargetID, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));\n  }\n}\n\n// New browsers have a path attribute on native events\nfunction handleTopLevelWithPath(bookKeeping) {\n  var path = bookKeeping.nativeEvent.path;\n  var currentNativeTarget = path[0];\n  var eventsFired = 0;\n  for (var i = 0; i < path.length; i++) {\n    var currentPathElement = path[i];\n    if (currentPathElement.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE) {\n      currentNativeTarget = path[i + 1];\n    }\n    // TODO: slow\n    var reactParent = ReactMount.getFirstReactDOM(currentPathElement);\n    if (reactParent === currentPathElement) {\n      var currentPathElementID = ReactMount.getID(currentPathElement);\n      var newRootID = ReactInstanceHandles.getReactRootIDFromNodeID(currentPathElementID);\n      bookKeeping.ancestors.push(currentPathElement);\n\n      var topLevelTargetID = ReactMount.getID(currentPathElement) || '';\n      eventsFired++;\n      ReactEventListener._handleTopLevel(bookKeeping.topLevelType, currentPathElement, topLevelTargetID, bookKeeping.nativeEvent, currentNativeTarget);\n\n      // Jump to the root of this React render tree\n      while (currentPathElementID !== newRootID) {\n        i++;\n        currentPathElement = path[i];\n        currentPathElementID = ReactMount.getID(currentPathElement);\n      }\n    }\n  }\n  if (eventsFired === 0) {\n    ReactEventListener._handleTopLevel(bookKeeping.topLevelType, window, '', bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));\n  }\n}\n\nfunction scrollValueMonitor(cb) {\n  var scrollPosition = getUnboundedScrollPosition(window);\n  cb(scrollPosition);\n}\n\nvar ReactEventListener = {\n  _enabled: true,\n  _handleTopLevel: null,\n\n  WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,\n\n  setHandleTopLevel: function (handleTopLevel) {\n    ReactEventListener._handleTopLevel = handleTopLevel;\n  },\n\n  setEnabled: function (enabled) {\n    ReactEventListener._enabled = !!enabled;\n  },\n\n  isEnabled: function () {\n    return ReactEventListener._enabled;\n  },\n\n  /**\n   * Traps top-level events by using event bubbling.\n   *\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {string} handlerBaseName Event name (e.g. \"click\").\n   * @param {object} handle Element on which to attach listener.\n   * @return {?object} An object with a remove function which will forcefully\n   *                  remove the listener.\n   * @internal\n   */\n  trapBubbledEvent: function (topLevelType, handlerBaseName, handle) {\n    var element = handle;\n    if (!element) {\n      return null;\n    }\n    return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));\n  },\n\n  /**\n   * Traps a top-level event by using event capturing.\n   *\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {string} handlerBaseName Event name (e.g. \"click\").\n   * @param {object} handle Element on which to attach listener.\n   * @return {?object} An object with a remove function which will forcefully\n   *                  remove the listener.\n   * @internal\n   */\n  trapCapturedEvent: function (topLevelType, handlerBaseName, handle) {\n    var element = handle;\n    if (!element) {\n      return null;\n    }\n    return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));\n  },\n\n  monitorScrollValue: function (refresh) {\n    var callback = scrollValueMonitor.bind(null, refresh);\n    EventListener.listen(window, 'scroll', callback);\n  },\n\n  dispatchEvent: function (topLevelType, nativeEvent) {\n    if (!ReactEventListener._enabled) {\n      return;\n    }\n\n    var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent);\n    try {\n      // Event queue being processed in the same cycle allows\n      // `preventDefault`.\n      ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);\n    } finally {\n      TopLevelCallbackBookKeeping.release(bookKeeping);\n    }\n  }\n};\n\nmodule.exports = ReactEventListener;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactEventListener.js\n ** module id = 132\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule EventListener\n * @typechecks\n */\n\n'use strict';\n\nvar emptyFunction = require('./emptyFunction');\n\n/**\n * Upstream version of event listener. Does not take into account specific\n * nature of platform.\n */\nvar EventListener = {\n  /**\n   * Listen to DOM events during the bubble phase.\n   *\n   * @param {DOMEventTarget} target DOM element to register listener on.\n   * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.\n   * @param {function} callback Callback function.\n   * @return {object} Object with a `remove` method.\n   */\n  listen: function (target, eventType, callback) {\n    if (target.addEventListener) {\n      target.addEventListener(eventType, callback, false);\n      return {\n        remove: function () {\n          target.removeEventListener(eventType, callback, false);\n        }\n      };\n    } else if (target.attachEvent) {\n      target.attachEvent('on' + eventType, callback);\n      return {\n        remove: function () {\n          target.detachEvent('on' + eventType, callback);\n        }\n      };\n    }\n  },\n\n  /**\n   * Listen to DOM events during the capture phase.\n   *\n   * @param {DOMEventTarget} target DOM element to register listener on.\n   * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.\n   * @param {function} callback Callback function.\n   * @return {object} Object with a `remove` method.\n   */\n  capture: function (target, eventType, callback) {\n    if (target.addEventListener) {\n      target.addEventListener(eventType, callback, true);\n      return {\n        remove: function () {\n          target.removeEventListener(eventType, callback, true);\n        }\n      };\n    } else {\n      if (process.env.NODE_ENV !== 'production') {\n        console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.');\n      }\n      return {\n        remove: emptyFunction\n      };\n    }\n  },\n\n  registerDefault: function () {}\n};\n\nmodule.exports = EventListener;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/EventListener.js\n ** module id = 133\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getUnboundedScrollPosition\n * @typechecks\n */\n\n'use strict';\n\n/**\n * Gets the scroll position of the supplied element or window.\n *\n * The return values are unbounded, unlike `getScrollPosition`. This means they\n * may be negative or exceed the element boundaries (which is possible using\n * inertial scrolling).\n *\n * @param {DOMWindow|DOMElement} scrollable\n * @return {object} Map with `x` and `y` keys.\n */\nfunction getUnboundedScrollPosition(scrollable) {\n  if (scrollable === window) {\n    return {\n      x: window.pageXOffset || document.documentElement.scrollLeft,\n      y: window.pageYOffset || document.documentElement.scrollTop\n    };\n  }\n  return {\n    x: scrollable.scrollLeft,\n    y: scrollable.scrollTop\n  };\n}\n\nmodule.exports = getUnboundedScrollPosition;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/getUnboundedScrollPosition.js\n ** module id = 134\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactInjection\n */\n\n'use strict';\n\nvar DOMProperty = require('./DOMProperty');\nvar EventPluginHub = require('./EventPluginHub');\nvar ReactComponentEnvironment = require('./ReactComponentEnvironment');\nvar ReactClass = require('./ReactClass');\nvar ReactEmptyComponent = require('./ReactEmptyComponent');\nvar ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');\nvar ReactNativeComponent = require('./ReactNativeComponent');\nvar ReactPerf = require('./ReactPerf');\nvar ReactRootIndex = require('./ReactRootIndex');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar ReactInjection = {\n  Component: ReactComponentEnvironment.injection,\n  Class: ReactClass.injection,\n  DOMProperty: DOMProperty.injection,\n  EmptyComponent: ReactEmptyComponent.injection,\n  EventPluginHub: EventPluginHub.injection,\n  EventEmitter: ReactBrowserEventEmitter.injection,\n  NativeComponent: ReactNativeComponent.injection,\n  Perf: ReactPerf.injection,\n  RootIndex: ReactRootIndex.injection,\n  Updates: ReactUpdates.injection\n};\n\nmodule.exports = ReactInjection;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactInjection.js\n ** module id = 135\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactClass\n */\n\n'use strict';\n\nvar ReactComponent = require('./ReactComponent');\nvar ReactElement = require('./ReactElement');\nvar ReactPropTypeLocations = require('./ReactPropTypeLocations');\nvar ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');\nvar ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue');\n\nvar assign = require('./Object.assign');\nvar emptyObject = require('fbjs/lib/emptyObject');\nvar invariant = require('fbjs/lib/invariant');\nvar keyMirror = require('fbjs/lib/keyMirror');\nvar keyOf = require('fbjs/lib/keyOf');\nvar warning = require('fbjs/lib/warning');\n\nvar MIXINS_KEY = keyOf({ mixins: null });\n\n/**\n * Policies that describe methods in `ReactClassInterface`.\n */\nvar SpecPolicy = keyMirror({\n  /**\n   * These methods may be defined only once by the class specification or mixin.\n   */\n  DEFINE_ONCE: null,\n  /**\n   * These methods may be defined by both the class specification and mixins.\n   * Subsequent definitions will be chained. These methods must return void.\n   */\n  DEFINE_MANY: null,\n  /**\n   * These methods are overriding the base class.\n   */\n  OVERRIDE_BASE: null,\n  /**\n   * These methods are similar to DEFINE_MANY, except we assume they return\n   * objects. We try to merge the keys of the return values of all the mixed in\n   * functions. If there is a key conflict we throw.\n   */\n  DEFINE_MANY_MERGED: null\n});\n\nvar injectedMixins = [];\n\nvar warnedSetProps = false;\nfunction warnSetProps() {\n  if (!warnedSetProps) {\n    warnedSetProps = true;\n    process.env.NODE_ENV !== 'production' ? warning(false, 'setProps(...) and replaceProps(...) are deprecated. ' + 'Instead, call render again at the top level.') : undefined;\n  }\n}\n\n/**\n * Composite components are higher-level components that compose other composite\n * or native components.\n *\n * To create a new type of `ReactClass`, pass a specification of\n * your new class to `React.createClass`. The only requirement of your class\n * specification is that you implement a `render` method.\n *\n *   var MyComponent = React.createClass({\n *     render: function() {\n *       return <div>Hello World</div>;\n *     }\n *   });\n *\n * The class specification supports a specific protocol of methods that have\n * special meaning (e.g. `render`). See `ReactClassInterface` for\n * more the comprehensive protocol. Any other properties and methods in the\n * class specification will be available on the prototype.\n *\n * @interface ReactClassInterface\n * @internal\n */\nvar ReactClassInterface = {\n\n  /**\n   * An array of Mixin objects to include when defining your component.\n   *\n   * @type {array}\n   * @optional\n   */\n  mixins: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * An object containing properties and methods that should be defined on\n   * the component's constructor instead of its prototype (static methods).\n   *\n   * @type {object}\n   * @optional\n   */\n  statics: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Definition of prop types for this component.\n   *\n   * @type {object}\n   * @optional\n   */\n  propTypes: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Definition of context types for this component.\n   *\n   * @type {object}\n   * @optional\n   */\n  contextTypes: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Definition of context types this component sets for its children.\n   *\n   * @type {object}\n   * @optional\n   */\n  childContextTypes: SpecPolicy.DEFINE_MANY,\n\n  // ==== Definition methods ====\n\n  /**\n   * Invoked when the component is mounted. Values in the mapping will be set on\n   * `this.props` if that prop is not specified (i.e. using an `in` check).\n   *\n   * This method is invoked before `getInitialState` and therefore cannot rely\n   * on `this.state` or use `this.setState`.\n   *\n   * @return {object}\n   * @optional\n   */\n  getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,\n\n  /**\n   * Invoked once before the component is mounted. The return value will be used\n   * as the initial value of `this.state`.\n   *\n   *   getInitialState: function() {\n   *     return {\n   *       isOn: false,\n   *       fooBaz: new BazFoo()\n   *     }\n   *   }\n   *\n   * @return {object}\n   * @optional\n   */\n  getInitialState: SpecPolicy.DEFINE_MANY_MERGED,\n\n  /**\n   * @return {object}\n   * @optional\n   */\n  getChildContext: SpecPolicy.DEFINE_MANY_MERGED,\n\n  /**\n   * Uses props from `this.props` and state from `this.state` to render the\n   * structure of the component.\n   *\n   * No guarantees are made about when or how often this method is invoked, so\n   * it must not have side effects.\n   *\n   *   render: function() {\n   *     var name = this.props.name;\n   *     return <div>Hello, {name}!</div>;\n   *   }\n   *\n   * @return {ReactComponent}\n   * @nosideeffects\n   * @required\n   */\n  render: SpecPolicy.DEFINE_ONCE,\n\n  // ==== Delegate methods ====\n\n  /**\n   * Invoked when the component is initially created and about to be mounted.\n   * This may have side effects, but any external subscriptions or data created\n   * by this method must be cleaned up in `componentWillUnmount`.\n   *\n   * @optional\n   */\n  componentWillMount: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Invoked when the component has been mounted and has a DOM representation.\n   * However, there is no guarantee that the DOM node is in the document.\n   *\n   * Use this as an opportunity to operate on the DOM when the component has\n   * been mounted (initialized and rendered) for the first time.\n   *\n   * @param {DOMElement} rootNode DOM element representing the component.\n   * @optional\n   */\n  componentDidMount: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Invoked before the component receives new props.\n   *\n   * Use this as an opportunity to react to a prop transition by updating the\n   * state using `this.setState`. Current props are accessed via `this.props`.\n   *\n   *   componentWillReceiveProps: function(nextProps, nextContext) {\n   *     this.setState({\n   *       likesIncreasing: nextProps.likeCount > this.props.likeCount\n   *     });\n   *   }\n   *\n   * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop\n   * transition may cause a state change, but the opposite is not true. If you\n   * need it, you are probably looking for `componentWillUpdate`.\n   *\n   * @param {object} nextProps\n   * @optional\n   */\n  componentWillReceiveProps: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Invoked while deciding if the component should be updated as a result of\n   * receiving new props, state and/or context.\n   *\n   * Use this as an opportunity to `return false` when you're certain that the\n   * transition to the new props/state/context will not require a component\n   * update.\n   *\n   *   shouldComponentUpdate: function(nextProps, nextState, nextContext) {\n   *     return !equal(nextProps, this.props) ||\n   *       !equal(nextState, this.state) ||\n   *       !equal(nextContext, this.context);\n   *   }\n   *\n   * @param {object} nextProps\n   * @param {?object} nextState\n   * @param {?object} nextContext\n   * @return {boolean} True if the component should update.\n   * @optional\n   */\n  shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,\n\n  /**\n   * Invoked when the component is about to update due to a transition from\n   * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`\n   * and `nextContext`.\n   *\n   * Use this as an opportunity to perform preparation before an update occurs.\n   *\n   * NOTE: You **cannot** use `this.setState()` in this method.\n   *\n   * @param {object} nextProps\n   * @param {?object} nextState\n   * @param {?object} nextContext\n   * @param {ReactReconcileTransaction} transaction\n   * @optional\n   */\n  componentWillUpdate: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Invoked when the component's DOM representation has been updated.\n   *\n   * Use this as an opportunity to operate on the DOM when the component has\n   * been updated.\n   *\n   * @param {object} prevProps\n   * @param {?object} prevState\n   * @param {?object} prevContext\n   * @param {DOMElement} rootNode DOM element representing the component.\n   * @optional\n   */\n  componentDidUpdate: SpecPolicy.DEFINE_MANY,\n\n  /**\n   * Invoked when the component is about to be removed from its parent and have\n   * its DOM representation destroyed.\n   *\n   * Use this as an opportunity to deallocate any external resources.\n   *\n   * NOTE: There is no `componentDidUnmount` since your component will have been\n   * destroyed by that point.\n   *\n   * @optional\n   */\n  componentWillUnmount: SpecPolicy.DEFINE_MANY,\n\n  // ==== Advanced methods ====\n\n  /**\n   * Updates the component's currently mounted DOM representation.\n   *\n   * By default, this implements React's rendering and reconciliation algorithm.\n   * Sophisticated clients may wish to override this.\n   *\n   * @param {ReactReconcileTransaction} transaction\n   * @internal\n   * @overridable\n   */\n  updateComponent: SpecPolicy.OVERRIDE_BASE\n\n};\n\n/**\n * Mapping from class specification keys to special processing functions.\n *\n * Although these are declared like instance properties in the specification\n * when defining classes using `React.createClass`, they are actually static\n * and are accessible on the constructor instead of the prototype. Despite\n * being static, they must be defined outside of the \"statics\" key under\n * which all other static methods are defined.\n */\nvar RESERVED_SPEC_KEYS = {\n  displayName: function (Constructor, displayName) {\n    Constructor.displayName = displayName;\n  },\n  mixins: function (Constructor, mixins) {\n    if (mixins) {\n      for (var i = 0; i < mixins.length; i++) {\n        mixSpecIntoComponent(Constructor, mixins[i]);\n      }\n    }\n  },\n  childContextTypes: function (Constructor, childContextTypes) {\n    if (process.env.NODE_ENV !== 'production') {\n      validateTypeDef(Constructor, childContextTypes, ReactPropTypeLocations.childContext);\n    }\n    Constructor.childContextTypes = assign({}, Constructor.childContextTypes, childContextTypes);\n  },\n  contextTypes: function (Constructor, contextTypes) {\n    if (process.env.NODE_ENV !== 'production') {\n      validateTypeDef(Constructor, contextTypes, ReactPropTypeLocations.context);\n    }\n    Constructor.contextTypes = assign({}, Constructor.contextTypes, contextTypes);\n  },\n  /**\n   * Special case getDefaultProps which should move into statics but requires\n   * automatic merging.\n   */\n  getDefaultProps: function (Constructor, getDefaultProps) {\n    if (Constructor.getDefaultProps) {\n      Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps);\n    } else {\n      Constructor.getDefaultProps = getDefaultProps;\n    }\n  },\n  propTypes: function (Constructor, propTypes) {\n    if (process.env.NODE_ENV !== 'production') {\n      validateTypeDef(Constructor, propTypes, ReactPropTypeLocations.prop);\n    }\n    Constructor.propTypes = assign({}, Constructor.propTypes, propTypes);\n  },\n  statics: function (Constructor, statics) {\n    mixStaticSpecIntoComponent(Constructor, statics);\n  },\n  autobind: function () {} };\n\n// noop\nfunction validateTypeDef(Constructor, typeDef, location) {\n  for (var propName in typeDef) {\n    if (typeDef.hasOwnProperty(propName)) {\n      // use a warning instead of an invariant so components\n      // don't show up in prod but not in __DEV__\n      process.env.NODE_ENV !== 'production' ? warning(typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactClass', ReactPropTypeLocationNames[location], propName) : undefined;\n    }\n  }\n}\n\nfunction validateMethodOverride(proto, name) {\n  var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null;\n\n  // Disallow overriding of base class methods unless explicitly allowed.\n  if (ReactClassMixin.hasOwnProperty(name)) {\n    !(specPolicy === SpecPolicy.OVERRIDE_BASE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override ' + '`%s` from your class specification. Ensure that your method names ' + 'do not overlap with React methods.', name) : invariant(false) : undefined;\n  }\n\n  // Disallow defining methods more than once unless explicitly allowed.\n  if (proto.hasOwnProperty(name)) {\n    !(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define ' + '`%s` on your component more than once. This conflict may be due ' + 'to a mixin.', name) : invariant(false) : undefined;\n  }\n}\n\n/**\n * Mixin helper which handles policy validation and reserved\n * specification keys when building React classses.\n */\nfunction mixSpecIntoComponent(Constructor, spec) {\n  if (!spec) {\n    return;\n  }\n\n  !(typeof spec !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.') : invariant(false) : undefined;\n  !!ReactElement.isValidElement(spec) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.') : invariant(false) : undefined;\n\n  var proto = Constructor.prototype;\n\n  // By handling mixins before any other properties, we ensure the same\n  // chaining order is applied to methods with DEFINE_MANY policy, whether\n  // mixins are listed before or after these methods in the spec.\n  if (spec.hasOwnProperty(MIXINS_KEY)) {\n    RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);\n  }\n\n  for (var name in spec) {\n    if (!spec.hasOwnProperty(name)) {\n      continue;\n    }\n\n    if (name === MIXINS_KEY) {\n      // We have already handled mixins in a special case above.\n      continue;\n    }\n\n    var property = spec[name];\n    validateMethodOverride(proto, name);\n\n    if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {\n      RESERVED_SPEC_KEYS[name](Constructor, property);\n    } else {\n      // Setup methods on prototype:\n      // The following member methods should not be automatically bound:\n      // 1. Expected ReactClass methods (in the \"interface\").\n      // 2. Overridden methods (that were mixed in).\n      var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);\n      var isAlreadyDefined = proto.hasOwnProperty(name);\n      var isFunction = typeof property === 'function';\n      var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false;\n\n      if (shouldAutoBind) {\n        if (!proto.__reactAutoBindMap) {\n          proto.__reactAutoBindMap = {};\n        }\n        proto.__reactAutoBindMap[name] = property;\n        proto[name] = property;\n      } else {\n        if (isAlreadyDefined) {\n          var specPolicy = ReactClassInterface[name];\n\n          // These cases should already be caught by validateMethodOverride.\n          !(isReactClassMethod && (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.', specPolicy, name) : invariant(false) : undefined;\n\n          // For methods which are defined more than once, call the existing\n          // methods before calling the new property, merging if appropriate.\n          if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {\n            proto[name] = createMergedResultFunction(proto[name], property);\n          } else if (specPolicy === SpecPolicy.DEFINE_MANY) {\n            proto[name] = createChainedFunction(proto[name], property);\n          }\n        } else {\n          proto[name] = property;\n          if (process.env.NODE_ENV !== 'production') {\n            // Add verbose displayName to the function, which helps when looking\n            // at profiling tools.\n            if (typeof property === 'function' && spec.displayName) {\n              proto[name].displayName = spec.displayName + '_' + name;\n            }\n          }\n        }\n      }\n    }\n  }\n}\n\nfunction mixStaticSpecIntoComponent(Constructor, statics) {\n  if (!statics) {\n    return;\n  }\n  for (var name in statics) {\n    var property = statics[name];\n    if (!statics.hasOwnProperty(name)) {\n      continue;\n    }\n\n    var isReserved = (name in RESERVED_SPEC_KEYS);\n    !!isReserved ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define a reserved ' + 'property, `%s`, that shouldn\\'t be on the \"statics\" key. Define it ' + 'as an instance property instead; it will still be accessible on the ' + 'constructor.', name) : invariant(false) : undefined;\n\n    var isInherited = (name in Constructor);\n    !!isInherited ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define ' + '`%s` on your component more than once. This conflict may be ' + 'due to a mixin.', name) : invariant(false) : undefined;\n    Constructor[name] = property;\n  }\n}\n\n/**\n * Merge two objects, but throw if both contain the same key.\n *\n * @param {object} one The first object, which is mutated.\n * @param {object} two The second object\n * @return {object} one after it has been mutated to contain everything in two.\n */\nfunction mergeIntoWithNoDuplicateKeys(one, two) {\n  !(one && two && typeof one === 'object' && typeof two === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.') : invariant(false) : undefined;\n\n  for (var key in two) {\n    if (two.hasOwnProperty(key)) {\n      !(one[key] === undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): ' + 'Tried to merge two objects with the same key: `%s`. This conflict ' + 'may be due to a mixin; in particular, this may be caused by two ' + 'getInitialState() or getDefaultProps() methods returning objects ' + 'with clashing keys.', key) : invariant(false) : undefined;\n      one[key] = two[key];\n    }\n  }\n  return one;\n}\n\n/**\n * Creates a function that invokes two functions and merges their return values.\n *\n * @param {function} one Function to invoke first.\n * @param {function} two Function to invoke second.\n * @return {function} Function that invokes the two argument functions.\n * @private\n */\nfunction createMergedResultFunction(one, two) {\n  return function mergedResult() {\n    var a = one.apply(this, arguments);\n    var b = two.apply(this, arguments);\n    if (a == null) {\n      return b;\n    } else if (b == null) {\n      return a;\n    }\n    var c = {};\n    mergeIntoWithNoDuplicateKeys(c, a);\n    mergeIntoWithNoDuplicateKeys(c, b);\n    return c;\n  };\n}\n\n/**\n * Creates a function that invokes two functions and ignores their return vales.\n *\n * @param {function} one Function to invoke first.\n * @param {function} two Function to invoke second.\n * @return {function} Function that invokes the two argument functions.\n * @private\n */\nfunction createChainedFunction(one, two) {\n  return function chainedFunction() {\n    one.apply(this, arguments);\n    two.apply(this, arguments);\n  };\n}\n\n/**\n * Binds a method to the component.\n *\n * @param {object} component Component whose method is going to be bound.\n * @param {function} method Method to be bound.\n * @return {function} The bound method.\n */\nfunction bindAutoBindMethod(component, method) {\n  var boundMethod = method.bind(component);\n  if (process.env.NODE_ENV !== 'production') {\n    boundMethod.__reactBoundContext = component;\n    boundMethod.__reactBoundMethod = method;\n    boundMethod.__reactBoundArguments = null;\n    var componentName = component.constructor.displayName;\n    var _bind = boundMethod.bind;\n    /* eslint-disable block-scoped-var, no-undef */\n    boundMethod.bind = function (newThis) {\n      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n        args[_key - 1] = arguments[_key];\n      }\n\n      // User is trying to bind() an autobound method; we effectively will\n      // ignore the value of \"this\" that the user is trying to use, so\n      // let's warn.\n      if (newThis !== component && newThis !== null) {\n        process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName) : undefined;\n      } else if (!args.length) {\n        process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See %s', componentName) : undefined;\n        return boundMethod;\n      }\n      var reboundMethod = _bind.apply(boundMethod, arguments);\n      reboundMethod.__reactBoundContext = component;\n      reboundMethod.__reactBoundMethod = method;\n      reboundMethod.__reactBoundArguments = args;\n      return reboundMethod;\n      /* eslint-enable */\n    };\n  }\n  return boundMethod;\n}\n\n/**\n * Binds all auto-bound methods in a component.\n *\n * @param {object} component Component whose method is going to be bound.\n */\nfunction bindAutoBindMethods(component) {\n  for (var autoBindKey in component.__reactAutoBindMap) {\n    if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {\n      var method = component.__reactAutoBindMap[autoBindKey];\n      component[autoBindKey] = bindAutoBindMethod(component, method);\n    }\n  }\n}\n\n/**\n * Add more to the ReactClass base class. These are all legacy features and\n * therefore not already part of the modern ReactComponent.\n */\nvar ReactClassMixin = {\n\n  /**\n   * TODO: This will be deprecated because state should always keep a consistent\n   * type signature and the only use case for this, is to avoid that.\n   */\n  replaceState: function (newState, callback) {\n    this.updater.enqueueReplaceState(this, newState);\n    if (callback) {\n      this.updater.enqueueCallback(this, callback);\n    }\n  },\n\n  /**\n   * Checks whether or not this composite component is mounted.\n   * @return {boolean} True if mounted, false otherwise.\n   * @protected\n   * @final\n   */\n  isMounted: function () {\n    return this.updater.isMounted(this);\n  },\n\n  /**\n   * Sets a subset of the props.\n   *\n   * @param {object} partialProps Subset of the next props.\n   * @param {?function} callback Called after props are updated.\n   * @final\n   * @public\n   * @deprecated\n   */\n  setProps: function (partialProps, callback) {\n    if (process.env.NODE_ENV !== 'production') {\n      warnSetProps();\n    }\n    this.updater.enqueueSetProps(this, partialProps);\n    if (callback) {\n      this.updater.enqueueCallback(this, callback);\n    }\n  },\n\n  /**\n   * Replace all the props.\n   *\n   * @param {object} newProps Subset of the next props.\n   * @param {?function} callback Called after props are updated.\n   * @final\n   * @public\n   * @deprecated\n   */\n  replaceProps: function (newProps, callback) {\n    if (process.env.NODE_ENV !== 'production') {\n      warnSetProps();\n    }\n    this.updater.enqueueReplaceProps(this, newProps);\n    if (callback) {\n      this.updater.enqueueCallback(this, callback);\n    }\n  }\n};\n\nvar ReactClassComponent = function () {};\nassign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin);\n\n/**\n * Module for creating composite components.\n *\n * @class ReactClass\n */\nvar ReactClass = {\n\n  /**\n   * Creates a composite component class given a class specification.\n   *\n   * @param {object} spec Class specification (which must define `render`).\n   * @return {function} Component constructor function.\n   * @public\n   */\n  createClass: function (spec) {\n    var Constructor = function (props, context, updater) {\n      // This constructor is overridden by mocks. The argument is used\n      // by mocks to assert on what gets mounted.\n\n      if (process.env.NODE_ENV !== 'production') {\n        process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory') : undefined;\n      }\n\n      // Wire up auto-binding\n      if (this.__reactAutoBindMap) {\n        bindAutoBindMethods(this);\n      }\n\n      this.props = props;\n      this.context = context;\n      this.refs = emptyObject;\n      this.updater = updater || ReactNoopUpdateQueue;\n\n      this.state = null;\n\n      // ReactClasses doesn't have constructors. Instead, they use the\n      // getInitialState and componentWillMount methods for initialization.\n\n      var initialState = this.getInitialState ? this.getInitialState() : null;\n      if (process.env.NODE_ENV !== 'production') {\n        // We allow auto-mocks to proceed as if they're returning null.\n        if (typeof initialState === 'undefined' && this.getInitialState._isMockFunction) {\n          // This is probably bad practice. Consider warning here and\n          // deprecating this convenience.\n          initialState = null;\n        }\n      }\n      !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : invariant(false) : undefined;\n\n      this.state = initialState;\n    };\n    Constructor.prototype = new ReactClassComponent();\n    Constructor.prototype.constructor = Constructor;\n\n    injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));\n\n    mixSpecIntoComponent(Constructor, spec);\n\n    // Initialize the defaultProps property after all mixins have been merged.\n    if (Constructor.getDefaultProps) {\n      Constructor.defaultProps = Constructor.getDefaultProps();\n    }\n\n    if (process.env.NODE_ENV !== 'production') {\n      // This is a tag to indicate that the use of these method names is ok,\n      // since it's used with createClass. If it's not, then it's likely a\n      // mistake so we'll warn you to use the static property, property\n      // initializer or constructor respectively.\n      if (Constructor.getDefaultProps) {\n        Constructor.getDefaultProps.isReactClassApproved = {};\n      }\n      if (Constructor.prototype.getInitialState) {\n        Constructor.prototype.getInitialState.isReactClassApproved = {};\n      }\n    }\n\n    !Constructor.prototype.render ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createClass(...): Class specification must implement a `render` method.') : invariant(false) : undefined;\n\n    if (process.env.NODE_ENV !== 'production') {\n      process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', spec.displayName || 'A component') : undefined;\n      process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component') : undefined;\n    }\n\n    // Reduce time spent doing lookups by setting these on the prototype.\n    for (var methodName in ReactClassInterface) {\n      if (!Constructor.prototype[methodName]) {\n        Constructor.prototype[methodName] = null;\n      }\n    }\n\n    return Constructor;\n  },\n\n  injection: {\n    injectMixin: function (mixin) {\n      injectedMixins.push(mixin);\n    }\n  }\n\n};\n\nmodule.exports = ReactClass;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactClass.js\n ** module id = 136\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactComponent\n */\n\n'use strict';\n\nvar ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue');\n\nvar canDefineProperty = require('./canDefineProperty');\nvar emptyObject = require('fbjs/lib/emptyObject');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * Base class helpers for the updating state of a component.\n */\nfunction ReactComponent(props, context, updater) {\n  this.props = props;\n  this.context = context;\n  this.refs = emptyObject;\n  // We initialize the default updater but the real one gets injected by the\n  // renderer.\n  this.updater = updater || ReactNoopUpdateQueue;\n}\n\nReactComponent.prototype.isReactComponent = {};\n\n/**\n * Sets a subset of the state. Always use this to mutate\n * state. You should treat `this.state` as immutable.\n *\n * There is no guarantee that `this.state` will be immediately updated, so\n * accessing `this.state` after calling this method may return the old value.\n *\n * There is no guarantee that calls to `setState` will run synchronously,\n * as they may eventually be batched together.  You can provide an optional\n * callback that will be executed when the call to setState is actually\n * completed.\n *\n * When a function is provided to setState, it will be called at some point in\n * the future (not synchronously). It will be called with the up to date\n * component arguments (state, props, context). These values can be different\n * from this.* because your function may be called after receiveProps but before\n * shouldComponentUpdate, and this new state, props, and context will not yet be\n * assigned to this.\n *\n * @param {object|function} partialState Next partial state or function to\n *        produce next partial state to be merged with current state.\n * @param {?function} callback Called after state is updated.\n * @final\n * @protected\n */\nReactComponent.prototype.setState = function (partialState, callback) {\n  !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setState(...): takes an object of state variables to update or a ' + 'function which returns an object of state variables.') : invariant(false) : undefined;\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : undefined;\n  }\n  this.updater.enqueueSetState(this, partialState);\n  if (callback) {\n    this.updater.enqueueCallback(this, callback);\n  }\n};\n\n/**\n * Forces an update. This should only be invoked when it is known with\n * certainty that we are **not** in a DOM transaction.\n *\n * You may want to call this when you know that some deeper aspect of the\n * component's state has changed but `setState` was not called.\n *\n * This will not invoke `shouldComponentUpdate`, but it will invoke\n * `componentWillUpdate` and `componentDidUpdate`.\n *\n * @param {?function} callback Called after update is complete.\n * @final\n * @protected\n */\nReactComponent.prototype.forceUpdate = function (callback) {\n  this.updater.enqueueForceUpdate(this);\n  if (callback) {\n    this.updater.enqueueCallback(this, callback);\n  }\n};\n\n/**\n * Deprecated APIs. These APIs used to exist on classic React classes but since\n * we would like to deprecate them, we're not going to move them over to this\n * modern base class. Instead, we define a getter that warns if it's accessed.\n */\nif (process.env.NODE_ENV !== 'production') {\n  var deprecatedAPIs = {\n    getDOMNode: ['getDOMNode', 'Use ReactDOM.findDOMNode(component) instead.'],\n    isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'],\n    replaceProps: ['replaceProps', 'Instead, call render again at the top level.'],\n    replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).'],\n    setProps: ['setProps', 'Instead, call render again at the top level.']\n  };\n  var defineDeprecationWarning = function (methodName, info) {\n    if (canDefineProperty) {\n      Object.defineProperty(ReactComponent.prototype, methodName, {\n        get: function () {\n          process.env.NODE_ENV !== 'production' ? warning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]) : undefined;\n          return undefined;\n        }\n      });\n    }\n  };\n  for (var fnName in deprecatedAPIs) {\n    if (deprecatedAPIs.hasOwnProperty(fnName)) {\n      defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);\n    }\n  }\n}\n\nmodule.exports = ReactComponent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactComponent.js\n ** module id = 137\n ** module chunks = 0\n **/","/**\n * Copyright 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactNoopUpdateQueue\n */\n\n'use strict';\n\nvar warning = require('fbjs/lib/warning');\n\nfunction warnTDZ(publicInstance, callerName) {\n  if (process.env.NODE_ENV !== 'production') {\n    process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, publicInstance.constructor && publicInstance.constructor.displayName || '') : undefined;\n  }\n}\n\n/**\n * This is the abstract API for an update queue.\n */\nvar ReactNoopUpdateQueue = {\n\n  /**\n   * Checks whether or not this composite component is mounted.\n   * @param {ReactClass} publicInstance The instance we want to test.\n   * @return {boolean} True if mounted, false otherwise.\n   * @protected\n   * @final\n   */\n  isMounted: function (publicInstance) {\n    return false;\n  },\n\n  /**\n   * Enqueue a callback that will be executed after all the pending updates\n   * have processed.\n   *\n   * @param {ReactClass} publicInstance The instance to use as `this` context.\n   * @param {?function} callback Called after state is updated.\n   * @internal\n   */\n  enqueueCallback: function (publicInstance, callback) {},\n\n  /**\n   * Forces an update. This should only be invoked when it is known with\n   * certainty that we are **not** in a DOM transaction.\n   *\n   * You may want to call this when you know that some deeper aspect of the\n   * component's state has changed but `setState` was not called.\n   *\n   * This will not invoke `shouldComponentUpdate`, but it will invoke\n   * `componentWillUpdate` and `componentDidUpdate`.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @internal\n   */\n  enqueueForceUpdate: function (publicInstance) {\n    warnTDZ(publicInstance, 'forceUpdate');\n  },\n\n  /**\n   * Replaces all of the state. Always use this or `setState` to mutate state.\n   * You should treat `this.state` as immutable.\n   *\n   * There is no guarantee that `this.state` will be immediately updated, so\n   * accessing `this.state` after calling this method may return the old value.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} completeState Next state.\n   * @internal\n   */\n  enqueueReplaceState: function (publicInstance, completeState) {\n    warnTDZ(publicInstance, 'replaceState');\n  },\n\n  /**\n   * Sets a subset of the state. This only exists because _pendingState is\n   * internal. This provides a merging strategy that is not available to deep\n   * properties which is confusing. TODO: Expose pendingState or don't use it\n   * during the merge.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} partialState Next partial state to be merged with state.\n   * @internal\n   */\n  enqueueSetState: function (publicInstance, partialState) {\n    warnTDZ(publicInstance, 'setState');\n  },\n\n  /**\n   * Sets a subset of the props.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} partialProps Subset of the next props.\n   * @internal\n   */\n  enqueueSetProps: function (publicInstance, partialProps) {\n    warnTDZ(publicInstance, 'setProps');\n  },\n\n  /**\n   * Replaces all of the props.\n   *\n   * @param {ReactClass} publicInstance The instance that should rerender.\n   * @param {object} props New props.\n   * @internal\n   */\n  enqueueReplaceProps: function (publicInstance, props) {\n    warnTDZ(publicInstance, 'replaceProps');\n  }\n\n};\n\nmodule.exports = ReactNoopUpdateQueue;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactNoopUpdateQueue.js\n ** module id = 138\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactReconcileTransaction\n * @typechecks static-only\n */\n\n'use strict';\n\nvar CallbackQueue = require('./CallbackQueue');\nvar PooledClass = require('./PooledClass');\nvar ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');\nvar ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags');\nvar ReactInputSelection = require('./ReactInputSelection');\nvar Transaction = require('./Transaction');\n\nvar assign = require('./Object.assign');\n\n/**\n * Ensures that, when possible, the selection range (currently selected text\n * input) is not disturbed by performing the transaction.\n */\nvar SELECTION_RESTORATION = {\n  /**\n   * @return {Selection} Selection information.\n   */\n  initialize: ReactInputSelection.getSelectionInformation,\n  /**\n   * @param {Selection} sel Selection information returned from `initialize`.\n   */\n  close: ReactInputSelection.restoreSelection\n};\n\n/**\n * Suppresses events (blur/focus) that could be inadvertently dispatched due to\n * high level DOM manipulations (like temporarily removing a text input from the\n * DOM).\n */\nvar EVENT_SUPPRESSION = {\n  /**\n   * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before\n   * the reconciliation.\n   */\n  initialize: function () {\n    var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();\n    ReactBrowserEventEmitter.setEnabled(false);\n    return currentlyEnabled;\n  },\n\n  /**\n   * @param {boolean} previouslyEnabled Enabled status of\n   *   `ReactBrowserEventEmitter` before the reconciliation occurred. `close`\n   *   restores the previous value.\n   */\n  close: function (previouslyEnabled) {\n    ReactBrowserEventEmitter.setEnabled(previouslyEnabled);\n  }\n};\n\n/**\n * Provides a queue for collecting `componentDidMount` and\n * `componentDidUpdate` callbacks during the the transaction.\n */\nvar ON_DOM_READY_QUEUEING = {\n  /**\n   * Initializes the internal `onDOMReady` queue.\n   */\n  initialize: function () {\n    this.reactMountReady.reset();\n  },\n\n  /**\n   * After DOM is flushed, invoke all registered `onDOMReady` callbacks.\n   */\n  close: function () {\n    this.reactMountReady.notifyAll();\n  }\n};\n\n/**\n * Executed within the scope of the `Transaction` instance. Consider these as\n * being member methods, but with an implied ordering while being isolated from\n * each other.\n */\nvar TRANSACTION_WRAPPERS = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING];\n\n/**\n * Currently:\n * - The order that these are listed in the transaction is critical:\n * - Suppresses events.\n * - Restores selection range.\n *\n * Future:\n * - Restore document/overflow scroll positions that were unintentionally\n *   modified via DOM insertions above the top viewport boundary.\n * - Implement/integrate with customized constraint based layout system and keep\n *   track of which dimensions must be remeasured.\n *\n * @class ReactReconcileTransaction\n */\nfunction ReactReconcileTransaction(forceHTML) {\n  this.reinitializeTransaction();\n  // Only server-side rendering really needs this option (see\n  // `ReactServerRendering`), but server-side uses\n  // `ReactServerRenderingTransaction` instead. This option is here so that it's\n  // accessible and defaults to false when `ReactDOMComponent` and\n  // `ReactTextComponent` checks it in `mountComponent`.`\n  this.renderToStaticMarkup = false;\n  this.reactMountReady = CallbackQueue.getPooled(null);\n  this.useCreateElement = !forceHTML && ReactDOMFeatureFlags.useCreateElement;\n}\n\nvar Mixin = {\n  /**\n   * @see Transaction\n   * @abstract\n   * @final\n   * @return {array<object>} List of operation wrap procedures.\n   *   TODO: convert to array<TransactionWrapper>\n   */\n  getTransactionWrappers: function () {\n    return TRANSACTION_WRAPPERS;\n  },\n\n  /**\n   * @return {object} The queue to collect `onDOMReady` callbacks with.\n   */\n  getReactMountReady: function () {\n    return this.reactMountReady;\n  },\n\n  /**\n   * `PooledClass` looks for this, and will invoke this before allowing this\n   * instance to be reused.\n   */\n  destructor: function () {\n    CallbackQueue.release(this.reactMountReady);\n    this.reactMountReady = null;\n  }\n};\n\nassign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin);\n\nPooledClass.addPoolingTo(ReactReconcileTransaction);\n\nmodule.exports = ReactReconcileTransaction;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactReconcileTransaction.js\n ** module id = 139\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactInputSelection\n */\n\n'use strict';\n\nvar ReactDOMSelection = require('./ReactDOMSelection');\n\nvar containsNode = require('fbjs/lib/containsNode');\nvar focusNode = require('fbjs/lib/focusNode');\nvar getActiveElement = require('fbjs/lib/getActiveElement');\n\nfunction isInDocument(node) {\n  return containsNode(document.documentElement, node);\n}\n\n/**\n * @ReactInputSelection: React input selection module. Based on Selection.js,\n * but modified to be suitable for react and has a couple of bug fixes (doesn't\n * assume buttons have range selections allowed).\n * Input selection module for React.\n */\nvar ReactInputSelection = {\n\n  hasSelectionCapabilities: function (elem) {\n    var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n    return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');\n  },\n\n  getSelectionInformation: function () {\n    var focusedElem = getActiveElement();\n    return {\n      focusedElem: focusedElem,\n      selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null\n    };\n  },\n\n  /**\n   * @restoreSelection: If any selection information was potentially lost,\n   * restore it. This is useful when performing operations that could remove dom\n   * nodes and place them back in, resulting in focus being lost.\n   */\n  restoreSelection: function (priorSelectionInformation) {\n    var curFocusedElem = getActiveElement();\n    var priorFocusedElem = priorSelectionInformation.focusedElem;\n    var priorSelectionRange = priorSelectionInformation.selectionRange;\n    if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {\n      if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {\n        ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange);\n      }\n      focusNode(priorFocusedElem);\n    }\n  },\n\n  /**\n   * @getSelection: Gets the selection bounds of a focused textarea, input or\n   * contentEditable node.\n   * -@input: Look up selection bounds of this input\n   * -@return {start: selectionStart, end: selectionEnd}\n   */\n  getSelection: function (input) {\n    var selection;\n\n    if ('selectionStart' in input) {\n      // Modern browser with input or textarea.\n      selection = {\n        start: input.selectionStart,\n        end: input.selectionEnd\n      };\n    } else if (document.selection && (input.nodeName && input.nodeName.toLowerCase() === 'input')) {\n      // IE8 input.\n      var range = document.selection.createRange();\n      // There can only be one selection per document in IE, so it must\n      // be in our element.\n      if (range.parentElement() === input) {\n        selection = {\n          start: -range.moveStart('character', -input.value.length),\n          end: -range.moveEnd('character', -input.value.length)\n        };\n      }\n    } else {\n      // Content editable or old IE textarea.\n      selection = ReactDOMSelection.getOffsets(input);\n    }\n\n    return selection || { start: 0, end: 0 };\n  },\n\n  /**\n   * @setSelection: Sets the selection bounds of a textarea or input and focuses\n   * the input.\n   * -@input     Set selection bounds of this input or textarea\n   * -@offsets   Object of same form that is returned from get*\n   */\n  setSelection: function (input, offsets) {\n    var start = offsets.start;\n    var end = offsets.end;\n    if (typeof end === 'undefined') {\n      end = start;\n    }\n\n    if ('selectionStart' in input) {\n      input.selectionStart = start;\n      input.selectionEnd = Math.min(end, input.value.length);\n    } else if (document.selection && (input.nodeName && input.nodeName.toLowerCase() === 'input')) {\n      var range = input.createTextRange();\n      range.collapse(true);\n      range.moveStart('character', start);\n      range.moveEnd('character', end - start);\n      range.select();\n    } else {\n      ReactDOMSelection.setOffsets(input, offsets);\n    }\n  }\n};\n\nmodule.exports = ReactInputSelection;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactInputSelection.js\n ** module id = 140\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMSelection\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\n\nvar getNodeForCharacterOffset = require('./getNodeForCharacterOffset');\nvar getTextContentAccessor = require('./getTextContentAccessor');\n\n/**\n * While `isCollapsed` is available on the Selection object and `collapsed`\n * is available on the Range object, IE11 sometimes gets them wrong.\n * If the anchor/focus nodes and offsets are the same, the range is collapsed.\n */\nfunction isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) {\n  return anchorNode === focusNode && anchorOffset === focusOffset;\n}\n\n/**\n * Get the appropriate anchor and focus node/offset pairs for IE.\n *\n * The catch here is that IE's selection API doesn't provide information\n * about whether the selection is forward or backward, so we have to\n * behave as though it's always forward.\n *\n * IE text differs from modern selection in that it behaves as though\n * block elements end with a new line. This means character offsets will\n * differ between the two APIs.\n *\n * @param {DOMElement} node\n * @return {object}\n */\nfunction getIEOffsets(node) {\n  var selection = document.selection;\n  var selectedRange = selection.createRange();\n  var selectedLength = selectedRange.text.length;\n\n  // Duplicate selection so we can move range without breaking user selection.\n  var fromStart = selectedRange.duplicate();\n  fromStart.moveToElementText(node);\n  fromStart.setEndPoint('EndToStart', selectedRange);\n\n  var startOffset = fromStart.text.length;\n  var endOffset = startOffset + selectedLength;\n\n  return {\n    start: startOffset,\n    end: endOffset\n  };\n}\n\n/**\n * @param {DOMElement} node\n * @return {?object}\n */\nfunction getModernOffsets(node) {\n  var selection = window.getSelection && window.getSelection();\n\n  if (!selection || selection.rangeCount === 0) {\n    return null;\n  }\n\n  var anchorNode = selection.anchorNode;\n  var anchorOffset = selection.anchorOffset;\n  var focusNode = selection.focusNode;\n  var focusOffset = selection.focusOffset;\n\n  var currentRange = selection.getRangeAt(0);\n\n  // In Firefox, range.startContainer and range.endContainer can be \"anonymous\n  // divs\", e.g. the up/down buttons on an <input type=\"number\">. Anonymous\n  // divs do not seem to expose properties, triggering a \"Permission denied\n  // error\" if any of its properties are accessed. The only seemingly possible\n  // way to avoid erroring is to access a property that typically works for\n  // non-anonymous divs and catch any error that may otherwise arise. See\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=208427\n  try {\n    /* eslint-disable no-unused-expressions */\n    currentRange.startContainer.nodeType;\n    currentRange.endContainer.nodeType;\n    /* eslint-enable no-unused-expressions */\n  } catch (e) {\n    return null;\n  }\n\n  // If the node and offset values are the same, the selection is collapsed.\n  // `Selection.isCollapsed` is available natively, but IE sometimes gets\n  // this value wrong.\n  var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n  var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length;\n\n  var tempRange = currentRange.cloneRange();\n  tempRange.selectNodeContents(node);\n  tempRange.setEnd(currentRange.startContainer, currentRange.startOffset);\n\n  var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset);\n\n  var start = isTempRangeCollapsed ? 0 : tempRange.toString().length;\n  var end = start + rangeLength;\n\n  // Detect whether the selection is backward.\n  var detectionRange = document.createRange();\n  detectionRange.setStart(anchorNode, anchorOffset);\n  detectionRange.setEnd(focusNode, focusOffset);\n  var isBackward = detectionRange.collapsed;\n\n  return {\n    start: isBackward ? end : start,\n    end: isBackward ? start : end\n  };\n}\n\n/**\n * @param {DOMElement|DOMTextNode} node\n * @param {object} offsets\n */\nfunction setIEOffsets(node, offsets) {\n  var range = document.selection.createRange().duplicate();\n  var start, end;\n\n  if (typeof offsets.end === 'undefined') {\n    start = offsets.start;\n    end = start;\n  } else if (offsets.start > offsets.end) {\n    start = offsets.end;\n    end = offsets.start;\n  } else {\n    start = offsets.start;\n    end = offsets.end;\n  }\n\n  range.moveToElementText(node);\n  range.moveStart('character', start);\n  range.setEndPoint('EndToStart', range);\n  range.moveEnd('character', end - start);\n  range.select();\n}\n\n/**\n * In modern non-IE browsers, we can support both forward and backward\n * selections.\n *\n * Note: IE10+ supports the Selection object, but it does not support\n * the `extend` method, which means that even in modern IE, it's not possible\n * to programatically create a backward selection. Thus, for all IE\n * versions, we use the old IE API to create our selections.\n *\n * @param {DOMElement|DOMTextNode} node\n * @param {object} offsets\n */\nfunction setModernOffsets(node, offsets) {\n  if (!window.getSelection) {\n    return;\n  }\n\n  var selection = window.getSelection();\n  var length = node[getTextContentAccessor()].length;\n  var start = Math.min(offsets.start, length);\n  var end = typeof offsets.end === 'undefined' ? start : Math.min(offsets.end, length);\n\n  // IE 11 uses modern selection, but doesn't support the extend method.\n  // Flip backward selections, so we can set with a single range.\n  if (!selection.extend && start > end) {\n    var temp = end;\n    end = start;\n    start = temp;\n  }\n\n  var startMarker = getNodeForCharacterOffset(node, start);\n  var endMarker = getNodeForCharacterOffset(node, end);\n\n  if (startMarker && endMarker) {\n    var range = document.createRange();\n    range.setStart(startMarker.node, startMarker.offset);\n    selection.removeAllRanges();\n\n    if (start > end) {\n      selection.addRange(range);\n      selection.extend(endMarker.node, endMarker.offset);\n    } else {\n      range.setEnd(endMarker.node, endMarker.offset);\n      selection.addRange(range);\n    }\n  }\n}\n\nvar useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window);\n\nvar ReactDOMSelection = {\n  /**\n   * @param {DOMElement} node\n   */\n  getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets,\n\n  /**\n   * @param {DOMElement|DOMTextNode} node\n   * @param {object} offsets\n   */\n  setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets\n};\n\nmodule.exports = ReactDOMSelection;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMSelection.js\n ** module id = 141\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getNodeForCharacterOffset\n */\n\n'use strict';\n\n/**\n * Given any node return the first leaf node without children.\n *\n * @param {DOMElement|DOMTextNode} node\n * @return {DOMElement|DOMTextNode}\n */\nfunction getLeafNode(node) {\n  while (node && node.firstChild) {\n    node = node.firstChild;\n  }\n  return node;\n}\n\n/**\n * Get the next sibling within a container. This will walk up the\n * DOM if a node's siblings have been exhausted.\n *\n * @param {DOMElement|DOMTextNode} node\n * @return {?DOMElement|DOMTextNode}\n */\nfunction getSiblingNode(node) {\n  while (node) {\n    if (node.nextSibling) {\n      return node.nextSibling;\n    }\n    node = node.parentNode;\n  }\n}\n\n/**\n * Get object describing the nodes which contain characters at offset.\n *\n * @param {DOMElement|DOMTextNode} root\n * @param {number} offset\n * @return {?object}\n */\nfunction getNodeForCharacterOffset(root, offset) {\n  var node = getLeafNode(root);\n  var nodeStart = 0;\n  var nodeEnd = 0;\n\n  while (node) {\n    if (node.nodeType === 3) {\n      nodeEnd = nodeStart + node.textContent.length;\n\n      if (nodeStart <= offset && nodeEnd >= offset) {\n        return {\n          node: node,\n          offset: offset - nodeStart\n        };\n      }\n\n      nodeStart = nodeEnd;\n    }\n\n    node = getLeafNode(getSiblingNode(node));\n  }\n}\n\nmodule.exports = getNodeForCharacterOffset;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getNodeForCharacterOffset.js\n ** module id = 142\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getActiveElement\n * @typechecks\n */\n\n/**\n * Same as document.activeElement but wraps in a try-catch block. In IE it is\n * not safe to call document.activeElement if there is nothing focused.\n *\n * The activeElement will be null only if the document or document body is not yet defined.\n */\n'use strict';\n\nfunction getActiveElement() /*?DOMElement*/{\n  if (typeof document === 'undefined') {\n    return null;\n  }\n\n  try {\n    return document.activeElement || document.body;\n  } catch (e) {\n    return document.body;\n  }\n}\n\nmodule.exports = getActiveElement;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/getActiveElement.js\n ** module id = 143\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SelectEventPlugin\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventPropagators = require('./EventPropagators');\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar ReactInputSelection = require('./ReactInputSelection');\nvar SyntheticEvent = require('./SyntheticEvent');\n\nvar getActiveElement = require('fbjs/lib/getActiveElement');\nvar isTextInputElement = require('./isTextInputElement');\nvar keyOf = require('fbjs/lib/keyOf');\nvar shallowEqual = require('fbjs/lib/shallowEqual');\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\nvar skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11;\n\nvar eventTypes = {\n  select: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onSelect: null }),\n      captured: keyOf({ onSelectCapture: null })\n    },\n    dependencies: [topLevelTypes.topBlur, topLevelTypes.topContextMenu, topLevelTypes.topFocus, topLevelTypes.topKeyDown, topLevelTypes.topMouseDown, topLevelTypes.topMouseUp, topLevelTypes.topSelectionChange]\n  }\n};\n\nvar activeElement = null;\nvar activeElementID = null;\nvar lastSelection = null;\nvar mouseDown = false;\n\n// Track whether a listener exists for this plugin. If none exist, we do\n// not extract events.\nvar hasListener = false;\nvar ON_SELECT_KEY = keyOf({ onSelect: null });\n\n/**\n * Get an object which is a unique representation of the current selection.\n *\n * The return value will not be consistent across nodes or browsers, but\n * two identical selections on the same node will return identical objects.\n *\n * @param {DOMElement} node\n * @return {object}\n */\nfunction getSelection(node) {\n  if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) {\n    return {\n      start: node.selectionStart,\n      end: node.selectionEnd\n    };\n  } else if (window.getSelection) {\n    var selection = window.getSelection();\n    return {\n      anchorNode: selection.anchorNode,\n      anchorOffset: selection.anchorOffset,\n      focusNode: selection.focusNode,\n      focusOffset: selection.focusOffset\n    };\n  } else if (document.selection) {\n    var range = document.selection.createRange();\n    return {\n      parentElement: range.parentElement(),\n      text: range.text,\n      top: range.boundingTop,\n      left: range.boundingLeft\n    };\n  }\n}\n\n/**\n * Poll selection to see whether it's changed.\n *\n * @param {object} nativeEvent\n * @return {?SyntheticEvent}\n */\nfunction constructSelectEvent(nativeEvent, nativeEventTarget) {\n  // Ensure we have the right element, and that the user is not dragging a\n  // selection (this matches native `select` event behavior). In HTML5, select\n  // fires only on input and textarea thus if there's no focused element we\n  // won't dispatch.\n  if (mouseDown || activeElement == null || activeElement !== getActiveElement()) {\n    return null;\n  }\n\n  // Only fire when selection has actually changed.\n  var currentSelection = getSelection(activeElement);\n  if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {\n    lastSelection = currentSelection;\n\n    var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementID, nativeEvent, nativeEventTarget);\n\n    syntheticEvent.type = 'select';\n    syntheticEvent.target = activeElement;\n\n    EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent);\n\n    return syntheticEvent;\n  }\n\n  return null;\n}\n\n/**\n * This plugin creates an `onSelect` event that normalizes select events\n * across form elements.\n *\n * Supported elements are:\n * - input (see `isTextInputElement`)\n * - textarea\n * - contentEditable\n *\n * This differs from native browser implementations in the following ways:\n * - Fires on contentEditable fields as well as inputs.\n * - Fires for collapsed selection.\n * - Fires after user input.\n */\nvar SelectEventPlugin = {\n\n  eventTypes: eventTypes,\n\n  /**\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {DOMEventTarget} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native browser event.\n   * @return {*} An accumulation of synthetic events.\n   * @see {EventPluginHub.extractEvents}\n   */\n  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n    if (!hasListener) {\n      return null;\n    }\n\n    switch (topLevelType) {\n      // Track the input node that has focus.\n      case topLevelTypes.topFocus:\n        if (isTextInputElement(topLevelTarget) || topLevelTarget.contentEditable === 'true') {\n          activeElement = topLevelTarget;\n          activeElementID = topLevelTargetID;\n          lastSelection = null;\n        }\n        break;\n      case topLevelTypes.topBlur:\n        activeElement = null;\n        activeElementID = null;\n        lastSelection = null;\n        break;\n\n      // Don't fire the event while the user is dragging. This matches the\n      // semantics of the native select event.\n      case topLevelTypes.topMouseDown:\n        mouseDown = true;\n        break;\n      case topLevelTypes.topContextMenu:\n      case topLevelTypes.topMouseUp:\n        mouseDown = false;\n        return constructSelectEvent(nativeEvent, nativeEventTarget);\n\n      // Chrome and IE fire non-standard event when selection is changed (and\n      // sometimes when it hasn't). IE's event fires out of order with respect\n      // to key and input events on deletion, so we discard it.\n      //\n      // Firefox doesn't support selectionchange, so check selection status\n      // after each key entry. The selection changes after keydown and before\n      // keyup, but we check on keydown as well in the case of holding down a\n      // key, when multiple keydown events are fired but only one keyup is.\n      // This is also our approach for IE handling, for the reason above.\n      case topLevelTypes.topSelectionChange:\n        if (skipSelectionChangeEvent) {\n          break;\n        }\n      // falls through\n      case topLevelTypes.topKeyDown:\n      case topLevelTypes.topKeyUp:\n        return constructSelectEvent(nativeEvent, nativeEventTarget);\n    }\n\n    return null;\n  },\n\n  didPutListener: function (id, registrationName, listener) {\n    if (registrationName === ON_SELECT_KEY) {\n      hasListener = true;\n    }\n  }\n};\n\nmodule.exports = SelectEventPlugin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SelectEventPlugin.js\n ** module id = 144\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ServerReactRootIndex\n * @typechecks\n */\n\n'use strict';\n\n/**\n * Size of the reactRoot ID space. We generate random numbers for React root\n * IDs and if there's a collision the events and DOM update system will\n * get confused. In the future we need a way to generate GUIDs but for\n * now this will work on a smaller scale.\n */\nvar GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);\n\nvar ServerReactRootIndex = {\n  createReactRootIndex: function () {\n    return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);\n  }\n};\n\nmodule.exports = ServerReactRootIndex;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ServerReactRootIndex.js\n ** module id = 145\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SimpleEventPlugin\n */\n\n'use strict';\n\nvar EventConstants = require('./EventConstants');\nvar EventListener = require('fbjs/lib/EventListener');\nvar EventPropagators = require('./EventPropagators');\nvar ReactMount = require('./ReactMount');\nvar SyntheticClipboardEvent = require('./SyntheticClipboardEvent');\nvar SyntheticEvent = require('./SyntheticEvent');\nvar SyntheticFocusEvent = require('./SyntheticFocusEvent');\nvar SyntheticKeyboardEvent = require('./SyntheticKeyboardEvent');\nvar SyntheticMouseEvent = require('./SyntheticMouseEvent');\nvar SyntheticDragEvent = require('./SyntheticDragEvent');\nvar SyntheticTouchEvent = require('./SyntheticTouchEvent');\nvar SyntheticUIEvent = require('./SyntheticUIEvent');\nvar SyntheticWheelEvent = require('./SyntheticWheelEvent');\n\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar getEventCharCode = require('./getEventCharCode');\nvar invariant = require('fbjs/lib/invariant');\nvar keyOf = require('fbjs/lib/keyOf');\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\nvar eventTypes = {\n  abort: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onAbort: true }),\n      captured: keyOf({ onAbortCapture: true })\n    }\n  },\n  blur: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onBlur: true }),\n      captured: keyOf({ onBlurCapture: true })\n    }\n  },\n  canPlay: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCanPlay: true }),\n      captured: keyOf({ onCanPlayCapture: true })\n    }\n  },\n  canPlayThrough: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCanPlayThrough: true }),\n      captured: keyOf({ onCanPlayThroughCapture: true })\n    }\n  },\n  click: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onClick: true }),\n      captured: keyOf({ onClickCapture: true })\n    }\n  },\n  contextMenu: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onContextMenu: true }),\n      captured: keyOf({ onContextMenuCapture: true })\n    }\n  },\n  copy: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCopy: true }),\n      captured: keyOf({ onCopyCapture: true })\n    }\n  },\n  cut: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onCut: true }),\n      captured: keyOf({ onCutCapture: true })\n    }\n  },\n  doubleClick: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDoubleClick: true }),\n      captured: keyOf({ onDoubleClickCapture: true })\n    }\n  },\n  drag: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDrag: true }),\n      captured: keyOf({ onDragCapture: true })\n    }\n  },\n  dragEnd: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDragEnd: true }),\n      captured: keyOf({ onDragEndCapture: true })\n    }\n  },\n  dragEnter: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDragEnter: true }),\n      captured: keyOf({ onDragEnterCapture: true })\n    }\n  },\n  dragExit: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDragExit: true }),\n      captured: keyOf({ onDragExitCapture: true })\n    }\n  },\n  dragLeave: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDragLeave: true }),\n      captured: keyOf({ onDragLeaveCapture: true })\n    }\n  },\n  dragOver: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDragOver: true }),\n      captured: keyOf({ onDragOverCapture: true })\n    }\n  },\n  dragStart: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDragStart: true }),\n      captured: keyOf({ onDragStartCapture: true })\n    }\n  },\n  drop: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDrop: true }),\n      captured: keyOf({ onDropCapture: true })\n    }\n  },\n  durationChange: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onDurationChange: true }),\n      captured: keyOf({ onDurationChangeCapture: true })\n    }\n  },\n  emptied: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onEmptied: true }),\n      captured: keyOf({ onEmptiedCapture: true })\n    }\n  },\n  encrypted: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onEncrypted: true }),\n      captured: keyOf({ onEncryptedCapture: true })\n    }\n  },\n  ended: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onEnded: true }),\n      captured: keyOf({ onEndedCapture: true })\n    }\n  },\n  error: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onError: true }),\n      captured: keyOf({ onErrorCapture: true })\n    }\n  },\n  focus: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onFocus: true }),\n      captured: keyOf({ onFocusCapture: true })\n    }\n  },\n  input: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onInput: true }),\n      captured: keyOf({ onInputCapture: true })\n    }\n  },\n  keyDown: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onKeyDown: true }),\n      captured: keyOf({ onKeyDownCapture: true })\n    }\n  },\n  keyPress: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onKeyPress: true }),\n      captured: keyOf({ onKeyPressCapture: true })\n    }\n  },\n  keyUp: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onKeyUp: true }),\n      captured: keyOf({ onKeyUpCapture: true })\n    }\n  },\n  load: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onLoad: true }),\n      captured: keyOf({ onLoadCapture: true })\n    }\n  },\n  loadedData: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onLoadedData: true }),\n      captured: keyOf({ onLoadedDataCapture: true })\n    }\n  },\n  loadedMetadata: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onLoadedMetadata: true }),\n      captured: keyOf({ onLoadedMetadataCapture: true })\n    }\n  },\n  loadStart: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onLoadStart: true }),\n      captured: keyOf({ onLoadStartCapture: true })\n    }\n  },\n  // Note: We do not allow listening to mouseOver events. Instead, use the\n  // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.\n  mouseDown: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onMouseDown: true }),\n      captured: keyOf({ onMouseDownCapture: true })\n    }\n  },\n  mouseMove: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onMouseMove: true }),\n      captured: keyOf({ onMouseMoveCapture: true })\n    }\n  },\n  mouseOut: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onMouseOut: true }),\n      captured: keyOf({ onMouseOutCapture: true })\n    }\n  },\n  mouseOver: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onMouseOver: true }),\n      captured: keyOf({ onMouseOverCapture: true })\n    }\n  },\n  mouseUp: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onMouseUp: true }),\n      captured: keyOf({ onMouseUpCapture: true })\n    }\n  },\n  paste: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onPaste: true }),\n      captured: keyOf({ onPasteCapture: true })\n    }\n  },\n  pause: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onPause: true }),\n      captured: keyOf({ onPauseCapture: true })\n    }\n  },\n  play: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onPlay: true }),\n      captured: keyOf({ onPlayCapture: true })\n    }\n  },\n  playing: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onPlaying: true }),\n      captured: keyOf({ onPlayingCapture: true })\n    }\n  },\n  progress: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onProgress: true }),\n      captured: keyOf({ onProgressCapture: true })\n    }\n  },\n  rateChange: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onRateChange: true }),\n      captured: keyOf({ onRateChangeCapture: true })\n    }\n  },\n  reset: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onReset: true }),\n      captured: keyOf({ onResetCapture: true })\n    }\n  },\n  scroll: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onScroll: true }),\n      captured: keyOf({ onScrollCapture: true })\n    }\n  },\n  seeked: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onSeeked: true }),\n      captured: keyOf({ onSeekedCapture: true })\n    }\n  },\n  seeking: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onSeeking: true }),\n      captured: keyOf({ onSeekingCapture: true })\n    }\n  },\n  stalled: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onStalled: true }),\n      captured: keyOf({ onStalledCapture: true })\n    }\n  },\n  submit: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onSubmit: true }),\n      captured: keyOf({ onSubmitCapture: true })\n    }\n  },\n  suspend: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onSuspend: true }),\n      captured: keyOf({ onSuspendCapture: true })\n    }\n  },\n  timeUpdate: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onTimeUpdate: true }),\n      captured: keyOf({ onTimeUpdateCapture: true })\n    }\n  },\n  touchCancel: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onTouchCancel: true }),\n      captured: keyOf({ onTouchCancelCapture: true })\n    }\n  },\n  touchEnd: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onTouchEnd: true }),\n      captured: keyOf({ onTouchEndCapture: true })\n    }\n  },\n  touchMove: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onTouchMove: true }),\n      captured: keyOf({ onTouchMoveCapture: true })\n    }\n  },\n  touchStart: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onTouchStart: true }),\n      captured: keyOf({ onTouchStartCapture: true })\n    }\n  },\n  volumeChange: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onVolumeChange: true }),\n      captured: keyOf({ onVolumeChangeCapture: true })\n    }\n  },\n  waiting: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onWaiting: true }),\n      captured: keyOf({ onWaitingCapture: true })\n    }\n  },\n  wheel: {\n    phasedRegistrationNames: {\n      bubbled: keyOf({ onWheel: true }),\n      captured: keyOf({ onWheelCapture: true })\n    }\n  }\n};\n\nvar topLevelEventsToDispatchConfig = {\n  topAbort: eventTypes.abort,\n  topBlur: eventTypes.blur,\n  topCanPlay: eventTypes.canPlay,\n  topCanPlayThrough: eventTypes.canPlayThrough,\n  topClick: eventTypes.click,\n  topContextMenu: eventTypes.contextMenu,\n  topCopy: eventTypes.copy,\n  topCut: eventTypes.cut,\n  topDoubleClick: eventTypes.doubleClick,\n  topDrag: eventTypes.drag,\n  topDragEnd: eventTypes.dragEnd,\n  topDragEnter: eventTypes.dragEnter,\n  topDragExit: eventTypes.dragExit,\n  topDragLeave: eventTypes.dragLeave,\n  topDragOver: eventTypes.dragOver,\n  topDragStart: eventTypes.dragStart,\n  topDrop: eventTypes.drop,\n  topDurationChange: eventTypes.durationChange,\n  topEmptied: eventTypes.emptied,\n  topEncrypted: eventTypes.encrypted,\n  topEnded: eventTypes.ended,\n  topError: eventTypes.error,\n  topFocus: eventTypes.focus,\n  topInput: eventTypes.input,\n  topKeyDown: eventTypes.keyDown,\n  topKeyPress: eventTypes.keyPress,\n  topKeyUp: eventTypes.keyUp,\n  topLoad: eventTypes.load,\n  topLoadedData: eventTypes.loadedData,\n  topLoadedMetadata: eventTypes.loadedMetadata,\n  topLoadStart: eventTypes.loadStart,\n  topMouseDown: eventTypes.mouseDown,\n  topMouseMove: eventTypes.mouseMove,\n  topMouseOut: eventTypes.mouseOut,\n  topMouseOver: eventTypes.mouseOver,\n  topMouseUp: eventTypes.mouseUp,\n  topPaste: eventTypes.paste,\n  topPause: eventTypes.pause,\n  topPlay: eventTypes.play,\n  topPlaying: eventTypes.playing,\n  topProgress: eventTypes.progress,\n  topRateChange: eventTypes.rateChange,\n  topReset: eventTypes.reset,\n  topScroll: eventTypes.scroll,\n  topSeeked: eventTypes.seeked,\n  topSeeking: eventTypes.seeking,\n  topStalled: eventTypes.stalled,\n  topSubmit: eventTypes.submit,\n  topSuspend: eventTypes.suspend,\n  topTimeUpdate: eventTypes.timeUpdate,\n  topTouchCancel: eventTypes.touchCancel,\n  topTouchEnd: eventTypes.touchEnd,\n  topTouchMove: eventTypes.touchMove,\n  topTouchStart: eventTypes.touchStart,\n  topVolumeChange: eventTypes.volumeChange,\n  topWaiting: eventTypes.waiting,\n  topWheel: eventTypes.wheel\n};\n\nfor (var type in topLevelEventsToDispatchConfig) {\n  topLevelEventsToDispatchConfig[type].dependencies = [type];\n}\n\nvar ON_CLICK_KEY = keyOf({ onClick: null });\nvar onClickListeners = {};\n\nvar SimpleEventPlugin = {\n\n  eventTypes: eventTypes,\n\n  /**\n   * @param {string} topLevelType Record from `EventConstants`.\n   * @param {DOMEventTarget} topLevelTarget The listening component root node.\n   * @param {string} topLevelTargetID ID of `topLevelTarget`.\n   * @param {object} nativeEvent Native browser event.\n   * @return {*} An accumulation of synthetic events.\n   * @see {EventPluginHub.extractEvents}\n   */\n  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {\n    var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];\n    if (!dispatchConfig) {\n      return null;\n    }\n    var EventConstructor;\n    switch (topLevelType) {\n      case topLevelTypes.topAbort:\n      case topLevelTypes.topCanPlay:\n      case topLevelTypes.topCanPlayThrough:\n      case topLevelTypes.topDurationChange:\n      case topLevelTypes.topEmptied:\n      case topLevelTypes.topEncrypted:\n      case topLevelTypes.topEnded:\n      case topLevelTypes.topError:\n      case topLevelTypes.topInput:\n      case topLevelTypes.topLoad:\n      case topLevelTypes.topLoadedData:\n      case topLevelTypes.topLoadedMetadata:\n      case topLevelTypes.topLoadStart:\n      case topLevelTypes.topPause:\n      case topLevelTypes.topPlay:\n      case topLevelTypes.topPlaying:\n      case topLevelTypes.topProgress:\n      case topLevelTypes.topRateChange:\n      case topLevelTypes.topReset:\n      case topLevelTypes.topSeeked:\n      case topLevelTypes.topSeeking:\n      case topLevelTypes.topStalled:\n      case topLevelTypes.topSubmit:\n      case topLevelTypes.topSuspend:\n      case topLevelTypes.topTimeUpdate:\n      case topLevelTypes.topVolumeChange:\n      case topLevelTypes.topWaiting:\n        // HTML Events\n        // @see http://www.w3.org/TR/html5/index.html#events-0\n        EventConstructor = SyntheticEvent;\n        break;\n      case topLevelTypes.topKeyPress:\n        // FireFox creates a keypress event for function keys too. This removes\n        // the unwanted keypress events. Enter is however both printable and\n        // non-printable. One would expect Tab to be as well (but it isn't).\n        if (getEventCharCode(nativeEvent) === 0) {\n          return null;\n        }\n      /* falls through */\n      case topLevelTypes.topKeyDown:\n      case topLevelTypes.topKeyUp:\n        EventConstructor = SyntheticKeyboardEvent;\n        break;\n      case topLevelTypes.topBlur:\n      case topLevelTypes.topFocus:\n        EventConstructor = SyntheticFocusEvent;\n        break;\n      case topLevelTypes.topClick:\n        // Firefox creates a click event on right mouse clicks. This removes the\n        // unwanted click events.\n        if (nativeEvent.button === 2) {\n          return null;\n        }\n      /* falls through */\n      case topLevelTypes.topContextMenu:\n      case topLevelTypes.topDoubleClick:\n      case topLevelTypes.topMouseDown:\n      case topLevelTypes.topMouseMove:\n      case topLevelTypes.topMouseOut:\n      case topLevelTypes.topMouseOver:\n      case topLevelTypes.topMouseUp:\n        EventConstructor = SyntheticMouseEvent;\n        break;\n      case topLevelTypes.topDrag:\n      case topLevelTypes.topDragEnd:\n      case topLevelTypes.topDragEnter:\n      case topLevelTypes.topDragExit:\n      case topLevelTypes.topDragLeave:\n      case topLevelTypes.topDragOver:\n      case topLevelTypes.topDragStart:\n      case topLevelTypes.topDrop:\n        EventConstructor = SyntheticDragEvent;\n        break;\n      case topLevelTypes.topTouchCancel:\n      case topLevelTypes.topTouchEnd:\n      case topLevelTypes.topTouchMove:\n      case topLevelTypes.topTouchStart:\n        EventConstructor = SyntheticTouchEvent;\n        break;\n      case topLevelTypes.topScroll:\n        EventConstructor = SyntheticUIEvent;\n        break;\n      case topLevelTypes.topWheel:\n        EventConstructor = SyntheticWheelEvent;\n        break;\n      case topLevelTypes.topCopy:\n      case topLevelTypes.topCut:\n      case topLevelTypes.topPaste:\n        EventConstructor = SyntheticClipboardEvent;\n        break;\n    }\n    !EventConstructor ? process.env.NODE_ENV !== 'production' ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : invariant(false) : undefined;\n    var event = EventConstructor.getPooled(dispatchConfig, topLevelTargetID, nativeEvent, nativeEventTarget);\n    EventPropagators.accumulateTwoPhaseDispatches(event);\n    return event;\n  },\n\n  didPutListener: function (id, registrationName, listener) {\n    // Mobile Safari does not fire properly bubble click events on\n    // non-interactive elements, which means delegated click listeners do not\n    // fire. The workaround for this bug involves attaching an empty click\n    // listener on the target node.\n    if (registrationName === ON_CLICK_KEY) {\n      var node = ReactMount.getNode(id);\n      if (!onClickListeners[id]) {\n        onClickListeners[id] = EventListener.listen(node, 'click', emptyFunction);\n      }\n    }\n  },\n\n  willDeleteListener: function (id, registrationName) {\n    if (registrationName === ON_CLICK_KEY) {\n      onClickListeners[id].remove();\n      delete onClickListeners[id];\n    }\n  }\n\n};\n\nmodule.exports = SimpleEventPlugin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SimpleEventPlugin.js\n ** module id = 146\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticClipboardEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticEvent = require('./SyntheticEvent');\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/clipboard-apis/\n */\nvar ClipboardEventInterface = {\n  clipboardData: function (event) {\n    return 'clipboardData' in event ? event.clipboardData : window.clipboardData;\n  }\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);\n\nmodule.exports = SyntheticClipboardEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticClipboardEvent.js\n ** module id = 147\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticFocusEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticUIEvent = require('./SyntheticUIEvent');\n\n/**\n * @interface FocusEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar FocusEventInterface = {\n  relatedTarget: null\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);\n\nmodule.exports = SyntheticFocusEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticFocusEvent.js\n ** module id = 148\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticKeyboardEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticUIEvent = require('./SyntheticUIEvent');\n\nvar getEventCharCode = require('./getEventCharCode');\nvar getEventKey = require('./getEventKey');\nvar getEventModifierState = require('./getEventModifierState');\n\n/**\n * @interface KeyboardEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar KeyboardEventInterface = {\n  key: getEventKey,\n  location: null,\n  ctrlKey: null,\n  shiftKey: null,\n  altKey: null,\n  metaKey: null,\n  repeat: null,\n  locale: null,\n  getModifierState: getEventModifierState,\n  // Legacy Interface\n  charCode: function (event) {\n    // `charCode` is the result of a KeyPress event and represents the value of\n    // the actual printable character.\n\n    // KeyPress is deprecated, but its replacement is not yet final and not\n    // implemented in any major browser. Only KeyPress has charCode.\n    if (event.type === 'keypress') {\n      return getEventCharCode(event);\n    }\n    return 0;\n  },\n  keyCode: function (event) {\n    // `keyCode` is the result of a KeyDown/Up event and represents the value of\n    // physical keyboard key.\n\n    // The actual meaning of the value depends on the users' keyboard layout\n    // which cannot be detected. Assuming that it is a US keyboard layout\n    // provides a surprisingly accurate mapping for US and European users.\n    // Due to this, it is left to the user to implement at this time.\n    if (event.type === 'keydown' || event.type === 'keyup') {\n      return event.keyCode;\n    }\n    return 0;\n  },\n  which: function (event) {\n    // `which` is an alias for either `keyCode` or `charCode` depending on the\n    // type of the event.\n    if (event.type === 'keypress') {\n      return getEventCharCode(event);\n    }\n    if (event.type === 'keydown' || event.type === 'keyup') {\n      return event.keyCode;\n    }\n    return 0;\n  }\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);\n\nmodule.exports = SyntheticKeyboardEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticKeyboardEvent.js\n ** module id = 149\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getEventCharCode\n * @typechecks static-only\n */\n\n'use strict';\n\n/**\n * `charCode` represents the actual \"character code\" and is safe to use with\n * `String.fromCharCode`. As such, only keys that correspond to printable\n * characters produce a valid `charCode`, the only exception to this is Enter.\n * The Tab-key is considered non-printable and does not have a `charCode`,\n * presumably because it does not produce a tab-character in browsers.\n *\n * @param {object} nativeEvent Native browser event.\n * @return {number} Normalized `charCode` property.\n */\nfunction getEventCharCode(nativeEvent) {\n  var charCode;\n  var keyCode = nativeEvent.keyCode;\n\n  if ('charCode' in nativeEvent) {\n    charCode = nativeEvent.charCode;\n\n    // FF does not set `charCode` for the Enter-key, check against `keyCode`.\n    if (charCode === 0 && keyCode === 13) {\n      charCode = 13;\n    }\n  } else {\n    // IE8 does not implement `charCode`, but `keyCode` has the correct value.\n    charCode = keyCode;\n  }\n\n  // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.\n  // Must not discard the (non-)printable Enter-key.\n  if (charCode >= 32 || charCode === 13) {\n    return charCode;\n  }\n\n  return 0;\n}\n\nmodule.exports = getEventCharCode;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getEventCharCode.js\n ** module id = 150\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule getEventKey\n * @typechecks static-only\n */\n\n'use strict';\n\nvar getEventCharCode = require('./getEventCharCode');\n\n/**\n * Normalization of deprecated HTML5 `key` values\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names\n */\nvar normalizeKey = {\n  'Esc': 'Escape',\n  'Spacebar': ' ',\n  'Left': 'ArrowLeft',\n  'Up': 'ArrowUp',\n  'Right': 'ArrowRight',\n  'Down': 'ArrowDown',\n  'Del': 'Delete',\n  'Win': 'OS',\n  'Menu': 'ContextMenu',\n  'Apps': 'ContextMenu',\n  'Scroll': 'ScrollLock',\n  'MozPrintableKey': 'Unidentified'\n};\n\n/**\n * Translation from legacy `keyCode` to HTML5 `key`\n * Only special keys supported, all others depend on keyboard layout or browser\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names\n */\nvar translateToKey = {\n  8: 'Backspace',\n  9: 'Tab',\n  12: 'Clear',\n  13: 'Enter',\n  16: 'Shift',\n  17: 'Control',\n  18: 'Alt',\n  19: 'Pause',\n  20: 'CapsLock',\n  27: 'Escape',\n  32: ' ',\n  33: 'PageUp',\n  34: 'PageDown',\n  35: 'End',\n  36: 'Home',\n  37: 'ArrowLeft',\n  38: 'ArrowUp',\n  39: 'ArrowRight',\n  40: 'ArrowDown',\n  45: 'Insert',\n  46: 'Delete',\n  112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6',\n  118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12',\n  144: 'NumLock',\n  145: 'ScrollLock',\n  224: 'Meta'\n};\n\n/**\n * @param {object} nativeEvent Native browser event.\n * @return {string} Normalized `key` property.\n */\nfunction getEventKey(nativeEvent) {\n  if (nativeEvent.key) {\n    // Normalize inconsistent values reported by browsers due to\n    // implementations of a working draft specification.\n\n    // FireFox implements `key` but returns `MozPrintableKey` for all\n    // printable characters (normalized to `Unidentified`), ignore it.\n    var key = normalizeKey[nativeEvent.key] || nativeEvent.key;\n    if (key !== 'Unidentified') {\n      return key;\n    }\n  }\n\n  // Browser does not implement `key`, polyfill as much of it as we can.\n  if (nativeEvent.type === 'keypress') {\n    var charCode = getEventCharCode(nativeEvent);\n\n    // The enter-key is technically both printable and non-printable and can\n    // thus be captured by `keypress`, no other non-printable key should.\n    return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);\n  }\n  if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {\n    // While user keyboard layout determines the actual meaning of each\n    // `keyCode` value, almost all function keys have a universal value.\n    return translateToKey[nativeEvent.keyCode] || 'Unidentified';\n  }\n  return '';\n}\n\nmodule.exports = getEventKey;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/getEventKey.js\n ** module id = 151\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticDragEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticMouseEvent = require('./SyntheticMouseEvent');\n\n/**\n * @interface DragEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar DragEventInterface = {\n  dataTransfer: null\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);\n\nmodule.exports = SyntheticDragEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticDragEvent.js\n ** module id = 152\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticTouchEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticUIEvent = require('./SyntheticUIEvent');\n\nvar getEventModifierState = require('./getEventModifierState');\n\n/**\n * @interface TouchEvent\n * @see http://www.w3.org/TR/touch-events/\n */\nvar TouchEventInterface = {\n  touches: null,\n  targetTouches: null,\n  changedTouches: null,\n  altKey: null,\n  metaKey: null,\n  ctrlKey: null,\n  shiftKey: null,\n  getModifierState: getEventModifierState\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);\n\nmodule.exports = SyntheticTouchEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticTouchEvent.js\n ** module id = 153\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SyntheticWheelEvent\n * @typechecks static-only\n */\n\n'use strict';\n\nvar SyntheticMouseEvent = require('./SyntheticMouseEvent');\n\n/**\n * @interface WheelEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar WheelEventInterface = {\n  deltaX: function (event) {\n    return 'deltaX' in event ? event.deltaX :\n    // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).\n    'wheelDeltaX' in event ? -event.wheelDeltaX : 0;\n  },\n  deltaY: function (event) {\n    return 'deltaY' in event ? event.deltaY :\n    // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).\n    'wheelDeltaY' in event ? -event.wheelDeltaY :\n    // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).\n    'wheelDelta' in event ? -event.wheelDelta : 0;\n  },\n  deltaZ: null,\n\n  // Browsers without \"deltaMode\" is reporting in raw wheel delta where one\n  // notch on the scroll is always +/- 120, roughly equivalent to pixels.\n  // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or\n  // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.\n  deltaMode: null\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticMouseEvent}\n */\nfunction SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n  SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);\n\nmodule.exports = SyntheticWheelEvent;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SyntheticWheelEvent.js\n ** module id = 154\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule SVGDOMPropertyConfig\n */\n\n'use strict';\n\nvar DOMProperty = require('./DOMProperty');\n\nvar MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;\n\nvar NS = {\n  xlink: 'http://www.w3.org/1999/xlink',\n  xml: 'http://www.w3.org/XML/1998/namespace'\n};\n\nvar SVGDOMPropertyConfig = {\n  Properties: {\n    clipPath: MUST_USE_ATTRIBUTE,\n    cx: MUST_USE_ATTRIBUTE,\n    cy: MUST_USE_ATTRIBUTE,\n    d: MUST_USE_ATTRIBUTE,\n    dx: MUST_USE_ATTRIBUTE,\n    dy: MUST_USE_ATTRIBUTE,\n    fill: MUST_USE_ATTRIBUTE,\n    fillOpacity: MUST_USE_ATTRIBUTE,\n    fontFamily: MUST_USE_ATTRIBUTE,\n    fontSize: MUST_USE_ATTRIBUTE,\n    fx: MUST_USE_ATTRIBUTE,\n    fy: MUST_USE_ATTRIBUTE,\n    gradientTransform: MUST_USE_ATTRIBUTE,\n    gradientUnits: MUST_USE_ATTRIBUTE,\n    markerEnd: MUST_USE_ATTRIBUTE,\n    markerMid: MUST_USE_ATTRIBUTE,\n    markerStart: MUST_USE_ATTRIBUTE,\n    offset: MUST_USE_ATTRIBUTE,\n    opacity: MUST_USE_ATTRIBUTE,\n    patternContentUnits: MUST_USE_ATTRIBUTE,\n    patternUnits: MUST_USE_ATTRIBUTE,\n    points: MUST_USE_ATTRIBUTE,\n    preserveAspectRatio: MUST_USE_ATTRIBUTE,\n    r: MUST_USE_ATTRIBUTE,\n    rx: MUST_USE_ATTRIBUTE,\n    ry: MUST_USE_ATTRIBUTE,\n    spreadMethod: MUST_USE_ATTRIBUTE,\n    stopColor: MUST_USE_ATTRIBUTE,\n    stopOpacity: MUST_USE_ATTRIBUTE,\n    stroke: MUST_USE_ATTRIBUTE,\n    strokeDasharray: MUST_USE_ATTRIBUTE,\n    strokeLinecap: MUST_USE_ATTRIBUTE,\n    strokeOpacity: MUST_USE_ATTRIBUTE,\n    strokeWidth: MUST_USE_ATTRIBUTE,\n    textAnchor: MUST_USE_ATTRIBUTE,\n    transform: MUST_USE_ATTRIBUTE,\n    version: MUST_USE_ATTRIBUTE,\n    viewBox: MUST_USE_ATTRIBUTE,\n    x1: MUST_USE_ATTRIBUTE,\n    x2: MUST_USE_ATTRIBUTE,\n    x: MUST_USE_ATTRIBUTE,\n    xlinkActuate: MUST_USE_ATTRIBUTE,\n    xlinkArcrole: MUST_USE_ATTRIBUTE,\n    xlinkHref: MUST_USE_ATTRIBUTE,\n    xlinkRole: MUST_USE_ATTRIBUTE,\n    xlinkShow: MUST_USE_ATTRIBUTE,\n    xlinkTitle: MUST_USE_ATTRIBUTE,\n    xlinkType: MUST_USE_ATTRIBUTE,\n    xmlBase: MUST_USE_ATTRIBUTE,\n    xmlLang: MUST_USE_ATTRIBUTE,\n    xmlSpace: MUST_USE_ATTRIBUTE,\n    y1: MUST_USE_ATTRIBUTE,\n    y2: MUST_USE_ATTRIBUTE,\n    y: MUST_USE_ATTRIBUTE\n  },\n  DOMAttributeNamespaces: {\n    xlinkActuate: NS.xlink,\n    xlinkArcrole: NS.xlink,\n    xlinkHref: NS.xlink,\n    xlinkRole: NS.xlink,\n    xlinkShow: NS.xlink,\n    xlinkTitle: NS.xlink,\n    xlinkType: NS.xlink,\n    xmlBase: NS.xml,\n    xmlLang: NS.xml,\n    xmlSpace: NS.xml\n  },\n  DOMAttributeNames: {\n    clipPath: 'clip-path',\n    fillOpacity: 'fill-opacity',\n    fontFamily: 'font-family',\n    fontSize: 'font-size',\n    gradientTransform: 'gradientTransform',\n    gradientUnits: 'gradientUnits',\n    markerEnd: 'marker-end',\n    markerMid: 'marker-mid',\n    markerStart: 'marker-start',\n    patternContentUnits: 'patternContentUnits',\n    patternUnits: 'patternUnits',\n    preserveAspectRatio: 'preserveAspectRatio',\n    spreadMethod: 'spreadMethod',\n    stopColor: 'stop-color',\n    stopOpacity: 'stop-opacity',\n    strokeDasharray: 'stroke-dasharray',\n    strokeLinecap: 'stroke-linecap',\n    strokeOpacity: 'stroke-opacity',\n    strokeWidth: 'stroke-width',\n    textAnchor: 'text-anchor',\n    viewBox: 'viewBox',\n    xlinkActuate: 'xlink:actuate',\n    xlinkArcrole: 'xlink:arcrole',\n    xlinkHref: 'xlink:href',\n    xlinkRole: 'xlink:role',\n    xlinkShow: 'xlink:show',\n    xlinkTitle: 'xlink:title',\n    xlinkType: 'xlink:type',\n    xmlBase: 'xml:base',\n    xmlLang: 'xml:lang',\n    xmlSpace: 'xml:space'\n  }\n};\n\nmodule.exports = SVGDOMPropertyConfig;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/SVGDOMPropertyConfig.js\n ** module id = 155\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDefaultPerf\n * @typechecks static-only\n */\n\n'use strict';\n\nvar DOMProperty = require('./DOMProperty');\nvar ReactDefaultPerfAnalysis = require('./ReactDefaultPerfAnalysis');\nvar ReactMount = require('./ReactMount');\nvar ReactPerf = require('./ReactPerf');\n\nvar performanceNow = require('fbjs/lib/performanceNow');\n\nfunction roundFloat(val) {\n  return Math.floor(val * 100) / 100;\n}\n\nfunction addValue(obj, key, val) {\n  obj[key] = (obj[key] || 0) + val;\n}\n\nvar ReactDefaultPerf = {\n  _allMeasurements: [], // last item in the list is the current one\n  _mountStack: [0],\n  _injected: false,\n\n  start: function () {\n    if (!ReactDefaultPerf._injected) {\n      ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);\n    }\n\n    ReactDefaultPerf._allMeasurements.length = 0;\n    ReactPerf.enableMeasure = true;\n  },\n\n  stop: function () {\n    ReactPerf.enableMeasure = false;\n  },\n\n  getLastMeasurements: function () {\n    return ReactDefaultPerf._allMeasurements;\n  },\n\n  printExclusive: function (measurements) {\n    measurements = measurements || ReactDefaultPerf._allMeasurements;\n    var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements);\n    console.table(summary.map(function (item) {\n      return {\n        'Component class name': item.componentName,\n        'Total inclusive time (ms)': roundFloat(item.inclusive),\n        'Exclusive mount time (ms)': roundFloat(item.exclusive),\n        'Exclusive render time (ms)': roundFloat(item.render),\n        'Mount time per instance (ms)': roundFloat(item.exclusive / item.count),\n        'Render time per instance (ms)': roundFloat(item.render / item.count),\n        'Instances': item.count\n      };\n    }));\n    // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct\n    // number.\n  },\n\n  printInclusive: function (measurements) {\n    measurements = measurements || ReactDefaultPerf._allMeasurements;\n    var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements);\n    console.table(summary.map(function (item) {\n      return {\n        'Owner > component': item.componentName,\n        'Inclusive time (ms)': roundFloat(item.time),\n        'Instances': item.count\n      };\n    }));\n    console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms');\n  },\n\n  getMeasurementsSummaryMap: function (measurements) {\n    var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements, true);\n    return summary.map(function (item) {\n      return {\n        'Owner > component': item.componentName,\n        'Wasted time (ms)': item.time,\n        'Instances': item.count\n      };\n    });\n  },\n\n  printWasted: function (measurements) {\n    measurements = measurements || ReactDefaultPerf._allMeasurements;\n    console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements));\n    console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms');\n  },\n\n  printDOM: function (measurements) {\n    measurements = measurements || ReactDefaultPerf._allMeasurements;\n    var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements);\n    console.table(summary.map(function (item) {\n      var result = {};\n      result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id;\n      result.type = item.type;\n      result.args = JSON.stringify(item.args);\n      return result;\n    }));\n    console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms');\n  },\n\n  _recordWrite: function (id, fnName, totalTime, args) {\n    // TODO: totalTime isn't that useful since it doesn't count paints/reflows\n    var writes = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].writes;\n    writes[id] = writes[id] || [];\n    writes[id].push({\n      type: fnName,\n      time: totalTime,\n      args: args\n    });\n  },\n\n  measure: function (moduleName, fnName, func) {\n    return function () {\n      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n        args[_key] = arguments[_key];\n      }\n\n      var totalTime;\n      var rv;\n      var start;\n\n      if (fnName === '_renderNewRootComponent' || fnName === 'flushBatchedUpdates') {\n        // A \"measurement\" is a set of metrics recorded for each flush. We want\n        // to group the metrics for a given flush together so we can look at the\n        // components that rendered and the DOM operations that actually\n        // happened to determine the amount of \"wasted work\" performed.\n        ReactDefaultPerf._allMeasurements.push({\n          exclusive: {},\n          inclusive: {},\n          render: {},\n          counts: {},\n          writes: {},\n          displayNames: {},\n          totalTime: 0,\n          created: {}\n        });\n        start = performanceNow();\n        rv = func.apply(this, args);\n        ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].totalTime = performanceNow() - start;\n        return rv;\n      } else if (fnName === '_mountImageIntoNode' || moduleName === 'ReactBrowserEventEmitter' || moduleName === 'ReactDOMIDOperations' || moduleName === 'CSSPropertyOperations' || moduleName === 'DOMChildrenOperations' || moduleName === 'DOMPropertyOperations') {\n        start = performanceNow();\n        rv = func.apply(this, args);\n        totalTime = performanceNow() - start;\n\n        if (fnName === '_mountImageIntoNode') {\n          var mountID = ReactMount.getID(args[1]);\n          ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);\n        } else if (fnName === 'dangerouslyProcessChildrenUpdates') {\n          // special format\n          args[0].forEach(function (update) {\n            var writeArgs = {};\n            if (update.fromIndex !== null) {\n              writeArgs.fromIndex = update.fromIndex;\n            }\n            if (update.toIndex !== null) {\n              writeArgs.toIndex = update.toIndex;\n            }\n            if (update.textContent !== null) {\n              writeArgs.textContent = update.textContent;\n            }\n            if (update.markupIndex !== null) {\n              writeArgs.markup = args[1][update.markupIndex];\n            }\n            ReactDefaultPerf._recordWrite(update.parentID, update.type, totalTime, writeArgs);\n          });\n        } else {\n          // basic format\n          var id = args[0];\n          if (typeof id === 'object') {\n            id = ReactMount.getID(args[0]);\n          }\n          ReactDefaultPerf._recordWrite(id, fnName, totalTime, Array.prototype.slice.call(args, 1));\n        }\n        return rv;\n      } else if (moduleName === 'ReactCompositeComponent' && (fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()?\n      fnName === '_renderValidatedComponent')) {\n\n        if (this._currentElement.type === ReactMount.TopLevelWrapper) {\n          return func.apply(this, args);\n        }\n\n        var rootNodeID = fnName === 'mountComponent' ? args[0] : this._rootNodeID;\n        var isRender = fnName === '_renderValidatedComponent';\n        var isMount = fnName === 'mountComponent';\n\n        var mountStack = ReactDefaultPerf._mountStack;\n        var entry = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1];\n\n        if (isRender) {\n          addValue(entry.counts, rootNodeID, 1);\n        } else if (isMount) {\n          entry.created[rootNodeID] = true;\n          mountStack.push(0);\n        }\n\n        start = performanceNow();\n        rv = func.apply(this, args);\n        totalTime = performanceNow() - start;\n\n        if (isRender) {\n          addValue(entry.render, rootNodeID, totalTime);\n        } else if (isMount) {\n          var subMountTime = mountStack.pop();\n          mountStack[mountStack.length - 1] += totalTime;\n          addValue(entry.exclusive, rootNodeID, totalTime - subMountTime);\n          addValue(entry.inclusive, rootNodeID, totalTime);\n        } else {\n          addValue(entry.inclusive, rootNodeID, totalTime);\n        }\n\n        entry.displayNames[rootNodeID] = {\n          current: this.getName(),\n          owner: this._currentElement._owner ? this._currentElement._owner.getName() : '<root>'\n        };\n\n        return rv;\n      } else {\n        return func.apply(this, args);\n      }\n    };\n  }\n};\n\nmodule.exports = ReactDefaultPerf;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDefaultPerf.js\n ** module id = 156\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDefaultPerfAnalysis\n */\n\n'use strict';\n\nvar assign = require('./Object.assign');\n\n// Don't try to save users less than 1.2ms (a number I made up)\nvar DONT_CARE_THRESHOLD = 1.2;\nvar DOM_OPERATION_TYPES = {\n  '_mountImageIntoNode': 'set innerHTML',\n  INSERT_MARKUP: 'set innerHTML',\n  MOVE_EXISTING: 'move',\n  REMOVE_NODE: 'remove',\n  SET_MARKUP: 'set innerHTML',\n  TEXT_CONTENT: 'set textContent',\n  'setValueForProperty': 'update attribute',\n  'setValueForAttribute': 'update attribute',\n  'deleteValueForProperty': 'remove attribute',\n  'dangerouslyReplaceNodeWithMarkupByID': 'replace'\n};\n\nfunction getTotalTime(measurements) {\n  // TODO: return number of DOM ops? could be misleading.\n  // TODO: measure dropped frames after reconcile?\n  // TODO: log total time of each reconcile and the top-level component\n  // class that triggered it.\n  var totalTime = 0;\n  for (var i = 0; i < measurements.length; i++) {\n    var measurement = measurements[i];\n    totalTime += measurement.totalTime;\n  }\n  return totalTime;\n}\n\nfunction getDOMSummary(measurements) {\n  var items = [];\n  measurements.forEach(function (measurement) {\n    Object.keys(measurement.writes).forEach(function (id) {\n      measurement.writes[id].forEach(function (write) {\n        items.push({\n          id: id,\n          type: DOM_OPERATION_TYPES[write.type] || write.type,\n          args: write.args\n        });\n      });\n    });\n  });\n  return items;\n}\n\nfunction getExclusiveSummary(measurements) {\n  var candidates = {};\n  var displayName;\n\n  for (var i = 0; i < measurements.length; i++) {\n    var measurement = measurements[i];\n    var allIDs = assign({}, measurement.exclusive, measurement.inclusive);\n\n    for (var id in allIDs) {\n      displayName = measurement.displayNames[id].current;\n\n      candidates[displayName] = candidates[displayName] || {\n        componentName: displayName,\n        inclusive: 0,\n        exclusive: 0,\n        render: 0,\n        count: 0\n      };\n      if (measurement.render[id]) {\n        candidates[displayName].render += measurement.render[id];\n      }\n      if (measurement.exclusive[id]) {\n        candidates[displayName].exclusive += measurement.exclusive[id];\n      }\n      if (measurement.inclusive[id]) {\n        candidates[displayName].inclusive += measurement.inclusive[id];\n      }\n      if (measurement.counts[id]) {\n        candidates[displayName].count += measurement.counts[id];\n      }\n    }\n  }\n\n  // Now make a sorted array with the results.\n  var arr = [];\n  for (displayName in candidates) {\n    if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {\n      arr.push(candidates[displayName]);\n    }\n  }\n\n  arr.sort(function (a, b) {\n    return b.exclusive - a.exclusive;\n  });\n\n  return arr;\n}\n\nfunction getInclusiveSummary(measurements, onlyClean) {\n  var candidates = {};\n  var inclusiveKey;\n\n  for (var i = 0; i < measurements.length; i++) {\n    var measurement = measurements[i];\n    var allIDs = assign({}, measurement.exclusive, measurement.inclusive);\n    var cleanComponents;\n\n    if (onlyClean) {\n      cleanComponents = getUnchangedComponents(measurement);\n    }\n\n    for (var id in allIDs) {\n      if (onlyClean && !cleanComponents[id]) {\n        continue;\n      }\n\n      var displayName = measurement.displayNames[id];\n\n      // Inclusive time is not useful for many components without knowing where\n      // they are instantiated. So we aggregate inclusive time with both the\n      // owner and current displayName as the key.\n      inclusiveKey = displayName.owner + ' > ' + displayName.current;\n\n      candidates[inclusiveKey] = candidates[inclusiveKey] || {\n        componentName: inclusiveKey,\n        time: 0,\n        count: 0\n      };\n\n      if (measurement.inclusive[id]) {\n        candidates[inclusiveKey].time += measurement.inclusive[id];\n      }\n      if (measurement.counts[id]) {\n        candidates[inclusiveKey].count += measurement.counts[id];\n      }\n    }\n  }\n\n  // Now make a sorted array with the results.\n  var arr = [];\n  for (inclusiveKey in candidates) {\n    if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {\n      arr.push(candidates[inclusiveKey]);\n    }\n  }\n\n  arr.sort(function (a, b) {\n    return b.time - a.time;\n  });\n\n  return arr;\n}\n\nfunction getUnchangedComponents(measurement) {\n  // For a given reconcile, look at which components did not actually\n  // render anything to the DOM and return a mapping of their ID to\n  // the amount of time it took to render the entire subtree.\n  var cleanComponents = {};\n  var dirtyLeafIDs = Object.keys(measurement.writes);\n  var allIDs = assign({}, measurement.exclusive, measurement.inclusive);\n\n  for (var id in allIDs) {\n    var isDirty = false;\n    // For each component that rendered, see if a component that triggered\n    // a DOM op is in its subtree.\n    for (var i = 0; i < dirtyLeafIDs.length; i++) {\n      if (dirtyLeafIDs[i].indexOf(id) === 0) {\n        isDirty = true;\n        break;\n      }\n    }\n    // check if component newly created\n    if (measurement.created[id]) {\n      isDirty = true;\n    }\n    if (!isDirty && measurement.counts[id] > 0) {\n      cleanComponents[id] = true;\n    }\n  }\n  return cleanComponents;\n}\n\nvar ReactDefaultPerfAnalysis = {\n  getExclusiveSummary: getExclusiveSummary,\n  getInclusiveSummary: getInclusiveSummary,\n  getDOMSummary: getDOMSummary,\n  getTotalTime: getTotalTime\n};\n\nmodule.exports = ReactDefaultPerfAnalysis;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDefaultPerfAnalysis.js\n ** module id = 157\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule performanceNow\n * @typechecks\n */\n\n'use strict';\n\nvar performance = require('./performance');\nvar curPerformance = performance;\n\n/**\n * Detect if we can use `window.performance.now()` and gracefully fallback to\n * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now\n * because of Facebook's testing infrastructure.\n */\nif (!curPerformance || !curPerformance.now) {\n  curPerformance = Date;\n}\n\nvar performanceNow = curPerformance.now.bind(curPerformance);\n\nmodule.exports = performanceNow;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/performanceNow.js\n ** module id = 158\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule performance\n * @typechecks\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('./ExecutionEnvironment');\n\nvar performance;\n\nif (ExecutionEnvironment.canUseDOM) {\n  performance = window.performance || window.msPerformance || window.webkitPerformance;\n}\n\nmodule.exports = performance || {};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/performance.js\n ** module id = 159\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactVersion\n */\n\n'use strict';\n\nmodule.exports = '0.14.3';\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactVersion.js\n ** module id = 160\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n* @providesModule renderSubtreeIntoContainer\n*/\n\n'use strict';\n\nvar ReactMount = require('./ReactMount');\n\nmodule.exports = ReactMount.renderSubtreeIntoContainer;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/renderSubtreeIntoContainer.js\n ** module id = 161\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMServer\n */\n\n'use strict';\n\nvar ReactDefaultInjection = require('./ReactDefaultInjection');\nvar ReactServerRendering = require('./ReactServerRendering');\nvar ReactVersion = require('./ReactVersion');\n\nReactDefaultInjection.inject();\n\nvar ReactDOMServer = {\n  renderToString: ReactServerRendering.renderToString,\n  renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup,\n  version: ReactVersion\n};\n\nmodule.exports = ReactDOMServer;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMServer.js\n ** module id = 162\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @typechecks static-only\n * @providesModule ReactServerRendering\n */\n'use strict';\n\nvar ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy');\nvar ReactElement = require('./ReactElement');\nvar ReactInstanceHandles = require('./ReactInstanceHandles');\nvar ReactMarkupChecksum = require('./ReactMarkupChecksum');\nvar ReactServerBatchingStrategy = require('./ReactServerBatchingStrategy');\nvar ReactServerRenderingTransaction = require('./ReactServerRenderingTransaction');\nvar ReactUpdates = require('./ReactUpdates');\n\nvar emptyObject = require('fbjs/lib/emptyObject');\nvar instantiateReactComponent = require('./instantiateReactComponent');\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * @param {ReactElement} element\n * @return {string} the HTML markup\n */\nfunction renderToString(element) {\n  !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'renderToString(): You must pass a valid ReactElement.') : invariant(false) : undefined;\n\n  var transaction;\n  try {\n    ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy);\n\n    var id = ReactInstanceHandles.createReactRootID();\n    transaction = ReactServerRenderingTransaction.getPooled(false);\n\n    return transaction.perform(function () {\n      var componentInstance = instantiateReactComponent(element, null);\n      var markup = componentInstance.mountComponent(id, transaction, emptyObject);\n      return ReactMarkupChecksum.addChecksumToMarkup(markup);\n    }, null);\n  } finally {\n    ReactServerRenderingTransaction.release(transaction);\n    // Revert to the DOM batching strategy since these two renderers\n    // currently share these stateful modules.\n    ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);\n  }\n}\n\n/**\n * @param {ReactElement} element\n * @return {string} the HTML markup, without the extra React ID and checksum\n * (for generating static pages)\n */\nfunction renderToStaticMarkup(element) {\n  !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'renderToStaticMarkup(): You must pass a valid ReactElement.') : invariant(false) : undefined;\n\n  var transaction;\n  try {\n    ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy);\n\n    var id = ReactInstanceHandles.createReactRootID();\n    transaction = ReactServerRenderingTransaction.getPooled(true);\n\n    return transaction.perform(function () {\n      var componentInstance = instantiateReactComponent(element, null);\n      return componentInstance.mountComponent(id, transaction, emptyObject);\n    }, null);\n  } finally {\n    ReactServerRenderingTransaction.release(transaction);\n    // Revert to the DOM batching strategy since these two renderers\n    // currently share these stateful modules.\n    ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);\n  }\n}\n\nmodule.exports = {\n  renderToString: renderToString,\n  renderToStaticMarkup: renderToStaticMarkup\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactServerRendering.js\n ** module id = 163\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactServerBatchingStrategy\n * @typechecks\n */\n\n'use strict';\n\nvar ReactServerBatchingStrategy = {\n  isBatchingUpdates: false,\n  batchedUpdates: function (callback) {\n    // Don't do anything here. During the server rendering we don't want to\n    // schedule any updates. We will simply ignore them.\n  }\n};\n\nmodule.exports = ReactServerBatchingStrategy;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactServerBatchingStrategy.js\n ** module id = 164\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactServerRenderingTransaction\n * @typechecks\n */\n\n'use strict';\n\nvar PooledClass = require('./PooledClass');\nvar CallbackQueue = require('./CallbackQueue');\nvar Transaction = require('./Transaction');\n\nvar assign = require('./Object.assign');\nvar emptyFunction = require('fbjs/lib/emptyFunction');\n\n/**\n * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks\n * during the performing of the transaction.\n */\nvar ON_DOM_READY_QUEUEING = {\n  /**\n   * Initializes the internal `onDOMReady` queue.\n   */\n  initialize: function () {\n    this.reactMountReady.reset();\n  },\n\n  close: emptyFunction\n};\n\n/**\n * Executed within the scope of the `Transaction` instance. Consider these as\n * being member methods, but with an implied ordering while being isolated from\n * each other.\n */\nvar TRANSACTION_WRAPPERS = [ON_DOM_READY_QUEUEING];\n\n/**\n * @class ReactServerRenderingTransaction\n * @param {boolean} renderToStaticMarkup\n */\nfunction ReactServerRenderingTransaction(renderToStaticMarkup) {\n  this.reinitializeTransaction();\n  this.renderToStaticMarkup = renderToStaticMarkup;\n  this.reactMountReady = CallbackQueue.getPooled(null);\n  this.useCreateElement = false;\n}\n\nvar Mixin = {\n  /**\n   * @see Transaction\n   * @abstract\n   * @final\n   * @return {array} Empty list of operation wrap procedures.\n   */\n  getTransactionWrappers: function () {\n    return TRANSACTION_WRAPPERS;\n  },\n\n  /**\n   * @return {object} The queue to collect `onDOMReady` callbacks with.\n   */\n  getReactMountReady: function () {\n    return this.reactMountReady;\n  },\n\n  /**\n   * `PooledClass` looks for this, and will invoke this before allowing this\n   * instance to be reused.\n   */\n  destructor: function () {\n    CallbackQueue.release(this.reactMountReady);\n    this.reactMountReady = null;\n  }\n};\n\nassign(ReactServerRenderingTransaction.prototype, Transaction.Mixin, Mixin);\n\nPooledClass.addPoolingTo(ReactServerRenderingTransaction);\n\nmodule.exports = ReactServerRenderingTransaction;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactServerRenderingTransaction.js\n ** module id = 165\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactIsomorphic\n */\n\n'use strict';\n\nvar ReactChildren = require('./ReactChildren');\nvar ReactComponent = require('./ReactComponent');\nvar ReactClass = require('./ReactClass');\nvar ReactDOMFactories = require('./ReactDOMFactories');\nvar ReactElement = require('./ReactElement');\nvar ReactElementValidator = require('./ReactElementValidator');\nvar ReactPropTypes = require('./ReactPropTypes');\nvar ReactVersion = require('./ReactVersion');\n\nvar assign = require('./Object.assign');\nvar onlyChild = require('./onlyChild');\n\nvar createElement = ReactElement.createElement;\nvar createFactory = ReactElement.createFactory;\nvar cloneElement = ReactElement.cloneElement;\n\nif (process.env.NODE_ENV !== 'production') {\n  createElement = ReactElementValidator.createElement;\n  createFactory = ReactElementValidator.createFactory;\n  cloneElement = ReactElementValidator.cloneElement;\n}\n\nvar React = {\n\n  // Modern\n\n  Children: {\n    map: ReactChildren.map,\n    forEach: ReactChildren.forEach,\n    count: ReactChildren.count,\n    toArray: ReactChildren.toArray,\n    only: onlyChild\n  },\n\n  Component: ReactComponent,\n\n  createElement: createElement,\n  cloneElement: cloneElement,\n  isValidElement: ReactElement.isValidElement,\n\n  // Classic\n\n  PropTypes: ReactPropTypes,\n  createClass: ReactClass.createClass,\n  createFactory: createFactory,\n  createMixin: function (mixin) {\n    // Currently a noop. Will be used to validate and trace mixins.\n    return mixin;\n  },\n\n  // This looks DOM specific but these are actually isomorphic helpers\n  // since they are just generating DOM strings.\n  DOM: ReactDOMFactories,\n\n  version: ReactVersion,\n\n  // Hook for JSX spread, don't use this for anything else.\n  __spread: assign\n};\n\nmodule.exports = React;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactIsomorphic.js\n ** module id = 166\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactDOMFactories\n * @typechecks static-only\n */\n\n'use strict';\n\nvar ReactElement = require('./ReactElement');\nvar ReactElementValidator = require('./ReactElementValidator');\n\nvar mapObject = require('fbjs/lib/mapObject');\n\n/**\n * Create a factory that creates HTML tag elements.\n *\n * @param {string} tag Tag name (e.g. `div`).\n * @private\n */\nfunction createDOMFactory(tag) {\n  if (process.env.NODE_ENV !== 'production') {\n    return ReactElementValidator.createFactory(tag);\n  }\n  return ReactElement.createFactory(tag);\n}\n\n/**\n * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.\n * This is also accessible via `React.DOM`.\n *\n * @public\n */\nvar ReactDOMFactories = mapObject({\n  a: 'a',\n  abbr: 'abbr',\n  address: 'address',\n  area: 'area',\n  article: 'article',\n  aside: 'aside',\n  audio: 'audio',\n  b: 'b',\n  base: 'base',\n  bdi: 'bdi',\n  bdo: 'bdo',\n  big: 'big',\n  blockquote: 'blockquote',\n  body: 'body',\n  br: 'br',\n  button: 'button',\n  canvas: 'canvas',\n  caption: 'caption',\n  cite: 'cite',\n  code: 'code',\n  col: 'col',\n  colgroup: 'colgroup',\n  data: 'data',\n  datalist: 'datalist',\n  dd: 'dd',\n  del: 'del',\n  details: 'details',\n  dfn: 'dfn',\n  dialog: 'dialog',\n  div: 'div',\n  dl: 'dl',\n  dt: 'dt',\n  em: 'em',\n  embed: 'embed',\n  fieldset: 'fieldset',\n  figcaption: 'figcaption',\n  figure: 'figure',\n  footer: 'footer',\n  form: 'form',\n  h1: 'h1',\n  h2: 'h2',\n  h3: 'h3',\n  h4: 'h4',\n  h5: 'h5',\n  h6: 'h6',\n  head: 'head',\n  header: 'header',\n  hgroup: 'hgroup',\n  hr: 'hr',\n  html: 'html',\n  i: 'i',\n  iframe: 'iframe',\n  img: 'img',\n  input: 'input',\n  ins: 'ins',\n  kbd: 'kbd',\n  keygen: 'keygen',\n  label: 'label',\n  legend: 'legend',\n  li: 'li',\n  link: 'link',\n  main: 'main',\n  map: 'map',\n  mark: 'mark',\n  menu: 'menu',\n  menuitem: 'menuitem',\n  meta: 'meta',\n  meter: 'meter',\n  nav: 'nav',\n  noscript: 'noscript',\n  object: 'object',\n  ol: 'ol',\n  optgroup: 'optgroup',\n  option: 'option',\n  output: 'output',\n  p: 'p',\n  param: 'param',\n  picture: 'picture',\n  pre: 'pre',\n  progress: 'progress',\n  q: 'q',\n  rp: 'rp',\n  rt: 'rt',\n  ruby: 'ruby',\n  s: 's',\n  samp: 'samp',\n  script: 'script',\n  section: 'section',\n  select: 'select',\n  small: 'small',\n  source: 'source',\n  span: 'span',\n  strong: 'strong',\n  style: 'style',\n  sub: 'sub',\n  summary: 'summary',\n  sup: 'sup',\n  table: 'table',\n  tbody: 'tbody',\n  td: 'td',\n  textarea: 'textarea',\n  tfoot: 'tfoot',\n  th: 'th',\n  thead: 'thead',\n  time: 'time',\n  title: 'title',\n  tr: 'tr',\n  track: 'track',\n  u: 'u',\n  ul: 'ul',\n  'var': 'var',\n  video: 'video',\n  wbr: 'wbr',\n\n  // SVG\n  circle: 'circle',\n  clipPath: 'clipPath',\n  defs: 'defs',\n  ellipse: 'ellipse',\n  g: 'g',\n  image: 'image',\n  line: 'line',\n  linearGradient: 'linearGradient',\n  mask: 'mask',\n  path: 'path',\n  pattern: 'pattern',\n  polygon: 'polygon',\n  polyline: 'polyline',\n  radialGradient: 'radialGradient',\n  rect: 'rect',\n  stop: 'stop',\n  svg: 'svg',\n  text: 'text',\n  tspan: 'tspan'\n\n}, createDOMFactory);\n\nmodule.exports = ReactDOMFactories;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactDOMFactories.js\n ** module id = 167\n ** module chunks = 0\n **/","/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactElementValidator\n */\n\n/**\n * ReactElementValidator provides a wrapper around a element factory\n * which validates the props passed to the element. This is intended to be\n * used only in DEV and could be replaced by a static type checker for languages\n * that support it.\n */\n\n'use strict';\n\nvar ReactElement = require('./ReactElement');\nvar ReactPropTypeLocations = require('./ReactPropTypeLocations');\nvar ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\n\nvar canDefineProperty = require('./canDefineProperty');\nvar getIteratorFn = require('./getIteratorFn');\nvar invariant = require('fbjs/lib/invariant');\nvar warning = require('fbjs/lib/warning');\n\nfunction getDeclarationErrorAddendum() {\n  if (ReactCurrentOwner.current) {\n    var name = ReactCurrentOwner.current.getName();\n    if (name) {\n      return ' Check the render method of `' + name + '`.';\n    }\n  }\n  return '';\n}\n\n/**\n * Warn if there's no key explicitly set on dynamic arrays of children or\n * object keys are not valid. This allows us to keep track of children between\n * updates.\n */\nvar ownerHasKeyUseWarning = {};\n\nvar loggedTypeFailures = {};\n\n/**\n * Warn if the element doesn't have an explicit key assigned to it.\n * This element is in an array. The array could grow and shrink or be\n * reordered. All children that haven't already been validated are required to\n * have a \"key\" property assigned to it.\n *\n * @internal\n * @param {ReactElement} element Element that requires a key.\n * @param {*} parentType element's parent's type.\n */\nfunction validateExplicitKey(element, parentType) {\n  if (!element._store || element._store.validated || element.key != null) {\n    return;\n  }\n  element._store.validated = true;\n\n  var addenda = getAddendaForKeyUse('uniqueKey', element, parentType);\n  if (addenda === null) {\n    // we already showed the warning\n    return;\n  }\n  process.env.NODE_ENV !== 'production' ? warning(false, 'Each child in an array or iterator should have a unique \"key\" prop.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined;\n}\n\n/**\n * Shared warning and monitoring code for the key warnings.\n *\n * @internal\n * @param {string} messageType A key used for de-duping warnings.\n * @param {ReactElement} element Component that requires a key.\n * @param {*} parentType element's parent's type.\n * @returns {?object} A set of addenda to use in the warning message, or null\n * if the warning has already been shown before (and shouldn't be shown again).\n */\nfunction getAddendaForKeyUse(messageType, element, parentType) {\n  var addendum = getDeclarationErrorAddendum();\n  if (!addendum) {\n    var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;\n    if (parentName) {\n      addendum = ' Check the top-level render call using <' + parentName + '>.';\n    }\n  }\n\n  var memoizer = ownerHasKeyUseWarning[messageType] || (ownerHasKeyUseWarning[messageType] = {});\n  if (memoizer[addendum]) {\n    return null;\n  }\n  memoizer[addendum] = true;\n\n  var addenda = {\n    parentOrOwner: addendum,\n    url: ' See https://fb.me/react-warning-keys for more information.',\n    childOwner: null\n  };\n\n  // Usually the current owner is the offender, but if it accepts children as a\n  // property, it may be the creator of the child that's responsible for\n  // assigning it a key.\n  if (element && element._owner && element._owner !== ReactCurrentOwner.current) {\n    // Give the component that originally created this child.\n    addenda.childOwner = ' It was passed a child from ' + element._owner.getName() + '.';\n  }\n\n  return addenda;\n}\n\n/**\n * Ensure that every element either is passed in a static location, in an\n * array with an explicit keys property defined, or in an object literal\n * with valid key property.\n *\n * @internal\n * @param {ReactNode} node Statically passed child of any type.\n * @param {*} parentType node's parent's type.\n */\nfunction validateChildKeys(node, parentType) {\n  if (typeof node !== 'object') {\n    return;\n  }\n  if (Array.isArray(node)) {\n    for (var i = 0; i < node.length; i++) {\n      var child = node[i];\n      if (ReactElement.isValidElement(child)) {\n        validateExplicitKey(child, parentType);\n      }\n    }\n  } else if (ReactElement.isValidElement(node)) {\n    // This element was passed in a valid location.\n    if (node._store) {\n      node._store.validated = true;\n    }\n  } else if (node) {\n    var iteratorFn = getIteratorFn(node);\n    // Entry iterators provide implicit keys.\n    if (iteratorFn) {\n      if (iteratorFn !== node.entries) {\n        var iterator = iteratorFn.call(node);\n        var step;\n        while (!(step = iterator.next()).done) {\n          if (ReactElement.isValidElement(step.value)) {\n            validateExplicitKey(step.value, parentType);\n          }\n        }\n      }\n    }\n  }\n}\n\n/**\n * Assert that the props are valid\n *\n * @param {string} componentName Name of the component for error messages.\n * @param {object} propTypes Map of prop name to a ReactPropType\n * @param {object} props\n * @param {string} location e.g. \"prop\", \"context\", \"child context\"\n * @private\n */\nfunction checkPropTypes(componentName, propTypes, props, location) {\n  for (var propName in propTypes) {\n    if (propTypes.hasOwnProperty(propName)) {\n      var error;\n      // Prop type validation may throw. In case they do, we don't want to\n      // fail the render phase where it didn't fail before. So we log it.\n      // After these have been cleaned up, we'll let them throw.\n      try {\n        // This is intentionally an invariant that gets caught. It's the same\n        // behavior as without this statement except with a better message.\n        !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : undefined;\n        error = propTypes[propName](props, propName, componentName, location);\n      } catch (ex) {\n        error = ex;\n      }\n      process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], propName, typeof error) : undefined;\n      if (error instanceof Error && !(error.message in loggedTypeFailures)) {\n        // Only monitor this failure once because there tends to be a lot of the\n        // same error.\n        loggedTypeFailures[error.message] = true;\n\n        var addendum = getDeclarationErrorAddendum();\n        process.env.NODE_ENV !== 'production' ? warning(false, 'Failed propType: %s%s', error.message, addendum) : undefined;\n      }\n    }\n  }\n}\n\n/**\n * Given an element, validate that its props follow the propTypes definition,\n * provided by the type.\n *\n * @param {ReactElement} element\n */\nfunction validatePropTypes(element) {\n  var componentClass = element.type;\n  if (typeof componentClass !== 'function') {\n    return;\n  }\n  var name = componentClass.displayName || componentClass.name;\n  if (componentClass.propTypes) {\n    checkPropTypes(name, componentClass.propTypes, element.props, ReactPropTypeLocations.prop);\n  }\n  if (typeof componentClass.getDefaultProps === 'function') {\n    process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : undefined;\n  }\n}\n\nvar ReactElementValidator = {\n\n  createElement: function (type, props, children) {\n    var validType = typeof type === 'string' || typeof type === 'function';\n    // We warn in this case but don't throw. We expect the element creation to\n    // succeed and there will likely be errors in render.\n    process.env.NODE_ENV !== 'production' ? warning(validType, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()) : undefined;\n\n    var element = ReactElement.createElement.apply(this, arguments);\n\n    // The result can be nullish if a mock or a custom function is used.\n    // TODO: Drop this when these are no longer allowed as the type argument.\n    if (element == null) {\n      return element;\n    }\n\n    // Skip key warning if the type isn't valid since our key validation logic\n    // doesn't expect a non-string/function type and can throw confusing errors.\n    // We don't want exception behavior to differ between dev and prod.\n    // (Rendering will throw with a helpful message and as soon as the type is\n    // fixed, the key warnings will appear.)\n    if (validType) {\n      for (var i = 2; i < arguments.length; i++) {\n        validateChildKeys(arguments[i], type);\n      }\n    }\n\n    validatePropTypes(element);\n\n    return element;\n  },\n\n  createFactory: function (type) {\n    var validatedFactory = ReactElementValidator.createElement.bind(null, type);\n    // Legacy hook TODO: Warn if this is accessed\n    validatedFactory.type = type;\n\n    if (process.env.NODE_ENV !== 'production') {\n      if (canDefineProperty) {\n        Object.defineProperty(validatedFactory, 'type', {\n          enumerable: false,\n          get: function () {\n            process.env.NODE_ENV !== 'production' ? warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.') : undefined;\n            Object.defineProperty(this, 'type', {\n              value: type\n            });\n            return type;\n          }\n        });\n      }\n    }\n\n    return validatedFactory;\n  },\n\n  cloneElement: function (element, props, children) {\n    var newElement = ReactElement.cloneElement.apply(this, arguments);\n    for (var i = 2; i < arguments.length; i++) {\n      validateChildKeys(arguments[i], newElement.type);\n    }\n    validatePropTypes(newElement);\n    return newElement;\n  }\n\n};\n\nmodule.exports = ReactElementValidator;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactElementValidator.js\n ** module id = 168\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule mapObject\n */\n\n'use strict';\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n/**\n * Executes the provided `callback` once for each enumerable own property in the\n * object and constructs a new object from the results. The `callback` is\n * invoked with three arguments:\n *\n *  - the property value\n *  - the property name\n *  - the object being traversed\n *\n * Properties that are added after the call to `mapObject` will not be visited\n * by `callback`. If the values of existing properties are changed, the value\n * passed to `callback` will be the value at the time `mapObject` visits them.\n * Properties that are deleted before being visited are not visited.\n *\n * @grep function objectMap()\n * @grep function objMap()\n *\n * @param {?object} object\n * @param {function} callback\n * @param {*} context\n * @return {?object}\n */\nfunction mapObject(object, callback, context) {\n  if (!object) {\n    return null;\n  }\n  var result = {};\n  for (var name in object) {\n    if (hasOwnProperty.call(object, name)) {\n      result[name] = callback.call(context, object[name], name, object);\n    }\n  }\n  return result;\n}\n\nmodule.exports = mapObject;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/~/fbjs/lib/mapObject.js\n ** module id = 169\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule onlyChild\n */\n'use strict';\n\nvar ReactElement = require('./ReactElement');\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Returns the first child in a collection of children and verifies that there\n * is only one child in the collection. The current implementation of this\n * function assumes that a single child gets passed without a wrapper, but the\n * purpose of this helper function is to abstract away the particular structure\n * of children.\n *\n * @param {?object} children Child collection structure.\n * @return {ReactComponent} The first and only `ReactComponent` contained in the\n * structure.\n */\nfunction onlyChild(children) {\n  !ReactElement.isValidElement(children) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'onlyChild must be passed a children with exactly one child.') : invariant(false) : undefined;\n  return children;\n}\n\nmodule.exports = onlyChild;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/onlyChild.js\n ** module id = 170\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule deprecated\n */\n\n'use strict';\n\nvar assign = require('./Object.assign');\nvar warning = require('fbjs/lib/warning');\n\n/**\n * This will log a single deprecation notice per function and forward the call\n * on to the new API.\n *\n * @param {string} fnName The name of the function\n * @param {string} newModule The module that fn will exist in\n * @param {string} newPackage The module that fn will exist in\n * @param {*} ctx The context this forwarded call should run in\n * @param {function} fn The function to forward on to\n * @return {function} The function that will warn once and then call fn\n */\nfunction deprecated(fnName, newModule, newPackage, ctx, fn) {\n  var warned = false;\n  if (process.env.NODE_ENV !== 'production') {\n    var newFn = function () {\n      process.env.NODE_ENV !== 'production' ? warning(warned,\n      // Require examples in this string must be split to prevent React's\n      // build tools from mistaking them for real requires.\n      // Otherwise the build tools will attempt to build a '%s' module.\n      'React.%s is deprecated. Please use %s.%s from require' + '(\\'%s\\') ' + 'instead.', fnName, newModule, fnName, newPackage) : undefined;\n      warned = true;\n      return fn.apply(ctx, arguments);\n    };\n    // We need to make sure all properties of the original fn are copied over.\n    // In particular, this is needed to support PropTypes\n    return assign(newFn, fn);\n  }\n\n  return fn;\n}\n\nmodule.exports = deprecated;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/deprecated.js\n ** module id = 171\n ** module chunks = 0\n **/","/*!\n * https://github.com/es-shims/es5-shim\n * @license es5-shim Copyright 2009-2015 by contributors, MIT License\n * see https://github.com/es-shims/es5-shim/blob/master/LICENSE\n */\n\n// vim: ts=4 sts=4 sw=4 expandtab\n\n// Add semicolon to prevent IIFE from being passed as argument to concatenated code.\n;\n\n// UMD (Universal Module Definition)\n// see https://github.com/umdjs/umd/blob/master/returnExports.js\n(function (root, factory) {\n    'use strict';\n\n    /* global define, exports, module */\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n    } else if (typeof exports === 'object') {\n        // Node. Does not work with strict CommonJS, but\n        // only CommonJS-like enviroments that support module.exports,\n        // like Node.\n        module.exports = factory();\n    } else {\n        // Browser globals (root is window)\n        root.returnExports = factory();\n    }\n}(this, function () {\n\n/**\n * Brings an environment as close to ECMAScript 5 compliance\n * as is possible with the facilities of erstwhile engines.\n *\n * Annotated ES5: http://es5.github.com/ (specific links below)\n * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf\n * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/\n */\n\n// Shortcut to an often accessed properties, in order to avoid multiple\n// dereference that costs universally. This also holds a reference to known-good\n// functions.\nvar $Array = Array;\nvar ArrayPrototype = $Array.prototype;\nvar $Object = Object;\nvar ObjectPrototype = $Object.prototype;\nvar FunctionPrototype = Function.prototype;\nvar $String = String;\nvar StringPrototype = $String.prototype;\nvar $Number = Number;\nvar NumberPrototype = $Number.prototype;\nvar array_slice = ArrayPrototype.slice;\nvar array_splice = ArrayPrototype.splice;\nvar array_push = ArrayPrototype.push;\nvar array_unshift = ArrayPrototype.unshift;\nvar array_concat = ArrayPrototype.concat;\nvar call = FunctionPrototype.call;\nvar max = Math.max;\nvar min = Math.min;\n\n// Having a toString local variable name breaks in Opera so use to_string.\nvar to_string = ObjectPrototype.toString;\n\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\nvar isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };\nvar isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };\nvar isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };\n\n/* inlined from http://npmjs.com/define-properties */\nvar defineProperties = (function (has) {\n  var supportsDescriptors = $Object.defineProperty && (function () {\n      try {\n          var obj = {};\n          $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });\n          for (var _ in obj) { return false; }\n          return obj.x === obj;\n      } catch (e) { /* this is ES3 */\n          return false;\n      }\n  }());\n\n  // Define configurable, writable and non-enumerable props\n  // if they don't exist.\n  var defineProperty;\n  if (supportsDescriptors) {\n      defineProperty = function (object, name, method, forceAssign) {\n          if (!forceAssign && (name in object)) { return; }\n          $Object.defineProperty(object, name, {\n              configurable: true,\n              enumerable: false,\n              writable: true,\n              value: method\n          });\n      };\n  } else {\n      defineProperty = function (object, name, method, forceAssign) {\n          if (!forceAssign && (name in object)) { return; }\n          object[name] = method;\n      };\n  }\n  return function defineProperties(object, map, forceAssign) {\n      for (var name in map) {\n          if (has.call(map, name)) {\n            defineProperty(object, name, map[name], forceAssign);\n          }\n      }\n  };\n}(ObjectPrototype.hasOwnProperty));\n\n//\n// Util\n// ======\n//\n\n/* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */\nvar isPrimitive = function isPrimitive(input) {\n    var type = typeof input;\n    return input === null || (type !== 'object' && type !== 'function');\n};\n\nvar isActualNaN = $Number.isNaN || function (x) { return x !== x; };\n\nvar ES = {\n    // ES5 9.4\n    // http://es5.github.com/#x9.4\n    // http://jsperf.com/to-integer\n    /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */\n    ToInteger: function ToInteger(num) {\n        var n = +num;\n        if (isActualNaN(n)) {\n            n = 0;\n        } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {\n            n = (n > 0 || -1) * Math.floor(Math.abs(n));\n        }\n        return n;\n    },\n\n    /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */\n    ToPrimitive: function ToPrimitive(input) {\n        var val, valueOf, toStr;\n        if (isPrimitive(input)) {\n            return input;\n        }\n        valueOf = input.valueOf;\n        if (isCallable(valueOf)) {\n            val = valueOf.call(input);\n            if (isPrimitive(val)) {\n                return val;\n            }\n        }\n        toStr = input.toString;\n        if (isCallable(toStr)) {\n            val = toStr.call(input);\n            if (isPrimitive(val)) {\n                return val;\n            }\n        }\n        throw new TypeError();\n    },\n\n    // ES5 9.9\n    // http://es5.github.com/#x9.9\n    /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */\n    ToObject: function (o) {\n        /* jshint eqnull: true */\n        if (o == null) { // this matches both null and undefined\n            throw new TypeError(\"can't convert \" + o + ' to object');\n        }\n        return $Object(o);\n    },\n\n    /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */\n    ToUint32: function ToUint32(x) {\n        return x >>> 0;\n    }\n};\n\n//\n// Function\n// ========\n//\n\n// ES-5 15.3.4.5\n// http://es5.github.com/#x15.3.4.5\n\nvar Empty = function Empty() {};\n\ndefineProperties(FunctionPrototype, {\n    bind: function bind(that) { // .length is 1\n        // 1. Let Target be the this value.\n        var target = this;\n        // 2. If IsCallable(Target) is false, throw a TypeError exception.\n        if (!isCallable(target)) {\n            throw new TypeError('Function.prototype.bind called on incompatible ' + target);\n        }\n        // 3. Let A be a new (possibly empty) internal list of all of the\n        //   argument values provided after thisArg (arg1, arg2 etc), in order.\n        // XXX slicedArgs will stand in for \"A\" if used\n        var args = array_slice.call(arguments, 1); // for normal call\n        // 4. Let F be a new native ECMAScript object.\n        // 11. Set the [[Prototype]] internal property of F to the standard\n        //   built-in Function prototype object as specified in 15.3.3.1.\n        // 12. Set the [[Call]] internal property of F as described in\n        //   15.3.4.5.1.\n        // 13. Set the [[Construct]] internal property of F as described in\n        //   15.3.4.5.2.\n        // 14. Set the [[HasInstance]] internal property of F as described in\n        //   15.3.4.5.3.\n        var bound;\n        var binder = function () {\n\n            if (this instanceof bound) {\n                // 15.3.4.5.2 [[Construct]]\n                // When the [[Construct]] internal method of a function object,\n                // F that was created using the bind function is called with a\n                // list of arguments ExtraArgs, the following steps are taken:\n                // 1. Let target be the value of F's [[TargetFunction]]\n                //   internal property.\n                // 2. If target has no [[Construct]] internal method, a\n                //   TypeError exception is thrown.\n                // 3. Let boundArgs be the value of F's [[BoundArgs]] internal\n                //   property.\n                // 4. Let args be a new list containing the same values as the\n                //   list boundArgs in the same order followed by the same\n                //   values as the list ExtraArgs in the same order.\n                // 5. Return the result of calling the [[Construct]] internal\n                //   method of target providing args as the arguments.\n\n                var result = target.apply(\n                    this,\n                    array_concat.call(args, array_slice.call(arguments))\n                );\n                if ($Object(result) === result) {\n                    return result;\n                }\n                return this;\n\n            } else {\n                // 15.3.4.5.1 [[Call]]\n                // When the [[Call]] internal method of a function object, F,\n                // which was created using the bind function is called with a\n                // this value and a list of arguments ExtraArgs, the following\n                // steps are taken:\n                // 1. Let boundArgs be the value of F's [[BoundArgs]] internal\n                //   property.\n                // 2. Let boundThis be the value of F's [[BoundThis]] internal\n                //   property.\n                // 3. Let target be the value of F's [[TargetFunction]] internal\n                //   property.\n                // 4. Let args be a new list containing the same values as the\n                //   list boundArgs in the same order followed by the same\n                //   values as the list ExtraArgs in the same order.\n                // 5. Return the result of calling the [[Call]] internal method\n                //   of target providing boundThis as the this value and\n                //   providing args as the arguments.\n\n                // equiv: target.call(this, ...boundArgs, ...args)\n                return target.apply(\n                    that,\n                    array_concat.call(args, array_slice.call(arguments))\n                );\n\n            }\n\n        };\n\n        // 15. If the [[Class]] internal property of Target is \"Function\", then\n        //     a. Let L be the length property of Target minus the length of A.\n        //     b. Set the length own property of F to either 0 or L, whichever is\n        //       larger.\n        // 16. Else set the length own property of F to 0.\n\n        var boundLength = max(0, target.length - args.length);\n\n        // 17. Set the attributes of the length own property of F to the values\n        //   specified in 15.3.5.1.\n        var boundArgs = [];\n        for (var i = 0; i < boundLength; i++) {\n            array_push.call(boundArgs, '$' + i);\n        }\n\n        // XXX Build a dynamic function with desired amount of arguments is the only\n        // way to set the length property of a function.\n        // In environments where Content Security Policies enabled (Chrome extensions,\n        // for ex.) all use of eval or Function costructor throws an exception.\n        // However in all of these environments Function.prototype.bind exists\n        // and so this code will never be executed.\n        bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);\n\n        if (target.prototype) {\n            Empty.prototype = target.prototype;\n            bound.prototype = new Empty();\n            // Clean up dangling references.\n            Empty.prototype = null;\n        }\n\n        // TODO\n        // 18. Set the [[Extensible]] internal property of F to true.\n\n        // TODO\n        // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).\n        // 20. Call the [[DefineOwnProperty]] internal method of F with\n        //   arguments \"caller\", PropertyDescriptor {[[Get]]: thrower, [[Set]]:\n        //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and\n        //   false.\n        // 21. Call the [[DefineOwnProperty]] internal method of F with\n        //   arguments \"arguments\", PropertyDescriptor {[[Get]]: thrower,\n        //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},\n        //   and false.\n\n        // TODO\n        // NOTE Function objects created using Function.prototype.bind do not\n        // have a prototype property or the [[Code]], [[FormalParameters]], and\n        // [[Scope]] internal properties.\n        // XXX can't delete prototype in pure-js.\n\n        // 22. Return F.\n        return bound;\n    }\n});\n\n// _Please note: Shortcuts are defined after `Function.prototype.bind` as we\n// us it in defining shortcuts.\nvar owns = call.bind(ObjectPrototype.hasOwnProperty);\nvar toStr = call.bind(ObjectPrototype.toString);\nvar strSlice = call.bind(StringPrototype.slice);\nvar strSplit = call.bind(StringPrototype.split);\nvar strIndexOf = call.bind(StringPrototype.indexOf);\nvar push = call.bind(array_push);\n\n//\n// Array\n// =====\n//\n\nvar isArray = $Array.isArray || function isArray(obj) {\n    return toStr(obj) === '[object Array]';\n};\n\n// ES5 15.4.4.12\n// http://es5.github.com/#x15.4.4.13\n// Return len+argCount.\n// [bugfix, ielt8]\n// IE < 8 bug: [].unshift(0) === undefined but should be \"1\"\nvar hasUnshiftReturnValueBug = [].unshift(0) !== 1;\ndefineProperties(ArrayPrototype, {\n    unshift: function () {\n        array_unshift.apply(this, arguments);\n        return this.length;\n    }\n}, hasUnshiftReturnValueBug);\n\n// ES5 15.4.3.2\n// http://es5.github.com/#x15.4.3.2\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray\ndefineProperties($Array, { isArray: isArray });\n\n// The IsCallable() check in the Array functions\n// has been replaced with a strict check on the\n// internal class of the object to trap cases where\n// the provided function was actually a regular\n// expression literal, which in V8 and\n// JavaScriptCore is a typeof \"function\".  Only in\n// V8 are regular expression literals permitted as\n// reduce parameters, so it is desirable in the\n// general case for the shim to match the more\n// strict and common behavior of rejecting regular\n// expressions.\n\n// ES5 15.4.4.18\n// http://es5.github.com/#x15.4.4.18\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach\n\n// Check failure of by-index access of string characters (IE < 9)\n// and failure of `0 in boxedString` (Rhino)\nvar boxedString = $Object('a');\nvar splitString = boxedString[0] !== 'a' || !(0 in boxedString);\n\nvar properlyBoxesContext = function properlyBoxed(method) {\n    // Check node 0.6.21 bug where third parameter is not boxed\n    var properlyBoxesNonStrict = true;\n    var properlyBoxesStrict = true;\n    if (method) {\n        method.call('foo', function (_, __, context) {\n            if (typeof context !== 'object') { properlyBoxesNonStrict = false; }\n        });\n\n        method.call([1], function () {\n            'use strict';\n\n            properlyBoxesStrict = typeof this === 'string';\n        }, 'x');\n    }\n    return !!method && properlyBoxesNonStrict && properlyBoxesStrict;\n};\n\ndefineProperties(ArrayPrototype, {\n    forEach: function forEach(callbackfn/*, thisArg*/) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var i = -1;\n        var length = ES.ToUint32(self.length);\n        var T;\n        if (arguments.length > 1) {\n          T = arguments[1];\n        }\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.forEach callback must be a function');\n        }\n\n        while (++i < length) {\n            if (i in self) {\n                // Invoke the callback function with call, passing arguments:\n                // context, property value, property key, thisArg object\n                if (typeof T === 'undefined') {\n                    callbackfn(self[i], i, object);\n                } else {\n                    callbackfn.call(T, self[i], i, object);\n                }\n            }\n        }\n    }\n}, !properlyBoxesContext(ArrayPrototype.forEach));\n\n// ES5 15.4.4.19\n// http://es5.github.com/#x15.4.4.19\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map\ndefineProperties(ArrayPrototype, {\n    map: function map(callbackfn/*, thisArg*/) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var length = ES.ToUint32(self.length);\n        var result = $Array(length);\n        var T;\n        if (arguments.length > 1) {\n            T = arguments[1];\n        }\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.map callback must be a function');\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self) {\n                if (typeof T === 'undefined') {\n                    result[i] = callbackfn(self[i], i, object);\n                } else {\n                    result[i] = callbackfn.call(T, self[i], i, object);\n                }\n            }\n        }\n        return result;\n    }\n}, !properlyBoxesContext(ArrayPrototype.map));\n\n// ES5 15.4.4.20\n// http://es5.github.com/#x15.4.4.20\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter\ndefineProperties(ArrayPrototype, {\n    filter: function filter(callbackfn/*, thisArg*/) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var length = ES.ToUint32(self.length);\n        var result = [];\n        var value;\n        var T;\n        if (arguments.length > 1) {\n            T = arguments[1];\n        }\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.filter callback must be a function');\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self) {\n                value = self[i];\n                if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {\n                    push(result, value);\n                }\n            }\n        }\n        return result;\n    }\n}, !properlyBoxesContext(ArrayPrototype.filter));\n\n// ES5 15.4.4.16\n// http://es5.github.com/#x15.4.4.16\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every\ndefineProperties(ArrayPrototype, {\n    every: function every(callbackfn/*, thisArg*/) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var length = ES.ToUint32(self.length);\n        var T;\n        if (arguments.length > 1) {\n            T = arguments[1];\n        }\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.every callback must be a function');\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {\n                return false;\n            }\n        }\n        return true;\n    }\n}, !properlyBoxesContext(ArrayPrototype.every));\n\n// ES5 15.4.4.17\n// http://es5.github.com/#x15.4.4.17\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some\ndefineProperties(ArrayPrototype, {\n    some: function some(callbackfn/*, thisArg */) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var length = ES.ToUint32(self.length);\n        var T;\n        if (arguments.length > 1) {\n            T = arguments[1];\n        }\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.some callback must be a function');\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {\n                return true;\n            }\n        }\n        return false;\n    }\n}, !properlyBoxesContext(ArrayPrototype.some));\n\n// ES5 15.4.4.21\n// http://es5.github.com/#x15.4.4.21\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce\nvar reduceCoercesToObject = false;\nif (ArrayPrototype.reduce) {\n    reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';\n}\ndefineProperties(ArrayPrototype, {\n    reduce: function reduce(callbackfn/*, initialValue*/) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var length = ES.ToUint32(self.length);\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.reduce callback must be a function');\n        }\n\n        // no value to return if no initial value and an empty array\n        if (length === 0 && arguments.length === 1) {\n            throw new TypeError('reduce of empty array with no initial value');\n        }\n\n        var i = 0;\n        var result;\n        if (arguments.length >= 2) {\n            result = arguments[1];\n        } else {\n            do {\n                if (i in self) {\n                    result = self[i++];\n                    break;\n                }\n\n                // if array contains no values, no initial value to return\n                if (++i >= length) {\n                    throw new TypeError('reduce of empty array with no initial value');\n                }\n            } while (true);\n        }\n\n        for (; i < length; i++) {\n            if (i in self) {\n                result = callbackfn(result, self[i], i, object);\n            }\n        }\n\n        return result;\n    }\n}, !reduceCoercesToObject);\n\n// ES5 15.4.4.22\n// http://es5.github.com/#x15.4.4.22\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight\nvar reduceRightCoercesToObject = false;\nif (ArrayPrototype.reduceRight) {\n    reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';\n}\ndefineProperties(ArrayPrototype, {\n    reduceRight: function reduceRight(callbackfn/*, initial*/) {\n        var object = ES.ToObject(this);\n        var self = splitString && isString(this) ? strSplit(this, '') : object;\n        var length = ES.ToUint32(self.length);\n\n        // If no callback function or if callback is not a callable function\n        if (!isCallable(callbackfn)) {\n            throw new TypeError('Array.prototype.reduceRight callback must be a function');\n        }\n\n        // no value to return if no initial value, empty array\n        if (length === 0 && arguments.length === 1) {\n            throw new TypeError('reduceRight of empty array with no initial value');\n        }\n\n        var result;\n        var i = length - 1;\n        if (arguments.length >= 2) {\n            result = arguments[1];\n        } else {\n            do {\n                if (i in self) {\n                    result = self[i--];\n                    break;\n                }\n\n                // if array contains no values, no initial value to return\n                if (--i < 0) {\n                    throw new TypeError('reduceRight of empty array with no initial value');\n                }\n            } while (true);\n        }\n\n        if (i < 0) {\n            return result;\n        }\n\n        do {\n            if (i in self) {\n                result = callbackfn(result, self[i], i, object);\n            }\n        } while (i--);\n\n        return result;\n    }\n}, !reduceRightCoercesToObject);\n\n// ES5 15.4.4.14\n// http://es5.github.com/#x15.4.4.14\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf\nvar hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;\ndefineProperties(ArrayPrototype, {\n    indexOf: function indexOf(searchElement/*, fromIndex */) {\n        var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);\n        var length = ES.ToUint32(self.length);\n\n        if (length === 0) {\n            return -1;\n        }\n\n        var i = 0;\n        if (arguments.length > 1) {\n            i = ES.ToInteger(arguments[1]);\n        }\n\n        // handle negative indices\n        i = i >= 0 ? i : max(0, length + i);\n        for (; i < length; i++) {\n            if (i in self && self[i] === searchElement) {\n                return i;\n            }\n        }\n        return -1;\n    }\n}, hasFirefox2IndexOfBug);\n\n// ES5 15.4.4.15\n// http://es5.github.com/#x15.4.4.15\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf\nvar hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;\ndefineProperties(ArrayPrototype, {\n    lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {\n        var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);\n        var length = ES.ToUint32(self.length);\n\n        if (length === 0) {\n            return -1;\n        }\n        var i = length - 1;\n        if (arguments.length > 1) {\n            i = min(i, ES.ToInteger(arguments[1]));\n        }\n        // handle negative indices\n        i = i >= 0 ? i : length - Math.abs(i);\n        for (; i >= 0; i--) {\n            if (i in self && searchElement === self[i]) {\n                return i;\n            }\n        }\n        return -1;\n    }\n}, hasFirefox2LastIndexOfBug);\n\n// ES5 15.4.4.12\n// http://es5.github.com/#x15.4.4.12\nvar spliceNoopReturnsEmptyArray = (function () {\n    var a = [1, 2];\n    var result = a.splice();\n    return a.length === 2 && isArray(result) && result.length === 0;\n}());\ndefineProperties(ArrayPrototype, {\n    // Safari 5.0 bug where .splice() returns undefined\n    splice: function splice(start, deleteCount) {\n        if (arguments.length === 0) {\n            return [];\n        } else {\n            return array_splice.apply(this, arguments);\n        }\n    }\n}, !spliceNoopReturnsEmptyArray);\n\nvar spliceWorksWithEmptyObject = (function () {\n    var obj = {};\n    ArrayPrototype.splice.call(obj, 0, 0, 1);\n    return obj.length === 1;\n}());\ndefineProperties(ArrayPrototype, {\n    splice: function splice(start, deleteCount) {\n        if (arguments.length === 0) { return []; }\n        var args = arguments;\n        this.length = max(ES.ToInteger(this.length), 0);\n        if (arguments.length > 0 && typeof deleteCount !== 'number') {\n            args = array_slice.call(arguments);\n            if (args.length < 2) {\n                push(args, this.length - start);\n            } else {\n                args[1] = ES.ToInteger(deleteCount);\n            }\n        }\n        return array_splice.apply(this, args);\n    }\n}, !spliceWorksWithEmptyObject);\nvar spliceWorksWithLargeSparseArrays = (function () {\n    // Per https://github.com/es-shims/es5-shim/issues/295\n    // Safari 7/8 breaks with sparse arrays of size 1e5 or greater\n    var arr = new $Array(1e5);\n    // note: the index MUST be 8 or larger or the test will false pass\n    arr[8] = 'x';\n    arr.splice(1, 1);\n    // note: this test must be defined *after* the indexOf shim\n    // per https://github.com/es-shims/es5-shim/issues/313\n    return arr.indexOf('x') === 7;\n}());\nvar spliceWorksWithSmallSparseArrays = (function () {\n    // Per https://github.com/es-shims/es5-shim/issues/295\n    // Opera 12.15 breaks on this, no idea why.\n    var n = 256;\n    var arr = [];\n    arr[n] = 'a';\n    arr.splice(n + 1, 0, 'b');\n    return arr[n] === 'a';\n}());\ndefineProperties(ArrayPrototype, {\n    splice: function splice(start, deleteCount) {\n        var O = ES.ToObject(this);\n        var A = [];\n        var len = ES.ToUint32(O.length);\n        var relativeStart = ES.ToInteger(start);\n        var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);\n        var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);\n\n        var k = 0;\n        var from;\n        while (k < actualDeleteCount) {\n            from = $String(actualStart + k);\n            if (owns(O, from)) {\n                A[k] = O[from];\n            }\n            k += 1;\n        }\n\n        var items = array_slice.call(arguments, 2);\n        var itemCount = items.length;\n        var to;\n        if (itemCount < actualDeleteCount) {\n            k = actualStart;\n            while (k < (len - actualDeleteCount)) {\n                from = $String(k + actualDeleteCount);\n                to = $String(k + itemCount);\n                if (owns(O, from)) {\n                    O[to] = O[from];\n                } else {\n                    delete O[to];\n                }\n                k += 1;\n            }\n            k = len;\n            while (k > (len - actualDeleteCount + itemCount)) {\n                delete O[k - 1];\n                k -= 1;\n            }\n        } else if (itemCount > actualDeleteCount) {\n            k = len - actualDeleteCount;\n            while (k > actualStart) {\n                from = $String(k + actualDeleteCount - 1);\n                to = $String(k + itemCount - 1);\n                if (owns(O, from)) {\n                    O[to] = O[from];\n                } else {\n                    delete O[to];\n                }\n                k -= 1;\n            }\n        }\n        k = actualStart;\n        for (var i = 0; i < items.length; ++i) {\n            O[k] = items[i];\n            k += 1;\n        }\n        O.length = len - actualDeleteCount + itemCount;\n\n        return A;\n    }\n}, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);\n\nvar hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';\nvar originalJoin = ArrayPrototype.join;\ndefineProperties(ArrayPrototype, {\n    join: function join(separator) {\n        return originalJoin.call(this, typeof separator === 'undefined' ? ',' : separator);\n    }\n}, hasJoinUndefinedBug);\n\nvar pushShim = function push(item) {\n    var O = ES.ToObject(this);\n    var n = ES.ToUint32(O.length);\n    var i = 0;\n    while (i < arguments.length) {\n        O[n + i] = arguments[i];\n        i += 1;\n    }\n    O.length = n + i;\n    return n + i;\n};\n\nvar pushIsNotGeneric = (function () {\n    var obj = {};\n    var result = Array.prototype.push.call(obj, undefined);\n    return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);\n}());\ndefineProperties(ArrayPrototype, {\n    push: function push(item) {\n        if (isArray(this)) {\n            return array_push.apply(this, arguments);\n        }\n        return pushShim.apply(this, arguments);\n    }\n}, pushIsNotGeneric);\n\n// This fixes a very weird bug in Opera 10.6 when pushing `undefined\nvar pushUndefinedIsWeird = (function () {\n    var arr = [];\n    var result = arr.push(undefined);\n    return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);\n}());\ndefineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);\n\n//\n// Object\n// ======\n//\n\n// ES5 15.2.3.14\n// http://es5.github.com/#x15.2.3.14\n\n// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation\nvar hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');\nvar hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');\nvar hasStringEnumBug = !owns('x', '0');\nvar equalsConstructorPrototype = function (o) {\n    var ctor = o.constructor;\n    return ctor && ctor.prototype === o;\n};\nvar blacklistedKeys = {\n    $window: true,\n    $console: true,\n    $parent: true,\n    $self: true,\n    $frame: true,\n    $frames: true,\n    $frameElement: true,\n    $webkitIndexedDB: true,\n    $webkitStorageInfo: true\n};\nvar hasAutomationEqualityBug = (function () {\n    /* globals window */\n    if (typeof window === 'undefined') { return false; }\n    for (var k in window) {\n        try {\n            if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {\n                equalsConstructorPrototype(window[k]);\n            }\n        } catch (e) {\n            return true;\n        }\n    }\n    return false;\n}());\nvar equalsConstructorPrototypeIfNotBuggy = function (object) {\n    if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); }\n    try {\n        return equalsConstructorPrototype(object);\n    } catch (e) {\n        return false;\n    }\n};\nvar dontEnums = [\n    'toString',\n    'toLocaleString',\n    'valueOf',\n    'hasOwnProperty',\n    'isPrototypeOf',\n    'propertyIsEnumerable',\n    'constructor'\n];\nvar dontEnumsLength = dontEnums.length;\n\n// taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js\n// can be replaced with require('is-arguments') if we ever use a build process instead\nvar isStandardArguments = function isArguments(value) {\n    return toStr(value) === '[object Arguments]';\n};\nvar isLegacyArguments = function isArguments(value) {\n    return value !== null &&\n        typeof value === 'object' &&\n        typeof value.length === 'number' &&\n        value.length >= 0 &&\n        !isArray(value) &&\n        isCallable(value.callee);\n};\nvar isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;\n\ndefineProperties($Object, {\n    keys: function keys(object) {\n        var isFn = isCallable(object);\n        var isArgs = isArguments(object);\n        var isObject = object !== null && typeof object === 'object';\n        var isStr = isObject && isString(object);\n\n        if (!isObject && !isFn && !isArgs) {\n            throw new TypeError('Object.keys called on a non-object');\n        }\n\n        var theKeys = [];\n        var skipProto = hasProtoEnumBug && isFn;\n        if ((isStr && hasStringEnumBug) || isArgs) {\n            for (var i = 0; i < object.length; ++i) {\n                push(theKeys, $String(i));\n            }\n        }\n\n        if (!isArgs) {\n            for (var name in object) {\n                if (!(skipProto && name === 'prototype') && owns(object, name)) {\n                    push(theKeys, $String(name));\n                }\n            }\n        }\n\n        if (hasDontEnumBug) {\n            var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n            for (var j = 0; j < dontEnumsLength; j++) {\n                var dontEnum = dontEnums[j];\n                if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {\n                    push(theKeys, dontEnum);\n                }\n            }\n        }\n        return theKeys;\n    }\n});\n\nvar keysWorksWithArguments = $Object.keys && (function () {\n    // Safari 5.0 bug\n    return $Object.keys(arguments).length === 2;\n}(1, 2));\nvar keysHasArgumentsLengthBug = $Object.keys && (function () {\n    var argKeys = $Object.keys(arguments);\n    return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;\n}(1));\nvar originalKeys = $Object.keys;\ndefineProperties($Object, {\n    keys: function keys(object) {\n        if (isArguments(object)) {\n            return originalKeys(array_slice.call(object));\n        } else {\n            return originalKeys(object);\n        }\n    }\n}, !keysWorksWithArguments || keysHasArgumentsLengthBug);\n\n//\n// Date\n// ====\n//\n\n// ES5 15.9.5.43\n// http://es5.github.com/#x15.9.5.43\n// This function returns a String value represent the instance in time\n// represented by this Date object. The format of the String is the Date Time\n// string format defined in 15.9.1.15. All fields are present in the String.\n// The time zone is always UTC, denoted by the suffix Z. If the time value of\n// this object is not a finite Number a RangeError exception is thrown.\nvar negativeDate = -62198755200000;\nvar negativeYearString = '-000001';\nvar hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;\nvar hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';\n\ndefineProperties(Date.prototype, {\n    toISOString: function toISOString() {\n        var result, length, value, year, month;\n        if (!isFinite(this)) {\n            throw new RangeError('Date.prototype.toISOString called on non-finite value.');\n        }\n\n        year = this.getUTCFullYear();\n\n        month = this.getUTCMonth();\n        // see https://github.com/es-shims/es5-shim/issues/111\n        year += Math.floor(month / 12);\n        month = (month % 12 + 12) % 12;\n\n        // the date time string format is specified in 15.9.1.15.\n        result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];\n        year = (\n            (year < 0 ? '-' : (year > 9999 ? '+' : '')) +\n            strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)\n        );\n\n        length = result.length;\n        while (length--) {\n            value = result[length];\n            // pad months, days, hours, minutes, and seconds to have two\n            // digits.\n            if (value < 10) {\n                result[length] = '0' + value;\n            }\n        }\n        // pad milliseconds to have three digits.\n        return (\n            year + '-' + array_slice.call(result, 0, 2).join('-') +\n            'T' + array_slice.call(result, 2).join(':') + '.' +\n            strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z'\n        );\n    }\n}, hasNegativeDateBug || hasSafari51DateBug);\n\n// ES5 15.9.5.44\n// http://es5.github.com/#x15.9.5.44\n// This function provides a String representation of a Date object for use by\n// JSON.stringify (15.12.3).\nvar dateToJSONIsSupported = (function () {\n    try {\n        return Date.prototype.toJSON &&\n            new Date(NaN).toJSON() === null &&\n            new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&\n            Date.prototype.toJSON.call({ // generic\n                toISOString: function () { return true; }\n            });\n    } catch (e) {\n        return false;\n    }\n}());\nif (!dateToJSONIsSupported) {\n    Date.prototype.toJSON = function toJSON(key) {\n        // When the toJSON method is called with argument key, the following\n        // steps are taken:\n\n        // 1.  Let O be the result of calling ToObject, giving it the this\n        // value as its argument.\n        // 2. Let tv be ES.ToPrimitive(O, hint Number).\n        var O = $Object(this);\n        var tv = ES.ToPrimitive(O);\n        // 3. If tv is a Number and is not finite, return null.\n        if (typeof tv === 'number' && !isFinite(tv)) {\n            return null;\n        }\n        // 4. Let toISO be the result of calling the [[Get]] internal method of\n        // O with argument \"toISOString\".\n        var toISO = O.toISOString;\n        // 5. If IsCallable(toISO) is false, throw a TypeError exception.\n        if (!isCallable(toISO)) {\n            throw new TypeError('toISOString property is not callable');\n        }\n        // 6. Return the result of calling the [[Call]] internal method of\n        //  toISO with O as the this value and an empty argument list.\n        return toISO.call(O);\n\n        // NOTE 1 The argument is ignored.\n\n        // NOTE 2 The toJSON function is intentionally generic; it does not\n        // require that its this value be a Date object. Therefore, it can be\n        // transferred to other kinds of objects for use as a method. However,\n        // it does require that any such object have a toISOString method. An\n        // object is free to use the argument key to filter its\n        // stringification.\n    };\n}\n\n// ES5 15.9.4.2\n// http://es5.github.com/#x15.9.4.2\n// based on work shared by Daniel Friesen (dantman)\n// http://gist.github.com/303249\nvar supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;\nvar acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));\nvar doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));\nif (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {\n    // XXX global assignment won't work in embeddings that use\n    // an alternate object for the context.\n    /* global Date: true */\n    /* eslint-disable no-undef */\n    var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;\n    var secondsWithinMaxSafeUnsigned32Bit = Math.floor(maxSafeUnsigned32Bit / 1e3);\n    var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());\n    Date = (function (NativeDate) {\n    /* eslint-enable no-undef */\n        // Date.length === 7\n        var DateShim = function Date(Y, M, D, h, m, s, ms) {\n            var length = arguments.length;\n            var date;\n            if (this instanceof NativeDate) {\n                var seconds = s;\n                var millis = ms;\n                if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {\n                    // work around a Safari 8/9 bug where it treats the seconds as signed\n                    var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;\n                    var sToShift = Math.floor(msToShift / 1e3);\n                    seconds += sToShift;\n                    millis -= sToShift * 1e3;\n                }\n                date = length === 1 && $String(Y) === Y ? // isString(Y)\n                    // We explicitly pass it through parse:\n                    new NativeDate(DateShim.parse(Y)) :\n                    // We have to manually make calls depending on argument\n                    // length here\n                    length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :\n                    length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :\n                    length >= 5 ? new NativeDate(Y, M, D, h, m) :\n                    length >= 4 ? new NativeDate(Y, M, D, h) :\n                    length >= 3 ? new NativeDate(Y, M, D) :\n                    length >= 2 ? new NativeDate(Y, M) :\n                    length >= 1 ? new NativeDate(Y) :\n                                  new NativeDate();\n            } else {\n                date = NativeDate.apply(this, arguments);\n            }\n            if (!isPrimitive(date)) {\n              // Prevent mixups with unfixed Date object\n              defineProperties(date, { constructor: DateShim }, true);\n            }\n            return date;\n        };\n\n        // 15.9.1.15 Date Time String Format.\n        var isoDateExpression = new RegExp('^' +\n            '(\\\\d{4}|[+-]\\\\d{6})' + // four-digit year capture or sign +\n                                      // 6-digit extended year\n            '(?:-(\\\\d{2})' + // optional month capture\n            '(?:-(\\\\d{2})' + // optional day capture\n            '(?:' + // capture hours:minutes:seconds.milliseconds\n                'T(\\\\d{2})' + // hours capture\n                ':(\\\\d{2})' + // minutes capture\n                '(?:' + // optional :seconds.milliseconds\n                    ':(\\\\d{2})' + // seconds capture\n                    '(?:(\\\\.\\\\d{1,}))?' + // milliseconds capture\n                ')?' +\n            '(' + // capture UTC offset component\n                'Z|' + // UTC capture\n                '(?:' + // offset specifier +/-hours:minutes\n                    '([-+])' + // sign capture\n                    '(\\\\d{2})' + // hours offset capture\n                    ':(\\\\d{2})' + // minutes offset capture\n                ')' +\n            ')?)?)?)?' +\n        '$');\n\n        var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];\n\n        var dayFromMonth = function dayFromMonth(year, month) {\n            var t = month > 1 ? 1 : 0;\n            return (\n                months[month] +\n                Math.floor((year - 1969 + t) / 4) -\n                Math.floor((year - 1901 + t) / 100) +\n                Math.floor((year - 1601 + t) / 400) +\n                365 * (year - 1970)\n            );\n        };\n\n        var toUTC = function toUTC(t) {\n            var s = 0;\n            var ms = t;\n            if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {\n                // work around a Safari 8/9 bug where it treats the seconds as signed\n                var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;\n                var sToShift = Math.floor(msToShift / 1e3);\n                s += sToShift;\n                ms -= sToShift * 1e3;\n            }\n            return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));\n        };\n\n        // Copy any custom methods a 3rd party library may have added\n        for (var key in NativeDate) {\n            if (owns(NativeDate, key)) {\n                DateShim[key] = NativeDate[key];\n            }\n        }\n\n        // Copy \"native\" methods explicitly; they may be non-enumerable\n        defineProperties(DateShim, {\n            now: NativeDate.now,\n            UTC: NativeDate.UTC\n        }, true);\n        DateShim.prototype = NativeDate.prototype;\n        defineProperties(DateShim.prototype, {\n            constructor: DateShim\n        }, true);\n\n        // Upgrade Date.parse to handle simplified ISO 8601 strings\n        var parseShim = function parse(string) {\n            var match = isoDateExpression.exec(string);\n            if (match) {\n                // parse months, days, hours, minutes, seconds, and milliseconds\n                // provide default values if necessary\n                // parse the UTC offset component\n                var year = $Number(match[1]),\n                    month = $Number(match[2] || 1) - 1,\n                    day = $Number(match[3] || 1) - 1,\n                    hour = $Number(match[4] || 0),\n                    minute = $Number(match[5] || 0),\n                    second = $Number(match[6] || 0),\n                    millisecond = Math.floor($Number(match[7] || 0) * 1000),\n                    // When time zone is missed, local offset should be used\n                    // (ES 5.1 bug)\n                    // see https://bugs.ecmascript.org/show_bug.cgi?id=112\n                    isLocalTime = Boolean(match[4] && !match[8]),\n                    signOffset = match[9] === '-' ? 1 : -1,\n                    hourOffset = $Number(match[10] || 0),\n                    minuteOffset = $Number(match[11] || 0),\n                    result;\n                var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;\n                if (\n                    hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&\n                    minute < 60 && second < 60 && millisecond < 1000 &&\n                    month > -1 && month < 12 && hourOffset < 24 &&\n                    minuteOffset < 60 && // detect invalid offsets\n                    day > -1 &&\n                    day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))\n                ) {\n                    result = (\n                        (dayFromMonth(year, month) + day) * 24 +\n                        hour +\n                        hourOffset * signOffset\n                    ) * 60;\n                    result = (\n                        (result + minute + minuteOffset * signOffset) * 60 +\n                        second\n                    ) * 1000 + millisecond;\n                    if (isLocalTime) {\n                        result = toUTC(result);\n                    }\n                    if (-8.64e15 <= result && result <= 8.64e15) {\n                        return result;\n                    }\n                }\n                return NaN;\n            }\n            return NativeDate.parse.apply(this, arguments);\n        };\n        defineProperties(DateShim, { parse: parseShim });\n\n        return DateShim;\n    }(Date));\n    /* global Date: false */\n}\n\n// ES5 15.9.4.4\n// http://es5.github.com/#x15.9.4.4\nif (!Date.now) {\n    Date.now = function now() {\n        return new Date().getTime();\n    };\n}\n\n//\n// Number\n// ======\n//\n\n// ES5.1 15.7.4.5\n// http://es5.github.com/#x15.7.4.5\nvar hasToFixedBugs = NumberPrototype.toFixed && (\n  (0.00008).toFixed(3) !== '0.000' ||\n  (0.9).toFixed(0) !== '1' ||\n  (1.255).toFixed(2) !== '1.25' ||\n  (1000000000000000128).toFixed(0) !== '1000000000000000128'\n);\n\nvar toFixedHelpers = {\n  base: 1e7,\n  size: 6,\n  data: [0, 0, 0, 0, 0, 0],\n  multiply: function multiply(n, c) {\n      var i = -1;\n      var c2 = c;\n      while (++i < toFixedHelpers.size) {\n          c2 += n * toFixedHelpers.data[i];\n          toFixedHelpers.data[i] = c2 % toFixedHelpers.base;\n          c2 = Math.floor(c2 / toFixedHelpers.base);\n      }\n  },\n  divide: function divide(n) {\n      var i = toFixedHelpers.size, c = 0;\n      while (--i >= 0) {\n          c += toFixedHelpers.data[i];\n          toFixedHelpers.data[i] = Math.floor(c / n);\n          c = (c % n) * toFixedHelpers.base;\n      }\n  },\n  numToString: function numToString() {\n      var i = toFixedHelpers.size;\n      var s = '';\n      while (--i >= 0) {\n          if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {\n              var t = $String(toFixedHelpers.data[i]);\n              if (s === '') {\n                  s = t;\n              } else {\n                  s += strSlice('0000000', 0, 7 - t.length) + t;\n              }\n          }\n      }\n      return s;\n  },\n  pow: function pow(x, n, acc) {\n      return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));\n  },\n  log: function log(x) {\n      var n = 0;\n      var x2 = x;\n      while (x2 >= 4096) {\n          n += 12;\n          x2 /= 4096;\n      }\n      while (x2 >= 2) {\n          n += 1;\n          x2 /= 2;\n      }\n      return n;\n  }\n};\n\nvar toFixedShim = function toFixed(fractionDigits) {\n    var f, x, s, m, e, z, j, k;\n\n    // Test for NaN and round fractionDigits down\n    f = $Number(fractionDigits);\n    f = isActualNaN(f) ? 0 : Math.floor(f);\n\n    if (f < 0 || f > 20) {\n        throw new RangeError('Number.toFixed called with invalid number of decimals');\n    }\n\n    x = $Number(this);\n\n    if (isActualNaN(x)) {\n        return 'NaN';\n    }\n\n    // If it is too big or small, return the string value of the number\n    if (x <= -1e21 || x >= 1e21) {\n        return $String(x);\n    }\n\n    s = '';\n\n    if (x < 0) {\n        s = '-';\n        x = -x;\n    }\n\n    m = '0';\n\n    if (x > 1e-21) {\n        // 1e-21 < x < 1e21\n        // -70 < log2(x) < 70\n        e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;\n        z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));\n        z *= 0x10000000000000; // Math.pow(2, 52);\n        e = 52 - e;\n\n        // -18 < e < 122\n        // x = z / 2 ^ e\n        if (e > 0) {\n            toFixedHelpers.multiply(0, z);\n            j = f;\n\n            while (j >= 7) {\n                toFixedHelpers.multiply(1e7, 0);\n                j -= 7;\n            }\n\n            toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);\n            j = e - 1;\n\n            while (j >= 23) {\n                toFixedHelpers.divide(1 << 23);\n                j -= 23;\n            }\n\n            toFixedHelpers.divide(1 << j);\n            toFixedHelpers.multiply(1, 1);\n            toFixedHelpers.divide(2);\n            m = toFixedHelpers.numToString();\n        } else {\n            toFixedHelpers.multiply(0, z);\n            toFixedHelpers.multiply(1 << (-e), 0);\n            m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);\n        }\n    }\n\n    if (f > 0) {\n        k = m.length;\n\n        if (k <= f) {\n            m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;\n        } else {\n            m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);\n        }\n    } else {\n        m = s + m;\n    }\n\n    return m;\n};\ndefineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);\n\nvar hasToPrecisionUndefinedBug = (function () {\n    try {\n        return 1.0.toPrecision(undefined) === '1';\n    } catch (e) {\n        return true;\n    }\n}());\nvar originalToPrecision = NumberPrototype.toPrecision;\ndefineProperties(NumberPrototype, {\n    toPrecision: function toPrecision(precision) {\n        return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);\n    }\n}, hasToPrecisionUndefinedBug);\n\n//\n// String\n// ======\n//\n\n// ES5 15.5.4.14\n// http://es5.github.com/#x15.5.4.14\n\n// [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]\n// Many browsers do not split properly with regular expressions or they\n// do not perform the split correctly under obscure conditions.\n// See http://blog.stevenlevithan.com/archives/cross-browser-split\n// I've tested in many browsers and this seems to cover the deviant ones:\n//    'ab'.split(/(?:ab)*/) should be [\"\", \"\"], not [\"\"]\n//    '.'.split(/(.?)(.?)/) should be [\"\", \".\", \"\", \"\"], not [\"\", \"\"]\n//    'tesst'.split(/(s)*/) should be [\"t\", undefined, \"e\", \"s\", \"t\"], not\n//       [undefined, \"t\", undefined, \"e\", ...]\n//    ''.split(/.?/) should be [], not [\"\"]\n//    '.'.split(/()()/) should be [\".\"], not [\"\", \"\", \".\"]\n\nif (\n    'ab'.split(/(?:ab)*/).length !== 2 ||\n    '.'.split(/(.?)(.?)/).length !== 4 ||\n    'tesst'.split(/(s)*/)[1] === 't' ||\n    'test'.split(/(?:)/, -1).length !== 4 ||\n    ''.split(/.?/).length ||\n    '.'.split(/()()/).length > 1\n) {\n    (function () {\n        var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group\n        var maxSafe32BitInt = Math.pow(2, 32) - 1;\n\n        StringPrototype.split = function (separator, limit) {\n            var string = this;\n            if (typeof separator === 'undefined' && limit === 0) {\n                return [];\n            }\n\n            // If `separator` is not a regex, use native split\n            if (!isRegex(separator)) {\n                return strSplit(this, separator, limit);\n            }\n\n            var output = [];\n            var flags = (separator.ignoreCase ? 'i' : '') +\n                        (separator.multiline ? 'm' : '') +\n                        (separator.unicode ? 'u' : '') + // in ES6\n                        (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6\n                lastLastIndex = 0,\n                // Make `global` and avoid `lastIndex` issues by working with a copy\n                separator2, match, lastIndex, lastLength;\n            var separatorCopy = new RegExp(separator.source, flags + 'g');\n            string += ''; // Type-convert\n            if (!compliantExecNpcg) {\n                // Doesn't need flags gy, but they don't hurt\n                separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\\\s)', flags);\n            }\n            /* Values for `limit`, per the spec:\n             * If undefined: 4294967295 // maxSafe32BitInt\n             * If 0, Infinity, or NaN: 0\n             * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;\n             * If negative number: 4294967296 - Math.floor(Math.abs(limit))\n             * If other: Type-convert, then use the above rules\n             */\n            var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);\n            match = separatorCopy.exec(string);\n            while (match) {\n                // `separatorCopy.lastIndex` is not reliable cross-browser\n                lastIndex = match.index + match[0].length;\n                if (lastIndex > lastLastIndex) {\n                    push(output, strSlice(string, lastLastIndex, match.index));\n                    // Fix browsers whose `exec` methods don't consistently return `undefined` for\n                    // nonparticipating capturing groups\n                    if (!compliantExecNpcg && match.length > 1) {\n                        /* eslint-disable no-loop-func */\n                        match[0].replace(separator2, function () {\n                            for (var i = 1; i < arguments.length - 2; i++) {\n                                if (typeof arguments[i] === 'undefined') {\n                                    match[i] = void 0;\n                                }\n                            }\n                        });\n                        /* eslint-enable no-loop-func */\n                    }\n                    if (match.length > 1 && match.index < string.length) {\n                        array_push.apply(output, array_slice.call(match, 1));\n                    }\n                    lastLength = match[0].length;\n                    lastLastIndex = lastIndex;\n                    if (output.length >= splitLimit) {\n                        break;\n                    }\n                }\n                if (separatorCopy.lastIndex === match.index) {\n                    separatorCopy.lastIndex++; // Avoid an infinite loop\n                }\n                match = separatorCopy.exec(string);\n            }\n            if (lastLastIndex === string.length) {\n                if (lastLength || !separatorCopy.test('')) {\n                    push(output, '');\n                }\n            } else {\n                push(output, strSlice(string, lastLastIndex));\n            }\n            return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output;\n        };\n    }());\n\n// [bugfix, chrome]\n// If separator is undefined, then the result array contains just one String,\n// which is the this value (converted to a String). If limit is not undefined,\n// then the output array is truncated so that it contains no more than limit\n// elements.\n// \"0\".split(undefined, 0) -> []\n} else if ('0'.split(void 0, 0).length) {\n    StringPrototype.split = function split(separator, limit) {\n        if (typeof separator === 'undefined' && limit === 0) { return []; }\n        return strSplit(this, separator, limit);\n    };\n}\n\nvar str_replace = StringPrototype.replace;\nvar replaceReportsGroupsCorrectly = (function () {\n    var groups = [];\n    'x'.replace(/x(.)?/g, function (match, group) {\n        push(groups, group);\n    });\n    return groups.length === 1 && typeof groups[0] === 'undefined';\n}());\n\nif (!replaceReportsGroupsCorrectly) {\n    StringPrototype.replace = function replace(searchValue, replaceValue) {\n        var isFn = isCallable(replaceValue);\n        var hasCapturingGroups = isRegex(searchValue) && (/\\)[*?]/).test(searchValue.source);\n        if (!isFn || !hasCapturingGroups) {\n            return str_replace.call(this, searchValue, replaceValue);\n        } else {\n            var wrappedReplaceValue = function (match) {\n                var length = arguments.length;\n                var originalLastIndex = searchValue.lastIndex;\n                searchValue.lastIndex = 0;\n                var args = searchValue.exec(match) || [];\n                searchValue.lastIndex = originalLastIndex;\n                push(args, arguments[length - 2], arguments[length - 1]);\n                return replaceValue.apply(this, args);\n            };\n            return str_replace.call(this, searchValue, wrappedReplaceValue);\n        }\n    };\n}\n\n// ECMA-262, 3rd B.2.3\n// Not an ECMAScript standard, although ECMAScript 3rd Edition has a\n// non-normative section suggesting uniform semantics and it should be\n// normalized across all browsers\n// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE\nvar string_substr = StringPrototype.substr;\nvar hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';\ndefineProperties(StringPrototype, {\n    substr: function substr(start, length) {\n        var normalizedStart = start;\n        if (start < 0) {\n            normalizedStart = max(this.length + start, 0);\n        }\n        return string_substr.call(this, normalizedStart, length);\n    }\n}, hasNegativeSubstrBug);\n\n// ES5 15.5.4.20\n// whitespace from: http://es5.github.io/#x15.5.4.20\nvar ws = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n    '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028' +\n    '\\u2029\\uFEFF';\nvar zeroWidth = '\\u200b';\nvar wsRegexChars = '[' + ws + ']';\nvar trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');\nvar trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');\nvar hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());\ndefineProperties(StringPrototype, {\n    // http://blog.stevenlevithan.com/archives/faster-trim-javascript\n    // http://perfectionkills.com/whitespace-deviations/\n    trim: function trim() {\n        if (typeof this === 'undefined' || this === null) {\n            throw new TypeError(\"can't convert \" + this + ' to object');\n        }\n        return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');\n    }\n}, hasTrimWhitespaceBug);\n\nvar hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;\ndefineProperties(StringPrototype, {\n    lastIndexOf: function lastIndexOf(searchString) {\n        if (typeof this === 'undefined' || this === null) {\n            throw new TypeError(\"can't convert \" + this + ' to object');\n        }\n        var S = $String(this);\n        var searchStr = $String(searchString);\n        var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;\n        var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);\n        var start = min(max(pos, 0), S.length);\n        var searchLen = searchStr.length;\n        var k = start + searchLen;\n        while (k > 0) {\n            k = max(0, k - searchLen);\n            var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);\n            if (index !== -1) {\n                return k + index;\n            }\n        }\n        return -1;\n    }\n}, hasLastIndexBug);\n\nvar originalLastIndexOf = StringPrototype.lastIndexOf;\ndefineProperties(StringPrototype, {\n    lastIndexOf: function lastIndexOf(searchString) {\n        return originalLastIndexOf.apply(this, arguments);\n    }\n}, StringPrototype.lastIndexOf.length !== 1);\n\n// ES-5 15.1.2.2\n/* eslint-disable radix */\nif (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {\n/* eslint-enable radix */\n    /* global parseInt: true */\n    parseInt = (function (origParseInt) {\n        var hexRegex = /^[\\-+]?0[xX]/;\n        return function parseInt(str, radix) {\n            var string = $String(str).trim();\n            var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);\n            return origParseInt(string, defaultedRadix);\n        };\n    }(parseInt));\n}\n\nif (String(new RangeError('test')) !== 'RangeError: test') {\n    var originalErrorToString = Error.prototype.toString;\n    var errorToStringShim = function toString() {\n        if (typeof this === 'undefined' || this === null) {\n            throw new TypeError(\"can't convert \" + this + ' to object');\n        }\n        var name = this.name;\n        if (typeof name === 'undefined') {\n            name = 'Error';\n        } else if (typeof name !== 'string') {\n            name = $String(name);\n        }\n        var msg = this.message;\n        if (typeof msg === 'undefined') {\n            msg = '';\n        } else if (typeof msg !== 'string') {\n            msg = $String(msg);\n        }\n        if (!name) {\n            return msg;\n        }\n        if (!msg) {\n            return name;\n        }\n        return name + ': ' + msg;\n    };\n    // can't use defineProperties here because of toString enumeration issue in IE <= 8\n    Error.prototype.toString = errorToStringShim;\n}\n\n}));\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/es5-shim/es5-shim.js\n ** module id = 172\n ** module chunks = 0\n **/","\"use strict\";\n\nrequire(\"core-js/shim\");\n\nrequire(\"babel-regenerator-runtime\");\n\nif (global._babelPolyfill) {\n  throw new Error(\"only one instance of babel-polyfill is allowed\");\n}\nglobal._babelPolyfill = true;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/lib/index.js\n ** module id = 173\n ** module chunks = 0\n **/","require('./modules/es5');\nrequire('./modules/es6.symbol');\nrequire('./modules/es6.object.assign');\nrequire('./modules/es6.object.is');\nrequire('./modules/es6.object.set-prototype-of');\nrequire('./modules/es6.object.to-string');\nrequire('./modules/es6.object.freeze');\nrequire('./modules/es6.object.seal');\nrequire('./modules/es6.object.prevent-extensions');\nrequire('./modules/es6.object.is-frozen');\nrequire('./modules/es6.object.is-sealed');\nrequire('./modules/es6.object.is-extensible');\nrequire('./modules/es6.object.get-own-property-descriptor');\nrequire('./modules/es6.object.get-prototype-of');\nrequire('./modules/es6.object.keys');\nrequire('./modules/es6.object.get-own-property-names');\nrequire('./modules/es6.function.name');\nrequire('./modules/es6.function.has-instance');\nrequire('./modules/es6.number.constructor');\nrequire('./modules/es6.number.epsilon');\nrequire('./modules/es6.number.is-finite');\nrequire('./modules/es6.number.is-integer');\nrequire('./modules/es6.number.is-nan');\nrequire('./modules/es6.number.is-safe-integer');\nrequire('./modules/es6.number.max-safe-integer');\nrequire('./modules/es6.number.min-safe-integer');\nrequire('./modules/es6.number.parse-float');\nrequire('./modules/es6.number.parse-int');\nrequire('./modules/es6.math.acosh');\nrequire('./modules/es6.math.asinh');\nrequire('./modules/es6.math.atanh');\nrequire('./modules/es6.math.cbrt');\nrequire('./modules/es6.math.clz32');\nrequire('./modules/es6.math.cosh');\nrequire('./modules/es6.math.expm1');\nrequire('./modules/es6.math.fround');\nrequire('./modules/es6.math.hypot');\nrequire('./modules/es6.math.imul');\nrequire('./modules/es6.math.log10');\nrequire('./modules/es6.math.log1p');\nrequire('./modules/es6.math.log2');\nrequire('./modules/es6.math.sign');\nrequire('./modules/es6.math.sinh');\nrequire('./modules/es6.math.tanh');\nrequire('./modules/es6.math.trunc');\nrequire('./modules/es6.string.from-code-point');\nrequire('./modules/es6.string.raw');\nrequire('./modules/es6.string.trim');\nrequire('./modules/es6.string.iterator');\nrequire('./modules/es6.string.code-point-at');\nrequire('./modules/es6.string.ends-with');\nrequire('./modules/es6.string.includes');\nrequire('./modules/es6.string.repeat');\nrequire('./modules/es6.string.starts-with');\nrequire('./modules/es6.array.from');\nrequire('./modules/es6.array.of');\nrequire('./modules/es6.array.iterator');\nrequire('./modules/es6.array.species');\nrequire('./modules/es6.array.copy-within');\nrequire('./modules/es6.array.fill');\nrequire('./modules/es6.array.find');\nrequire('./modules/es6.array.find-index');\nrequire('./modules/es6.regexp.constructor');\nrequire('./modules/es6.regexp.flags');\nrequire('./modules/es6.regexp.match');\nrequire('./modules/es6.regexp.replace');\nrequire('./modules/es6.regexp.search');\nrequire('./modules/es6.regexp.split');\nrequire('./modules/es6.promise');\nrequire('./modules/es6.map');\nrequire('./modules/es6.set');\nrequire('./modules/es6.weak-map');\nrequire('./modules/es6.weak-set');\nrequire('./modules/es6.reflect.apply');\nrequire('./modules/es6.reflect.construct');\nrequire('./modules/es6.reflect.define-property');\nrequire('./modules/es6.reflect.delete-property');\nrequire('./modules/es6.reflect.enumerate');\nrequire('./modules/es6.reflect.get');\nrequire('./modules/es6.reflect.get-own-property-descriptor');\nrequire('./modules/es6.reflect.get-prototype-of');\nrequire('./modules/es6.reflect.has');\nrequire('./modules/es6.reflect.is-extensible');\nrequire('./modules/es6.reflect.own-keys');\nrequire('./modules/es6.reflect.prevent-extensions');\nrequire('./modules/es6.reflect.set');\nrequire('./modules/es6.reflect.set-prototype-of');\nrequire('./modules/es7.array.includes');\nrequire('./modules/es7.string.at');\nrequire('./modules/es7.string.pad-left');\nrequire('./modules/es7.string.pad-right');\nrequire('./modules/es7.string.trim-left');\nrequire('./modules/es7.string.trim-right');\nrequire('./modules/es7.regexp.escape');\nrequire('./modules/es7.object.get-own-property-descriptors');\nrequire('./modules/es7.object.values');\nrequire('./modules/es7.object.entries');\nrequire('./modules/es7.map.to-json');\nrequire('./modules/es7.set.to-json');\nrequire('./modules/js.array.statics');\nrequire('./modules/web.timers');\nrequire('./modules/web.immediate');\nrequire('./modules/web.dom.iterable');\nmodule.exports = require('./modules/$.core');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/shim.js\n ** module id = 174\n ** module chunks = 0\n **/","'use strict';\nvar $                 = require('./$')\n  , $export           = require('./$.export')\n  , DESCRIPTORS       = require('./$.descriptors')\n  , createDesc        = require('./$.property-desc')\n  , html              = require('./$.html')\n  , cel               = require('./$.dom-create')\n  , has               = require('./$.has')\n  , cof               = require('./$.cof')\n  , invoke            = require('./$.invoke')\n  , fails             = require('./$.fails')\n  , anObject          = require('./$.an-object')\n  , aFunction         = require('./$.a-function')\n  , isObject          = require('./$.is-object')\n  , toObject          = require('./$.to-object')\n  , toIObject         = require('./$.to-iobject')\n  , toInteger         = require('./$.to-integer')\n  , toIndex           = require('./$.to-index')\n  , toLength          = require('./$.to-length')\n  , IObject           = require('./$.iobject')\n  , IE_PROTO          = require('./$.uid')('__proto__')\n  , createArrayMethod = require('./$.array-methods')\n  , arrayIndexOf      = require('./$.array-includes')(false)\n  , ObjectProto       = Object.prototype\n  , ArrayProto        = Array.prototype\n  , arraySlice        = ArrayProto.slice\n  , arrayJoin         = ArrayProto.join\n  , defineProperty    = $.setDesc\n  , getOwnDescriptor  = $.getDesc\n  , defineProperties  = $.setDescs\n  , factories         = {}\n  , IE8_DOM_DEFINE;\n\nif(!DESCRIPTORS){\n  IE8_DOM_DEFINE = !fails(function(){\n    return defineProperty(cel('div'), 'a', {get: function(){ return 7; }}).a != 7;\n  });\n  $.setDesc = function(O, P, Attributes){\n    if(IE8_DOM_DEFINE)try {\n      return defineProperty(O, P, Attributes);\n    } catch(e){ /* empty */ }\n    if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');\n    if('value' in Attributes)anObject(O)[P] = Attributes.value;\n    return O;\n  };\n  $.getDesc = function(O, P){\n    if(IE8_DOM_DEFINE)try {\n      return getOwnDescriptor(O, P);\n    } catch(e){ /* empty */ }\n    if(has(O, P))return createDesc(!ObjectProto.propertyIsEnumerable.call(O, P), O[P]);\n  };\n  $.setDescs = defineProperties = function(O, Properties){\n    anObject(O);\n    var keys   = $.getKeys(Properties)\n      , length = keys.length\n      , i = 0\n      , P;\n    while(length > i)$.setDesc(O, P = keys[i++], Properties[P]);\n    return O;\n  };\n}\n$export($export.S + $export.F * !DESCRIPTORS, 'Object', {\n  // 19.1.2.6 / 15.2.3.3 Object.getOwnPropertyDescriptor(O, P)\n  getOwnPropertyDescriptor: $.getDesc,\n  // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)\n  defineProperty: $.setDesc,\n  // 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)\n  defineProperties: defineProperties\n});\n\n  // IE 8- don't enum bug keys\nvar keys1 = ('constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,' +\n            'toLocaleString,toString,valueOf').split(',')\n  // Additional keys for getOwnPropertyNames\n  , keys2 = keys1.concat('length', 'prototype')\n  , keysLen1 = keys1.length;\n\n// Create object with `null` prototype: use iframe Object with cleared prototype\nvar createDict = function(){\n  // Thrash, waste and sodomy: IE GC bug\n  var iframe = cel('iframe')\n    , i      = keysLen1\n    , gt     = '>'\n    , iframeDocument;\n  iframe.style.display = 'none';\n  html.appendChild(iframe);\n  iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n  // createDict = iframe.contentWindow.Object;\n  // html.removeChild(iframe);\n  iframeDocument = iframe.contentWindow.document;\n  iframeDocument.open();\n  iframeDocument.write('<script>document.F=Object</script' + gt);\n  iframeDocument.close();\n  createDict = iframeDocument.F;\n  while(i--)delete createDict.prototype[keys1[i]];\n  return createDict();\n};\nvar createGetKeys = function(names, length){\n  return function(object){\n    var O      = toIObject(object)\n      , i      = 0\n      , result = []\n      , key;\n    for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);\n    // Don't enum bug & hidden keys\n    while(length > i)if(has(O, key = names[i++])){\n      ~arrayIndexOf(result, key) || result.push(key);\n    }\n    return result;\n  };\n};\nvar Empty = function(){};\n$export($export.S, 'Object', {\n  // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\n  getPrototypeOf: $.getProto = $.getProto || function(O){\n    O = toObject(O);\n    if(has(O, IE_PROTO))return O[IE_PROTO];\n    if(typeof O.constructor == 'function' && O instanceof O.constructor){\n      return O.constructor.prototype;\n    } return O instanceof Object ? ObjectProto : null;\n  },\n  // 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\n  getOwnPropertyNames: $.getNames = $.getNames || createGetKeys(keys2, keys2.length, true),\n  // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\n  create: $.create = $.create || function(O, /*?*/Properties){\n    var result;\n    if(O !== null){\n      Empty.prototype = anObject(O);\n      result = new Empty();\n      Empty.prototype = null;\n      // add \"__proto__\" for Object.getPrototypeOf shim\n      result[IE_PROTO] = O;\n    } else result = createDict();\n    return Properties === undefined ? result : defineProperties(result, Properties);\n  },\n  // 19.1.2.14 / 15.2.3.14 Object.keys(O)\n  keys: $.getKeys = $.getKeys || createGetKeys(keys1, keysLen1, false)\n});\n\nvar construct = function(F, len, args){\n  if(!(len in factories)){\n    for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']';\n    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');\n  }\n  return factories[len](F, args);\n};\n\n// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)\n$export($export.P, 'Function', {\n  bind: function bind(that /*, args... */){\n    var fn       = aFunction(this)\n      , partArgs = arraySlice.call(arguments, 1);\n    var bound = function(/* args... */){\n      var args = partArgs.concat(arraySlice.call(arguments));\n      return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);\n    };\n    if(isObject(fn.prototype))bound.prototype = fn.prototype;\n    return bound;\n  }\n});\n\n// fallback for not array-like ES3 strings and DOM objects\n$export($export.P + $export.F * fails(function(){\n  if(html)arraySlice.call(html);\n}), 'Array', {\n  slice: function(begin, end){\n    var len   = toLength(this.length)\n      , klass = cof(this);\n    end = end === undefined ? len : end;\n    if(klass == 'Array')return arraySlice.call(this, begin, end);\n    var start  = toIndex(begin, len)\n      , upTo   = toIndex(end, len)\n      , size   = toLength(upTo - start)\n      , cloned = Array(size)\n      , i      = 0;\n    for(; i < size; i++)cloned[i] = klass == 'String'\n      ? this.charAt(start + i)\n      : this[start + i];\n    return cloned;\n  }\n});\n$export($export.P + $export.F * (IObject != Object), 'Array', {\n  join: function join(separator){\n    return arrayJoin.call(IObject(this), separator === undefined ? ',' : separator);\n  }\n});\n\n// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)\n$export($export.S, 'Array', {isArray: require('./$.is-array')});\n\nvar createArrayReduce = function(isRight){\n  return function(callbackfn, memo){\n    aFunction(callbackfn);\n    var O      = IObject(this)\n      , length = toLength(O.length)\n      , index  = isRight ? length - 1 : 0\n      , i      = isRight ? -1 : 1;\n    if(arguments.length < 2)for(;;){\n      if(index in O){\n        memo = O[index];\n        index += i;\n        break;\n      }\n      index += i;\n      if(isRight ? index < 0 : length <= index){\n        throw TypeError('Reduce of empty array with no initial value');\n      }\n    }\n    for(;isRight ? index >= 0 : length > index; index += i)if(index in O){\n      memo = callbackfn(memo, O[index], index, this);\n    }\n    return memo;\n  };\n};\n\nvar methodize = function($fn){\n  return function(arg1/*, arg2 = undefined */){\n    return $fn(this, arg1, arguments[1]);\n  };\n};\n\n$export($export.P, 'Array', {\n  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])\n  forEach: $.each = $.each || methodize(createArrayMethod(0)),\n  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])\n  map: methodize(createArrayMethod(1)),\n  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])\n  filter: methodize(createArrayMethod(2)),\n  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])\n  some: methodize(createArrayMethod(3)),\n  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])\n  every: methodize(createArrayMethod(4)),\n  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])\n  reduce: createArrayReduce(false),\n  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])\n  reduceRight: createArrayReduce(true),\n  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])\n  indexOf: methodize(arrayIndexOf),\n  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])\n  lastIndexOf: function(el, fromIndex /* = @[*-1] */){\n    var O      = toIObject(this)\n      , length = toLength(O.length)\n      , index  = length - 1;\n    if(arguments.length > 1)index = Math.min(index, toInteger(fromIndex));\n    if(index < 0)index = toLength(length + index);\n    for(;index >= 0; index--)if(index in O)if(O[index] === el)return index;\n    return -1;\n  }\n});\n\n// 20.3.3.1 / 15.9.4.4 Date.now()\n$export($export.S, 'Date', {now: function(){ return +new Date; }});\n\nvar lz = function(num){\n  return num > 9 ? num : '0' + num;\n};\n\n// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()\n// PhantomJS / old WebKit has a broken implementations\n$export($export.P + $export.F * (fails(function(){\n  return new Date(-5e13 - 1).toISOString() != '0385-07-25T07:06:39.999Z';\n}) || !fails(function(){\n  new Date(NaN).toISOString();\n})), 'Date', {\n  toISOString: function toISOString(){\n    if(!isFinite(this))throw RangeError('Invalid time value');\n    var d = this\n      , y = d.getUTCFullYear()\n      , m = d.getUTCMilliseconds()\n      , s = y < 0 ? '-' : y > 9999 ? '+' : '';\n    return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +\n      '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +\n      'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +\n      ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es5.js\n ** module id = 175\n ** module chunks = 0\n **/","var $Object = Object;\nmodule.exports = {\n  create:     $Object.create,\n  getProto:   $Object.getPrototypeOf,\n  isEnum:     {}.propertyIsEnumerable,\n  getDesc:    $Object.getOwnPropertyDescriptor,\n  setDesc:    $Object.defineProperty,\n  setDescs:   $Object.defineProperties,\n  getKeys:    $Object.keys,\n  getNames:   $Object.getOwnPropertyNames,\n  getSymbols: $Object.getOwnPropertySymbols,\n  each:       [].forEach\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.js\n ** module id = 176\n ** module chunks = 0\n **/","var global    = require('./$.global')\n  , core      = require('./$.core')\n  , hide      = require('./$.hide')\n  , redefine  = require('./$.redefine')\n  , ctx       = require('./$.ctx')\n  , PROTOTYPE = 'prototype';\n\nvar $export = function(type, name, source){\n  var IS_FORCED = type & $export.F\n    , IS_GLOBAL = type & $export.G\n    , IS_STATIC = type & $export.S\n    , IS_PROTO  = type & $export.P\n    , IS_BIND   = type & $export.B\n    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]\n    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})\n    , expProto  = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})\n    , key, own, out, exp;\n  if(IS_GLOBAL)source = name;\n  for(key in source){\n    // contains in native\n    own = !IS_FORCED && target && key in target;\n    // export native or passed\n    out = (own ? target : source)[key];\n    // bind timers to global for call from export context\n    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n    // extend global\n    if(target && !own)redefine(target, key, out);\n    // export\n    if(exports[key] != out)hide(exports, key, exp);\n    if(IS_PROTO && expProto[key] != out)expProto[key] = out;\n  }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1;  // forced\n$export.G = 2;  // global\n$export.S = 4;  // static\n$export.P = 8;  // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\nmodule.exports = $export;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.export.js\n ** module id = 177\n ** module chunks = 0\n **/","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\nif(typeof __g == 'number')__g = global; // eslint-disable-line no-undef\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.global.js\n ** module id = 178\n ** module chunks = 0\n **/","var core = module.exports = {version: '1.2.6'};\nif(typeof __e == 'number')__e = core; // eslint-disable-line no-undef\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.core.js\n ** module id = 179\n ** module chunks = 0\n **/","var $          = require('./$')\n  , createDesc = require('./$.property-desc');\nmodule.exports = require('./$.descriptors') ? function(object, key, value){\n  return $.setDesc(object, key, createDesc(1, value));\n} : function(object, key, value){\n  object[key] = value;\n  return object;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.hide.js\n ** module id = 180\n ** module chunks = 0\n **/","module.exports = function(bitmap, value){\n  return {\n    enumerable  : !(bitmap & 1),\n    configurable: !(bitmap & 2),\n    writable    : !(bitmap & 4),\n    value       : value\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.property-desc.js\n ** module id = 181\n ** module chunks = 0\n **/","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./$.fails')(function(){\n  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.descriptors.js\n ** module id = 182\n ** module chunks = 0\n **/","module.exports = function(exec){\n  try {\n    return !!exec();\n  } catch(e){\n    return true;\n  }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.fails.js\n ** module id = 183\n ** module chunks = 0\n **/","// add fake Function#toString\n// for correct work wrapped methods / constructors with methods like LoDash isNative\nvar global    = require('./$.global')\n  , hide      = require('./$.hide')\n  , SRC       = require('./$.uid')('src')\n  , TO_STRING = 'toString'\n  , $toString = Function[TO_STRING]\n  , TPL       = ('' + $toString).split(TO_STRING);\n\nrequire('./$.core').inspectSource = function(it){\n  return $toString.call(it);\n};\n\n(module.exports = function(O, key, val, safe){\n  if(typeof val == 'function'){\n    val.hasOwnProperty(SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n    val.hasOwnProperty('name') || hide(val, 'name', key);\n  }\n  if(O === global){\n    O[key] = val;\n  } else {\n    if(!safe)delete O[key];\n    hide(O, key, val);\n  }\n})(Function.prototype, TO_STRING, function toString(){\n  return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.redefine.js\n ** module id = 184\n ** module chunks = 0\n **/","var id = 0\n  , px = Math.random();\nmodule.exports = function(key){\n  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.uid.js\n ** module id = 185\n ** module chunks = 0\n **/","// optional / simple context binding\nvar aFunction = require('./$.a-function');\nmodule.exports = function(fn, that, length){\n  aFunction(fn);\n  if(that === undefined)return fn;\n  switch(length){\n    case 1: return function(a){\n      return fn.call(that, a);\n    };\n    case 2: return function(a, b){\n      return fn.call(that, a, b);\n    };\n    case 3: return function(a, b, c){\n      return fn.call(that, a, b, c);\n    };\n  }\n  return function(/* ...args */){\n    return fn.apply(that, arguments);\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.ctx.js\n ** module id = 186\n ** module chunks = 0\n **/","module.exports = function(it){\n  if(typeof it != 'function')throw TypeError(it + ' is not a function!');\n  return it;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.a-function.js\n ** module id = 187\n ** module chunks = 0\n **/","module.exports = require('./$.global').document && document.documentElement;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.html.js\n ** module id = 188\n ** module chunks = 0\n **/","var isObject = require('./$.is-object')\n  , document = require('./$.global').document\n  // in old IE typeof document.createElement is 'object'\n  , is = isObject(document) && isObject(document.createElement);\nmodule.exports = function(it){\n  return is ? document.createElement(it) : {};\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.dom-create.js\n ** module id = 189\n ** module chunks = 0\n **/","module.exports = function(it){\n  return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.is-object.js\n ** module id = 190\n ** module chunks = 0\n **/","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function(it, key){\n  return hasOwnProperty.call(it, key);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.has.js\n ** module id = 191\n ** module chunks = 0\n **/","var toString = {}.toString;\n\nmodule.exports = function(it){\n  return toString.call(it).slice(8, -1);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.cof.js\n ** module id = 192\n ** module chunks = 0\n **/","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function(fn, args, that){\n  var un = that === undefined;\n  switch(args.length){\n    case 0: return un ? fn()\n                      : fn.call(that);\n    case 1: return un ? fn(args[0])\n                      : fn.call(that, args[0]);\n    case 2: return un ? fn(args[0], args[1])\n                      : fn.call(that, args[0], args[1]);\n    case 3: return un ? fn(args[0], args[1], args[2])\n                      : fn.call(that, args[0], args[1], args[2]);\n    case 4: return un ? fn(args[0], args[1], args[2], args[3])\n                      : fn.call(that, args[0], args[1], args[2], args[3]);\n  } return              fn.apply(that, args);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.invoke.js\n ** module id = 193\n ** module chunks = 0\n **/","var isObject = require('./$.is-object');\nmodule.exports = function(it){\n  if(!isObject(it))throw TypeError(it + ' is not an object!');\n  return it;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.an-object.js\n ** module id = 194\n ** module chunks = 0\n **/","// 7.1.13 ToObject(argument)\nvar defined = require('./$.defined');\nmodule.exports = function(it){\n  return Object(defined(it));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.to-object.js\n ** module id = 195\n ** module chunks = 0\n **/","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function(it){\n  if(it == undefined)throw TypeError(\"Can't call method on  \" + it);\n  return it;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.defined.js\n ** module id = 196\n ** module chunks = 0\n **/","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./$.iobject')\n  , defined = require('./$.defined');\nmodule.exports = function(it){\n  return IObject(defined(it));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.to-iobject.js\n ** module id = 197\n ** module chunks = 0\n **/","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./$.cof');\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){\n  return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iobject.js\n ** module id = 198\n ** module chunks = 0\n **/","// 7.1.4 ToInteger\nvar ceil  = Math.ceil\n  , floor = Math.floor;\nmodule.exports = function(it){\n  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.to-integer.js\n ** module id = 199\n ** module chunks = 0\n **/","var toInteger = require('./$.to-integer')\n  , max       = Math.max\n  , min       = Math.min;\nmodule.exports = function(index, length){\n  index = toInteger(index);\n  return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.to-index.js\n ** module id = 200\n ** module chunks = 0\n **/","// 7.1.15 ToLength\nvar toInteger = require('./$.to-integer')\n  , min       = Math.min;\nmodule.exports = function(it){\n  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.to-length.js\n ** module id = 201\n ** module chunks = 0\n **/","// 0 -> Array#forEach\n// 1 -> Array#map\n// 2 -> Array#filter\n// 3 -> Array#some\n// 4 -> Array#every\n// 5 -> Array#find\n// 6 -> Array#findIndex\nvar ctx      = require('./$.ctx')\n  , IObject  = require('./$.iobject')\n  , toObject = require('./$.to-object')\n  , toLength = require('./$.to-length')\n  , asc      = require('./$.array-species-create');\nmodule.exports = function(TYPE){\n  var IS_MAP        = TYPE == 1\n    , IS_FILTER     = TYPE == 2\n    , IS_SOME       = TYPE == 3\n    , IS_EVERY      = TYPE == 4\n    , IS_FIND_INDEX = TYPE == 6\n    , NO_HOLES      = TYPE == 5 || IS_FIND_INDEX;\n  return function($this, callbackfn, that){\n    var O      = toObject($this)\n      , self   = IObject(O)\n      , f      = ctx(callbackfn, that, 3)\n      , length = toLength(self.length)\n      , index  = 0\n      , result = IS_MAP ? asc($this, length) : IS_FILTER ? asc($this, 0) : undefined\n      , val, res;\n    for(;length > index; index++)if(NO_HOLES || index in self){\n      val = self[index];\n      res = f(val, index, O);\n      if(TYPE){\n        if(IS_MAP)result[index] = res;            // map\n        else if(res)switch(TYPE){\n          case 3: return true;                    // some\n          case 5: return val;                     // find\n          case 6: return index;                   // findIndex\n          case 2: result.push(val);               // filter\n        } else if(IS_EVERY)return false;          // every\n      }\n    }\n    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.array-methods.js\n ** module id = 202\n ** module chunks = 0\n **/","// 9.4.2.3 ArraySpeciesCreate(originalArray, length)\nvar isObject = require('./$.is-object')\n  , isArray  = require('./$.is-array')\n  , SPECIES  = require('./$.wks')('species');\nmodule.exports = function(original, length){\n  var C;\n  if(isArray(original)){\n    C = original.constructor;\n    // cross-realm fallback\n    if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined;\n    if(isObject(C)){\n      C = C[SPECIES];\n      if(C === null)C = undefined;\n    }\n  } return new (C === undefined ? Array : C)(length);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.array-species-create.js\n ** module id = 203\n ** module chunks = 0\n **/","// 7.2.2 IsArray(argument)\nvar cof = require('./$.cof');\nmodule.exports = Array.isArray || function(arg){\n  return cof(arg) == 'Array';\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.is-array.js\n ** module id = 204\n ** module chunks = 0\n **/","var store  = require('./$.shared')('wks')\n  , uid    = require('./$.uid')\n  , Symbol = require('./$.global').Symbol;\nmodule.exports = function(name){\n  return store[name] || (store[name] =\n    Symbol && Symbol[name] || (Symbol || uid)('Symbol.' + name));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.wks.js\n ** module id = 205\n ** module chunks = 0\n **/","var global = require('./$.global')\n  , SHARED = '__core-js_shared__'\n  , store  = global[SHARED] || (global[SHARED] = {});\nmodule.exports = function(key){\n  return store[key] || (store[key] = {});\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.shared.js\n ** module id = 206\n ** module chunks = 0\n **/","// false -> Array#indexOf\n// true  -> Array#includes\nvar toIObject = require('./$.to-iobject')\n  , toLength  = require('./$.to-length')\n  , toIndex   = require('./$.to-index');\nmodule.exports = function(IS_INCLUDES){\n  return function($this, el, fromIndex){\n    var O      = toIObject($this)\n      , length = toLength(O.length)\n      , index  = toIndex(fromIndex, length)\n      , value;\n    // Array#includes uses SameValueZero equality algorithm\n    if(IS_INCLUDES && el != el)while(length > index){\n      value = O[index++];\n      if(value != value)return true;\n    // Array#toIndex ignores holes, Array#includes - not\n    } else for(;length > index; index++)if(IS_INCLUDES || index in O){\n      if(O[index] === el)return IS_INCLUDES || index;\n    } return !IS_INCLUDES && -1;\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.array-includes.js\n ** module id = 207\n ** module chunks = 0\n **/","'use strict';\n// ECMAScript 6 symbols shim\nvar $              = require('./$')\n  , global         = require('./$.global')\n  , has            = require('./$.has')\n  , DESCRIPTORS    = require('./$.descriptors')\n  , $export        = require('./$.export')\n  , redefine       = require('./$.redefine')\n  , $fails         = require('./$.fails')\n  , shared         = require('./$.shared')\n  , setToStringTag = require('./$.set-to-string-tag')\n  , uid            = require('./$.uid')\n  , wks            = require('./$.wks')\n  , keyOf          = require('./$.keyof')\n  , $names         = require('./$.get-names')\n  , enumKeys       = require('./$.enum-keys')\n  , isArray        = require('./$.is-array')\n  , anObject       = require('./$.an-object')\n  , toIObject      = require('./$.to-iobject')\n  , createDesc     = require('./$.property-desc')\n  , getDesc        = $.getDesc\n  , setDesc        = $.setDesc\n  , _create        = $.create\n  , getNames       = $names.get\n  , $Symbol        = global.Symbol\n  , $JSON          = global.JSON\n  , _stringify     = $JSON && $JSON.stringify\n  , setter         = false\n  , HIDDEN         = wks('_hidden')\n  , isEnum         = $.isEnum\n  , SymbolRegistry = shared('symbol-registry')\n  , AllSymbols     = shared('symbols')\n  , useNative      = typeof $Symbol == 'function'\n  , ObjectProto    = Object.prototype;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDesc = DESCRIPTORS && $fails(function(){\n  return _create(setDesc({}, 'a', {\n    get: function(){ return setDesc(this, 'a', {value: 7}).a; }\n  })).a != 7;\n}) ? function(it, key, D){\n  var protoDesc = getDesc(ObjectProto, key);\n  if(protoDesc)delete ObjectProto[key];\n  setDesc(it, key, D);\n  if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc);\n} : setDesc;\n\nvar wrap = function(tag){\n  var sym = AllSymbols[tag] = _create($Symbol.prototype);\n  sym._k = tag;\n  DESCRIPTORS && setter && setSymbolDesc(ObjectProto, tag, {\n    configurable: true,\n    set: function(value){\n      if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;\n      setSymbolDesc(this, tag, createDesc(1, value));\n    }\n  });\n  return sym;\n};\n\nvar isSymbol = function(it){\n  return typeof it == 'symbol';\n};\n\nvar $defineProperty = function defineProperty(it, key, D){\n  if(D && has(AllSymbols, key)){\n    if(!D.enumerable){\n      if(!has(it, HIDDEN))setDesc(it, HIDDEN, createDesc(1, {}));\n      it[HIDDEN][key] = true;\n    } else {\n      if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;\n      D = _create(D, {enumerable: createDesc(0, false)});\n    } return setSymbolDesc(it, key, D);\n  } return setDesc(it, key, D);\n};\nvar $defineProperties = function defineProperties(it, P){\n  anObject(it);\n  var keys = enumKeys(P = toIObject(P))\n    , i    = 0\n    , l = keys.length\n    , key;\n  while(l > i)$defineProperty(it, key = keys[i++], P[key]);\n  return it;\n};\nvar $create = function create(it, P){\n  return P === undefined ? _create(it) : $defineProperties(_create(it), P);\n};\nvar $propertyIsEnumerable = function propertyIsEnumerable(key){\n  var E = isEnum.call(this, key);\n  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key]\n    ? E : true;\n};\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){\n  var D = getDesc(it = toIObject(it), key);\n  if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;\n  return D;\n};\nvar $getOwnPropertyNames = function getOwnPropertyNames(it){\n  var names  = getNames(toIObject(it))\n    , result = []\n    , i      = 0\n    , key;\n  while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key);\n  return result;\n};\nvar $getOwnPropertySymbols = function getOwnPropertySymbols(it){\n  var names  = getNames(toIObject(it))\n    , result = []\n    , i      = 0\n    , key;\n  while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]);\n  return result;\n};\nvar $stringify = function stringify(it){\n  if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined\n  var args = [it]\n    , i    = 1\n    , $$   = arguments\n    , replacer, $replacer;\n  while($$.length > i)args.push($$[i++]);\n  replacer = args[1];\n  if(typeof replacer == 'function')$replacer = replacer;\n  if($replacer || !isArray(replacer))replacer = function(key, value){\n    if($replacer)value = $replacer.call(this, key, value);\n    if(!isSymbol(value))return value;\n  };\n  args[1] = replacer;\n  return _stringify.apply($JSON, args);\n};\nvar buggyJSON = $fails(function(){\n  var S = $Symbol();\n  // MS Edge converts symbol values to JSON as {}\n  // WebKit converts symbol values to JSON as null\n  // V8 throws on boxed symbols\n  return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';\n});\n\n// 19.4.1.1 Symbol([description])\nif(!useNative){\n  $Symbol = function Symbol(){\n    if(isSymbol(this))throw TypeError('Symbol is not a constructor');\n    return wrap(uid(arguments.length > 0 ? arguments[0] : undefined));\n  };\n  redefine($Symbol.prototype, 'toString', function toString(){\n    return this._k;\n  });\n\n  isSymbol = function(it){\n    return it instanceof $Symbol;\n  };\n\n  $.create     = $create;\n  $.isEnum     = $propertyIsEnumerable;\n  $.getDesc    = $getOwnPropertyDescriptor;\n  $.setDesc    = $defineProperty;\n  $.setDescs   = $defineProperties;\n  $.getNames   = $names.get = $getOwnPropertyNames;\n  $.getSymbols = $getOwnPropertySymbols;\n\n  if(DESCRIPTORS && !require('./$.library')){\n    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);\n  }\n}\n\nvar symbolStatics = {\n  // 19.4.2.1 Symbol.for(key)\n  'for': function(key){\n    return has(SymbolRegistry, key += '')\n      ? SymbolRegistry[key]\n      : SymbolRegistry[key] = $Symbol(key);\n  },\n  // 19.4.2.5 Symbol.keyFor(sym)\n  keyFor: function keyFor(key){\n    return keyOf(SymbolRegistry, key);\n  },\n  useSetter: function(){ setter = true; },\n  useSimple: function(){ setter = false; }\n};\n// 19.4.2.2 Symbol.hasInstance\n// 19.4.2.3 Symbol.isConcatSpreadable\n// 19.4.2.4 Symbol.iterator\n// 19.4.2.6 Symbol.match\n// 19.4.2.8 Symbol.replace\n// 19.4.2.9 Symbol.search\n// 19.4.2.10 Symbol.species\n// 19.4.2.11 Symbol.split\n// 19.4.2.12 Symbol.toPrimitive\n// 19.4.2.13 Symbol.toStringTag\n// 19.4.2.14 Symbol.unscopables\n$.each.call((\n  'hasInstance,isConcatSpreadable,iterator,match,replace,search,' +\n  'species,split,toPrimitive,toStringTag,unscopables'\n).split(','), function(it){\n  var sym = wks(it);\n  symbolStatics[it] = useNative ? sym : wrap(sym);\n});\n\nsetter = true;\n\n$export($export.G + $export.W, {Symbol: $Symbol});\n\n$export($export.S, 'Symbol', symbolStatics);\n\n$export($export.S + $export.F * !useNative, 'Object', {\n  // 19.1.2.2 Object.create(O [, Properties])\n  create: $create,\n  // 19.1.2.4 Object.defineProperty(O, P, Attributes)\n  defineProperty: $defineProperty,\n  // 19.1.2.3 Object.defineProperties(O, Properties)\n  defineProperties: $defineProperties,\n  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\n  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,\n  // 19.1.2.7 Object.getOwnPropertyNames(O)\n  getOwnPropertyNames: $getOwnPropertyNames,\n  // 19.1.2.8 Object.getOwnPropertySymbols(O)\n  getOwnPropertySymbols: $getOwnPropertySymbols\n});\n\n// 24.3.2 JSON.stringify(value [, replacer [, space]])\n$JSON && $export($export.S + $export.F * (!useNative || buggyJSON), 'JSON', {stringify: $stringify});\n\n// 19.4.3.5 Symbol.prototype[@@toStringTag]\nsetToStringTag($Symbol, 'Symbol');\n// 20.2.1.9 Math[@@toStringTag]\nsetToStringTag(Math, 'Math', true);\n// 24.3.3 JSON[@@toStringTag]\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.symbol.js\n ** module id = 208\n ** module chunks = 0\n **/","var def = require('./$').setDesc\n  , has = require('./$.has')\n  , TAG = require('./$.wks')('toStringTag');\n\nmodule.exports = function(it, tag, stat){\n  if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.set-to-string-tag.js\n ** module id = 209\n ** module chunks = 0\n **/","var $         = require('./$')\n  , toIObject = require('./$.to-iobject');\nmodule.exports = function(object, el){\n  var O      = toIObject(object)\n    , keys   = $.getKeys(O)\n    , length = keys.length\n    , index  = 0\n    , key;\n  while(length > index)if(O[key = keys[index++]] === el)return key;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.keyof.js\n ** module id = 210\n ** module chunks = 0\n **/","// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nvar toIObject = require('./$.to-iobject')\n  , getNames  = require('./$').getNames\n  , toString  = {}.toString;\n\nvar windowNames = typeof window == 'object' && Object.getOwnPropertyNames\n  ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function(it){\n  try {\n    return getNames(it);\n  } catch(e){\n    return windowNames.slice();\n  }\n};\n\nmodule.exports.get = function getOwnPropertyNames(it){\n  if(windowNames && toString.call(it) == '[object Window]')return getWindowNames(it);\n  return getNames(toIObject(it));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.get-names.js\n ** module id = 211\n ** module chunks = 0\n **/","// all enumerable object keys, includes symbols\nvar $ = require('./$');\nmodule.exports = function(it){\n  var keys       = $.getKeys(it)\n    , getSymbols = $.getSymbols;\n  if(getSymbols){\n    var symbols = getSymbols(it)\n      , isEnum  = $.isEnum\n      , i       = 0\n      , key;\n    while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))keys.push(key);\n  }\n  return keys;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.enum-keys.js\n ** module id = 212\n ** module chunks = 0\n **/","module.exports = false;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.library.js\n ** module id = 213\n ** module chunks = 0\n **/","// 19.1.3.1 Object.assign(target, source)\nvar $export = require('./$.export');\n\n$export($export.S + $export.F, 'Object', {assign: require('./$.object-assign')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.assign.js\n ** module id = 214\n ** module chunks = 0\n **/","// 19.1.2.1 Object.assign(target, source, ...)\nvar $        = require('./$')\n  , toObject = require('./$.to-object')\n  , IObject  = require('./$.iobject');\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = require('./$.fails')(function(){\n  var a = Object.assign\n    , A = {}\n    , B = {}\n    , S = Symbol()\n    , K = 'abcdefghijklmnopqrst';\n  A[S] = 7;\n  K.split('').forEach(function(k){ B[k] = k; });\n  return a({}, A)[S] != 7 || Object.keys(a({}, B)).join('') != K;\n}) ? function assign(target, source){ // eslint-disable-line no-unused-vars\n  var T     = toObject(target)\n    , $$    = arguments\n    , $$len = $$.length\n    , index = 1\n    , getKeys    = $.getKeys\n    , getSymbols = $.getSymbols\n    , isEnum     = $.isEnum;\n  while($$len > index){\n    var S      = IObject($$[index++])\n      , keys   = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)\n      , length = keys.length\n      , j      = 0\n      , key;\n    while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];\n  }\n  return T;\n} : Object.assign;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.object-assign.js\n ** module id = 215\n ** module chunks = 0\n **/","// 19.1.3.10 Object.is(value1, value2)\nvar $export = require('./$.export');\n$export($export.S, 'Object', {is: require('./$.same-value')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.is.js\n ** module id = 216\n ** module chunks = 0\n **/","// 7.2.9 SameValue(x, y)\nmodule.exports = Object.is || function is(x, y){\n  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.same-value.js\n ** module id = 217\n ** module chunks = 0\n **/","// 19.1.3.19 Object.setPrototypeOf(O, proto)\nvar $export = require('./$.export');\n$export($export.S, 'Object', {setPrototypeOf: require('./$.set-proto').set});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.set-prototype-of.js\n ** module id = 218\n ** module chunks = 0\n **/","// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar getDesc  = require('./$').getDesc\n  , isObject = require('./$.is-object')\n  , anObject = require('./$.an-object');\nvar check = function(O, proto){\n  anObject(O);\n  if(!isObject(proto) && proto !== null)throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n    function(test, buggy, set){\n      try {\n        set = require('./$.ctx')(Function.call, getDesc(Object.prototype, '__proto__').set, 2);\n        set(test, []);\n        buggy = !(test instanceof Array);\n      } catch(e){ buggy = true; }\n      return function setPrototypeOf(O, proto){\n        check(O, proto);\n        if(buggy)O.__proto__ = proto;\n        else set(O, proto);\n        return O;\n      };\n    }({}, false) : undefined),\n  check: check\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.set-proto.js\n ** module id = 219\n ** module chunks = 0\n **/","'use strict';\n// 19.1.3.6 Object.prototype.toString()\nvar classof = require('./$.classof')\n  , test    = {};\ntest[require('./$.wks')('toStringTag')] = 'z';\nif(test + '' != '[object z]'){\n  require('./$.redefine')(Object.prototype, 'toString', function toString(){\n    return '[object ' + classof(this) + ']';\n  }, true);\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.to-string.js\n ** module id = 220\n ** module chunks = 0\n **/","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./$.cof')\n  , TAG = require('./$.wks')('toStringTag')\n  // ES3 wrong here\n  , ARG = cof(function(){ return arguments; }()) == 'Arguments';\n\nmodule.exports = function(it){\n  var O, T, B;\n  return it === undefined ? 'Undefined' : it === null ? 'Null'\n    // @@toStringTag case\n    : typeof (T = (O = Object(it))[TAG]) == 'string' ? T\n    // builtinTag case\n    : ARG ? cof(O)\n    // ES3 arguments fallback\n    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.classof.js\n ** module id = 221\n ** module chunks = 0\n **/","// 19.1.2.5 Object.freeze(O)\nvar isObject = require('./$.is-object');\n\nrequire('./$.object-sap')('freeze', function($freeze){\n  return function freeze(it){\n    return $freeze && isObject(it) ? $freeze(it) : it;\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.freeze.js\n ** module id = 222\n ** module chunks = 0\n **/","// most Object methods by ES6 should accept primitives\nvar $export = require('./$.export')\n  , core    = require('./$.core')\n  , fails   = require('./$.fails');\nmodule.exports = function(KEY, exec){\n  var fn  = (core.Object || {})[KEY] || Object[KEY]\n    , exp = {};\n  exp[KEY] = exec(fn);\n  $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.object-sap.js\n ** module id = 223\n ** module chunks = 0\n **/","// 19.1.2.17 Object.seal(O)\nvar isObject = require('./$.is-object');\n\nrequire('./$.object-sap')('seal', function($seal){\n  return function seal(it){\n    return $seal && isObject(it) ? $seal(it) : it;\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.seal.js\n ** module id = 224\n ** module chunks = 0\n **/","// 19.1.2.15 Object.preventExtensions(O)\nvar isObject = require('./$.is-object');\n\nrequire('./$.object-sap')('preventExtensions', function($preventExtensions){\n  return function preventExtensions(it){\n    return $preventExtensions && isObject(it) ? $preventExtensions(it) : it;\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.prevent-extensions.js\n ** module id = 225\n ** module chunks = 0\n **/","// 19.1.2.12 Object.isFrozen(O)\nvar isObject = require('./$.is-object');\n\nrequire('./$.object-sap')('isFrozen', function($isFrozen){\n  return function isFrozen(it){\n    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.is-frozen.js\n ** module id = 226\n ** module chunks = 0\n **/","// 19.1.2.13 Object.isSealed(O)\nvar isObject = require('./$.is-object');\n\nrequire('./$.object-sap')('isSealed', function($isSealed){\n  return function isSealed(it){\n    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.is-sealed.js\n ** module id = 227\n ** module chunks = 0\n **/","// 19.1.2.11 Object.isExtensible(O)\nvar isObject = require('./$.is-object');\n\nrequire('./$.object-sap')('isExtensible', function($isExtensible){\n  return function isExtensible(it){\n    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.is-extensible.js\n ** module id = 228\n ** module chunks = 0\n **/","// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\nvar toIObject = require('./$.to-iobject');\n\nrequire('./$.object-sap')('getOwnPropertyDescriptor', function($getOwnPropertyDescriptor){\n  return function getOwnPropertyDescriptor(it, key){\n    return $getOwnPropertyDescriptor(toIObject(it), key);\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.get-own-property-descriptor.js\n ** module id = 229\n ** module chunks = 0\n **/","// 19.1.2.9 Object.getPrototypeOf(O)\nvar toObject = require('./$.to-object');\n\nrequire('./$.object-sap')('getPrototypeOf', function($getPrototypeOf){\n  return function getPrototypeOf(it){\n    return $getPrototypeOf(toObject(it));\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.get-prototype-of.js\n ** module id = 230\n ** module chunks = 0\n **/","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./$.to-object');\n\nrequire('./$.object-sap')('keys', function($keys){\n  return function keys(it){\n    return $keys(toObject(it));\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.keys.js\n ** module id = 231\n ** module chunks = 0\n **/","// 19.1.2.7 Object.getOwnPropertyNames(O)\nrequire('./$.object-sap')('getOwnPropertyNames', function(){\n  return require('./$.get-names').get;\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.object.get-own-property-names.js\n ** module id = 232\n ** module chunks = 0\n **/","var setDesc    = require('./$').setDesc\n  , createDesc = require('./$.property-desc')\n  , has        = require('./$.has')\n  , FProto     = Function.prototype\n  , nameRE     = /^\\s*function ([^ (]*)/\n  , NAME       = 'name';\n// 19.2.4.2 name\nNAME in FProto || require('./$.descriptors') && setDesc(FProto, NAME, {\n  configurable: true,\n  get: function(){\n    var match = ('' + this).match(nameRE)\n      , name  = match ? match[1] : '';\n    has(this, NAME) || setDesc(this, NAME, createDesc(5, name));\n    return name;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.function.name.js\n ** module id = 233\n ** module chunks = 0\n **/","'use strict';\nvar $             = require('./$')\n  , isObject      = require('./$.is-object')\n  , HAS_INSTANCE  = require('./$.wks')('hasInstance')\n  , FunctionProto = Function.prototype;\n// 19.2.3.6 Function.prototype[@@hasInstance](V)\nif(!(HAS_INSTANCE in FunctionProto))$.setDesc(FunctionProto, HAS_INSTANCE, {value: function(O){\n  if(typeof this != 'function' || !isObject(O))return false;\n  if(!isObject(this.prototype))return O instanceof this;\n  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:\n  while(O = $.getProto(O))if(this.prototype === O)return true;\n  return false;\n}});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.function.has-instance.js\n ** module id = 234\n ** module chunks = 0\n **/","'use strict';\nvar $           = require('./$')\n  , global      = require('./$.global')\n  , has         = require('./$.has')\n  , cof         = require('./$.cof')\n  , toPrimitive = require('./$.to-primitive')\n  , fails       = require('./$.fails')\n  , $trim       = require('./$.string-trim').trim\n  , NUMBER      = 'Number'\n  , $Number     = global[NUMBER]\n  , Base        = $Number\n  , proto       = $Number.prototype\n  // Opera ~12 has broken Object#toString\n  , BROKEN_COF  = cof($.create(proto)) == NUMBER\n  , TRIM        = 'trim' in String.prototype;\n\n// 7.1.3 ToNumber(argument)\nvar toNumber = function(argument){\n  var it = toPrimitive(argument, false);\n  if(typeof it == 'string' && it.length > 2){\n    it = TRIM ? it.trim() : $trim(it, 3);\n    var first = it.charCodeAt(0)\n      , third, radix, maxCode;\n    if(first === 43 || first === 45){\n      third = it.charCodeAt(2);\n      if(third === 88 || third === 120)return NaN; // Number('+0x1') should be NaN, old V8 fix\n    } else if(first === 48){\n      switch(it.charCodeAt(1)){\n        case 66 : case 98  : radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i\n        case 79 : case 111 : radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i\n        default : return +it;\n      }\n      for(var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++){\n        code = digits.charCodeAt(i);\n        // parseInt parses a string to a first unavailable symbol\n        // but ToNumber should return NaN if a string contains unavailable symbols\n        if(code < 48 || code > maxCode)return NaN;\n      } return parseInt(digits, radix);\n    }\n  } return +it;\n};\n\nif(!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')){\n  $Number = function Number(value){\n    var it = arguments.length < 1 ? 0 : value\n      , that = this;\n    return that instanceof $Number\n      // check on 1..constructor(foo) case\n      && (BROKEN_COF ? fails(function(){ proto.valueOf.call(that); }) : cof(that) != NUMBER)\n        ? new Base(toNumber(it)) : toNumber(it);\n  };\n  $.each.call(require('./$.descriptors') ? $.getNames(Base) : (\n    // ES3:\n    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n    // ES6 (in case, if modules with ES6 Number statics required before):\n    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n  ).split(','), function(key){\n    if(has(Base, key) && !has($Number, key)){\n      $.setDesc($Number, key, $.getDesc(Base, key));\n    }\n  });\n  $Number.prototype = proto;\n  proto.constructor = $Number;\n  require('./$.redefine')(global, NUMBER, $Number);\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.constructor.js\n ** module id = 235\n ** module chunks = 0\n **/","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./$.is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function(it, S){\n  if(!isObject(it))return it;\n  var fn, val;\n  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;\n  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n  throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.to-primitive.js\n ** module id = 236\n ** module chunks = 0\n **/","var $export = require('./$.export')\n  , defined = require('./$.defined')\n  , fails   = require('./$.fails')\n  , spaces  = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n      '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF'\n  , space   = '[' + spaces + ']'\n  , non     = '\\u200b\\u0085'\n  , ltrim   = RegExp('^' + space + space + '*')\n  , rtrim   = RegExp(space + space + '*$');\n\nvar exporter = function(KEY, exec){\n  var exp  = {};\n  exp[KEY] = exec(trim);\n  $export($export.P + $export.F * fails(function(){\n    return !!spaces[KEY]() || non[KEY]() != non;\n  }), 'String', exp);\n};\n\n// 1 -> String#trimLeft\n// 2 -> String#trimRight\n// 3 -> String#trim\nvar trim = exporter.trim = function(string, TYPE){\n  string = String(defined(string));\n  if(TYPE & 1)string = string.replace(ltrim, '');\n  if(TYPE & 2)string = string.replace(rtrim, '');\n  return string;\n};\n\nmodule.exports = exporter;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.string-trim.js\n ** module id = 237\n ** module chunks = 0\n **/","// 20.1.2.1 Number.EPSILON\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.epsilon.js\n ** module id = 238\n ** module chunks = 0\n **/","// 20.1.2.2 Number.isFinite(number)\nvar $export   = require('./$.export')\n  , _isFinite = require('./$.global').isFinite;\n\n$export($export.S, 'Number', {\n  isFinite: function isFinite(it){\n    return typeof it == 'number' && _isFinite(it);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.is-finite.js\n ** module id = 239\n ** module chunks = 0\n **/","// 20.1.2.3 Number.isInteger(number)\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {isInteger: require('./$.is-integer')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.is-integer.js\n ** module id = 240\n ** module chunks = 0\n **/","// 20.1.2.3 Number.isInteger(number)\nvar isObject = require('./$.is-object')\n  , floor    = Math.floor;\nmodule.exports = function isInteger(it){\n  return !isObject(it) && isFinite(it) && floor(it) === it;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.is-integer.js\n ** module id = 241\n ** module chunks = 0\n **/","// 20.1.2.4 Number.isNaN(number)\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {\n  isNaN: function isNaN(number){\n    return number != number;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.is-nan.js\n ** module id = 242\n ** module chunks = 0\n **/","// 20.1.2.5 Number.isSafeInteger(number)\nvar $export   = require('./$.export')\n  , isInteger = require('./$.is-integer')\n  , abs       = Math.abs;\n\n$export($export.S, 'Number', {\n  isSafeInteger: function isSafeInteger(number){\n    return isInteger(number) && abs(number) <= 0x1fffffffffffff;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.is-safe-integer.js\n ** module id = 243\n ** module chunks = 0\n **/","// 20.1.2.6 Number.MAX_SAFE_INTEGER\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.max-safe-integer.js\n ** module id = 244\n ** module chunks = 0\n **/","// 20.1.2.10 Number.MIN_SAFE_INTEGER\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.min-safe-integer.js\n ** module id = 245\n ** module chunks = 0\n **/","// 20.1.2.12 Number.parseFloat(string)\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {parseFloat: parseFloat});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.parse-float.js\n ** module id = 246\n ** module chunks = 0\n **/","// 20.1.2.13 Number.parseInt(string, radix)\nvar $export = require('./$.export');\n\n$export($export.S, 'Number', {parseInt: parseInt});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.number.parse-int.js\n ** module id = 247\n ** module chunks = 0\n **/","// 20.2.2.3 Math.acosh(x)\nvar $export = require('./$.export')\n  , log1p   = require('./$.math-log1p')\n  , sqrt    = Math.sqrt\n  , $acosh  = Math.acosh;\n\n// V8 bug https://code.google.com/p/v8/issues/detail?id=3509\n$export($export.S + $export.F * !($acosh && Math.floor($acosh(Number.MAX_VALUE)) == 710), 'Math', {\n  acosh: function acosh(x){\n    return (x = +x) < 1 ? NaN : x > 94906265.62425156\n      ? Math.log(x) + Math.LN2\n      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.acosh.js\n ** module id = 248\n ** module chunks = 0\n **/","// 20.2.2.20 Math.log1p(x)\nmodule.exports = Math.log1p || function log1p(x){\n  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.math-log1p.js\n ** module id = 249\n ** module chunks = 0\n **/","// 20.2.2.5 Math.asinh(x)\nvar $export = require('./$.export');\n\nfunction asinh(x){\n  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));\n}\n\n$export($export.S, 'Math', {asinh: asinh});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.asinh.js\n ** module id = 250\n ** module chunks = 0\n **/","// 20.2.2.7 Math.atanh(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {\n  atanh: function atanh(x){\n    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.atanh.js\n ** module id = 251\n ** module chunks = 0\n **/","// 20.2.2.9 Math.cbrt(x)\nvar $export = require('./$.export')\n  , sign    = require('./$.math-sign');\n\n$export($export.S, 'Math', {\n  cbrt: function cbrt(x){\n    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.cbrt.js\n ** module id = 252\n ** module chunks = 0\n **/","// 20.2.2.28 Math.sign(x)\nmodule.exports = Math.sign || function sign(x){\n  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.math-sign.js\n ** module id = 253\n ** module chunks = 0\n **/","// 20.2.2.11 Math.clz32(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {\n  clz32: function clz32(x){\n    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.clz32.js\n ** module id = 254\n ** module chunks = 0\n **/","// 20.2.2.12 Math.cosh(x)\nvar $export = require('./$.export')\n  , exp     = Math.exp;\n\n$export($export.S, 'Math', {\n  cosh: function cosh(x){\n    return (exp(x = +x) + exp(-x)) / 2;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.cosh.js\n ** module id = 255\n ** module chunks = 0\n **/","// 20.2.2.14 Math.expm1(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {expm1: require('./$.math-expm1')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.expm1.js\n ** module id = 256\n ** module chunks = 0\n **/","// 20.2.2.14 Math.expm1(x)\nmodule.exports = Math.expm1 || function expm1(x){\n  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.math-expm1.js\n ** module id = 257\n ** module chunks = 0\n **/","// 20.2.2.16 Math.fround(x)\nvar $export   = require('./$.export')\n  , sign      = require('./$.math-sign')\n  , pow       = Math.pow\n  , EPSILON   = pow(2, -52)\n  , EPSILON32 = pow(2, -23)\n  , MAX32     = pow(2, 127) * (2 - EPSILON32)\n  , MIN32     = pow(2, -126);\n\nvar roundTiesToEven = function(n){\n  return n + 1 / EPSILON - 1 / EPSILON;\n};\n\n\n$export($export.S, 'Math', {\n  fround: function fround(x){\n    var $abs  = Math.abs(x)\n      , $sign = sign(x)\n      , a, result;\n    if($abs < MIN32)return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;\n    a = (1 + EPSILON32 / EPSILON) * $abs;\n    result = a - (a - $abs);\n    if(result > MAX32 || result != result)return $sign * Infinity;\n    return $sign * result;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.fround.js\n ** module id = 258\n ** module chunks = 0\n **/","// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])\nvar $export = require('./$.export')\n  , abs     = Math.abs;\n\n$export($export.S, 'Math', {\n  hypot: function hypot(value1, value2){ // eslint-disable-line no-unused-vars\n    var sum   = 0\n      , i     = 0\n      , $$    = arguments\n      , $$len = $$.length\n      , larg  = 0\n      , arg, div;\n    while(i < $$len){\n      arg = abs($$[i++]);\n      if(larg < arg){\n        div  = larg / arg;\n        sum  = sum * div * div + 1;\n        larg = arg;\n      } else if(arg > 0){\n        div  = arg / larg;\n        sum += div * div;\n      } else sum += arg;\n    }\n    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.hypot.js\n ** module id = 259\n ** module chunks = 0\n **/","// 20.2.2.18 Math.imul(x, y)\nvar $export = require('./$.export')\n  , $imul   = Math.imul;\n\n// some WebKit versions fails with big numbers, some has wrong arity\n$export($export.S + $export.F * require('./$.fails')(function(){\n  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;\n}), 'Math', {\n  imul: function imul(x, y){\n    var UINT16 = 0xffff\n      , xn = +x\n      , yn = +y\n      , xl = UINT16 & xn\n      , yl = UINT16 & yn;\n    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.imul.js\n ** module id = 260\n ** module chunks = 0\n **/","// 20.2.2.21 Math.log10(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {\n  log10: function log10(x){\n    return Math.log(x) / Math.LN10;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.log10.js\n ** module id = 261\n ** module chunks = 0\n **/","// 20.2.2.20 Math.log1p(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {log1p: require('./$.math-log1p')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.log1p.js\n ** module id = 262\n ** module chunks = 0\n **/","// 20.2.2.22 Math.log2(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {\n  log2: function log2(x){\n    return Math.log(x) / Math.LN2;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.log2.js\n ** module id = 263\n ** module chunks = 0\n **/","// 20.2.2.28 Math.sign(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {sign: require('./$.math-sign')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.sign.js\n ** module id = 264\n ** module chunks = 0\n **/","// 20.2.2.30 Math.sinh(x)\nvar $export = require('./$.export')\n  , expm1   = require('./$.math-expm1')\n  , exp     = Math.exp;\n\n// V8 near Chromium 38 has a problem with very small numbers\n$export($export.S + $export.F * require('./$.fails')(function(){\n  return !Math.sinh(-2e-17) != -2e-17;\n}), 'Math', {\n  sinh: function sinh(x){\n    return Math.abs(x = +x) < 1\n      ? (expm1(x) - expm1(-x)) / 2\n      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.sinh.js\n ** module id = 265\n ** module chunks = 0\n **/","// 20.2.2.33 Math.tanh(x)\nvar $export = require('./$.export')\n  , expm1   = require('./$.math-expm1')\n  , exp     = Math.exp;\n\n$export($export.S, 'Math', {\n  tanh: function tanh(x){\n    var a = expm1(x = +x)\n      , b = expm1(-x);\n    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.tanh.js\n ** module id = 266\n ** module chunks = 0\n **/","// 20.2.2.34 Math.trunc(x)\nvar $export = require('./$.export');\n\n$export($export.S, 'Math', {\n  trunc: function trunc(it){\n    return (it > 0 ? Math.floor : Math.ceil)(it);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.math.trunc.js\n ** module id = 267\n ** module chunks = 0\n **/","var $export        = require('./$.export')\n  , toIndex        = require('./$.to-index')\n  , fromCharCode   = String.fromCharCode\n  , $fromCodePoint = String.fromCodePoint;\n\n// length should be 1, old FF problem\n$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {\n  // 21.1.2.2 String.fromCodePoint(...codePoints)\n  fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars\n    var res   = []\n      , $$    = arguments\n      , $$len = $$.length\n      , i     = 0\n      , code;\n    while($$len > i){\n      code = +$$[i++];\n      if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point');\n      res.push(code < 0x10000\n        ? fromCharCode(code)\n        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)\n      );\n    } return res.join('');\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.from-code-point.js\n ** module id = 268\n ** module chunks = 0\n **/","var $export   = require('./$.export')\n  , toIObject = require('./$.to-iobject')\n  , toLength  = require('./$.to-length');\n\n$export($export.S, 'String', {\n  // 21.1.2.4 String.raw(callSite, ...substitutions)\n  raw: function raw(callSite){\n    var tpl   = toIObject(callSite.raw)\n      , len   = toLength(tpl.length)\n      , $$    = arguments\n      , $$len = $$.length\n      , res   = []\n      , i     = 0;\n    while(len > i){\n      res.push(String(tpl[i++]));\n      if(i < $$len)res.push(String($$[i]));\n    } return res.join('');\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.raw.js\n ** module id = 269\n ** module chunks = 0\n **/","'use strict';\n// 21.1.3.25 String.prototype.trim()\nrequire('./$.string-trim')('trim', function($trim){\n  return function trim(){\n    return $trim(this, 3);\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.trim.js\n ** module id = 270\n ** module chunks = 0\n **/","'use strict';\nvar $at  = require('./$.string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./$.iter-define')(String, 'String', function(iterated){\n  this._t = String(iterated); // target\n  this._i = 0;                // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function(){\n  var O     = this._t\n    , index = this._i\n    , point;\n  if(index >= O.length)return {value: undefined, done: true};\n  point = $at(O, index);\n  this._i += point.length;\n  return {value: point, done: false};\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.iterator.js\n ** module id = 271\n ** module chunks = 0\n **/","var toInteger = require('./$.to-integer')\n  , defined   = require('./$.defined');\n// true  -> String#at\n// false -> String#codePointAt\nmodule.exports = function(TO_STRING){\n  return function(that, pos){\n    var s = String(defined(that))\n      , i = toInteger(pos)\n      , l = s.length\n      , a, b;\n    if(i < 0 || i >= l)return TO_STRING ? '' : undefined;\n    a = s.charCodeAt(i);\n    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n      ? TO_STRING ? s.charAt(i) : a\n      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.string-at.js\n ** module id = 272\n ** module chunks = 0\n **/","'use strict';\nvar LIBRARY        = require('./$.library')\n  , $export        = require('./$.export')\n  , redefine       = require('./$.redefine')\n  , hide           = require('./$.hide')\n  , has            = require('./$.has')\n  , Iterators      = require('./$.iterators')\n  , $iterCreate    = require('./$.iter-create')\n  , setToStringTag = require('./$.set-to-string-tag')\n  , getProto       = require('./$').getProto\n  , ITERATOR       = require('./$.wks')('iterator')\n  , BUGGY          = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`\n  , FF_ITERATOR    = '@@iterator'\n  , KEYS           = 'keys'\n  , VALUES         = 'values';\n\nvar returnThis = function(){ return this; };\n\nmodule.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){\n  $iterCreate(Constructor, NAME, next);\n  var getMethod = function(kind){\n    if(!BUGGY && kind in proto)return proto[kind];\n    switch(kind){\n      case KEYS: return function keys(){ return new Constructor(this, kind); };\n      case VALUES: return function values(){ return new Constructor(this, kind); };\n    } return function entries(){ return new Constructor(this, kind); };\n  };\n  var TAG        = NAME + ' Iterator'\n    , DEF_VALUES = DEFAULT == VALUES\n    , VALUES_BUG = false\n    , proto      = Base.prototype\n    , $native    = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]\n    , $default   = $native || getMethod(DEFAULT)\n    , methods, key;\n  // Fix native\n  if($native){\n    var IteratorPrototype = getProto($default.call(new Base));\n    // Set @@toStringTag to native iterators\n    setToStringTag(IteratorPrototype, TAG, true);\n    // FF fix\n    if(!LIBRARY && has(proto, FF_ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);\n    // fix Array#{values, @@iterator}.name in V8 / FF\n    if(DEF_VALUES && $native.name !== VALUES){\n      VALUES_BUG = true;\n      $default = function values(){ return $native.call(this); };\n    }\n  }\n  // Define iterator\n  if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){\n    hide(proto, ITERATOR, $default);\n  }\n  // Plug for library\n  Iterators[NAME] = $default;\n  Iterators[TAG]  = returnThis;\n  if(DEFAULT){\n    methods = {\n      values:  DEF_VALUES  ? $default : getMethod(VALUES),\n      keys:    IS_SET      ? $default : getMethod(KEYS),\n      entries: !DEF_VALUES ? $default : getMethod('entries')\n    };\n    if(FORCED)for(key in methods){\n      if(!(key in proto))redefine(proto, key, methods[key]);\n    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n  }\n  return methods;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iter-define.js\n ** module id = 273\n ** module chunks = 0\n **/","module.exports = {};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iterators.js\n ** module id = 274\n ** module chunks = 0\n **/","'use strict';\nvar $              = require('./$')\n  , descriptor     = require('./$.property-desc')\n  , setToStringTag = require('./$.set-to-string-tag')\n  , IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./$.hide')(IteratorPrototype, require('./$.wks')('iterator'), function(){ return this; });\n\nmodule.exports = function(Constructor, NAME, next){\n  Constructor.prototype = $.create(IteratorPrototype, {next: descriptor(1, next)});\n  setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iter-create.js\n ** module id = 275\n ** module chunks = 0\n **/","'use strict';\nvar $export = require('./$.export')\n  , $at     = require('./$.string-at')(false);\n$export($export.P, 'String', {\n  // 21.1.3.3 String.prototype.codePointAt(pos)\n  codePointAt: function codePointAt(pos){\n    return $at(this, pos);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.code-point-at.js\n ** module id = 276\n ** module chunks = 0\n **/","// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])\n'use strict';\nvar $export   = require('./$.export')\n  , toLength  = require('./$.to-length')\n  , context   = require('./$.string-context')\n  , ENDS_WITH = 'endsWith'\n  , $endsWith = ''[ENDS_WITH];\n\n$export($export.P + $export.F * require('./$.fails-is-regexp')(ENDS_WITH), 'String', {\n  endsWith: function endsWith(searchString /*, endPosition = @length */){\n    var that = context(this, searchString, ENDS_WITH)\n      , $$   = arguments\n      , endPosition = $$.length > 1 ? $$[1] : undefined\n      , len    = toLength(that.length)\n      , end    = endPosition === undefined ? len : Math.min(toLength(endPosition), len)\n      , search = String(searchString);\n    return $endsWith\n      ? $endsWith.call(that, search, end)\n      : that.slice(end - search.length, end) === search;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.ends-with.js\n ** module id = 277\n ** module chunks = 0\n **/","// helper for String#{startsWith, endsWith, includes}\nvar isRegExp = require('./$.is-regexp')\n  , defined  = require('./$.defined');\n\nmodule.exports = function(that, searchString, NAME){\n  if(isRegExp(searchString))throw TypeError('String#' + NAME + \" doesn't accept regex!\");\n  return String(defined(that));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.string-context.js\n ** module id = 278\n ** module chunks = 0\n **/","// 7.2.8 IsRegExp(argument)\nvar isObject = require('./$.is-object')\n  , cof      = require('./$.cof')\n  , MATCH    = require('./$.wks')('match');\nmodule.exports = function(it){\n  var isRegExp;\n  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.is-regexp.js\n ** module id = 279\n ** module chunks = 0\n **/","var MATCH = require('./$.wks')('match');\nmodule.exports = function(KEY){\n  var re = /./;\n  try {\n    '/./'[KEY](re);\n  } catch(e){\n    try {\n      re[MATCH] = false;\n      return !'/./'[KEY](re);\n    } catch(f){ /* empty */ }\n  } return true;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.fails-is-regexp.js\n ** module id = 280\n ** module chunks = 0\n **/","// 21.1.3.7 String.prototype.includes(searchString, position = 0)\n'use strict';\nvar $export  = require('./$.export')\n  , context  = require('./$.string-context')\n  , INCLUDES = 'includes';\n\n$export($export.P + $export.F * require('./$.fails-is-regexp')(INCLUDES), 'String', {\n  includes: function includes(searchString /*, position = 0 */){\n    return !!~context(this, searchString, INCLUDES)\n      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.includes.js\n ** module id = 281\n ** module chunks = 0\n **/","var $export = require('./$.export');\n\n$export($export.P, 'String', {\n  // 21.1.3.13 String.prototype.repeat(count)\n  repeat: require('./$.string-repeat')\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.repeat.js\n ** module id = 282\n ** module chunks = 0\n **/","'use strict';\nvar toInteger = require('./$.to-integer')\n  , defined   = require('./$.defined');\n\nmodule.exports = function repeat(count){\n  var str = String(defined(this))\n    , res = ''\n    , n   = toInteger(count);\n  if(n < 0 || n == Infinity)throw RangeError(\"Count can't be negative\");\n  for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str;\n  return res;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.string-repeat.js\n ** module id = 283\n ** module chunks = 0\n **/","// 21.1.3.18 String.prototype.startsWith(searchString [, position ])\n'use strict';\nvar $export     = require('./$.export')\n  , toLength    = require('./$.to-length')\n  , context     = require('./$.string-context')\n  , STARTS_WITH = 'startsWith'\n  , $startsWith = ''[STARTS_WITH];\n\n$export($export.P + $export.F * require('./$.fails-is-regexp')(STARTS_WITH), 'String', {\n  startsWith: function startsWith(searchString /*, position = 0 */){\n    var that   = context(this, searchString, STARTS_WITH)\n      , $$     = arguments\n      , index  = toLength(Math.min($$.length > 1 ? $$[1] : undefined, that.length))\n      , search = String(searchString);\n    return $startsWith\n      ? $startsWith.call(that, search, index)\n      : that.slice(index, index + search.length) === search;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.string.starts-with.js\n ** module id = 284\n ** module chunks = 0\n **/","'use strict';\nvar ctx         = require('./$.ctx')\n  , $export     = require('./$.export')\n  , toObject    = require('./$.to-object')\n  , call        = require('./$.iter-call')\n  , isArrayIter = require('./$.is-array-iter')\n  , toLength    = require('./$.to-length')\n  , getIterFn   = require('./core.get-iterator-method');\n$export($export.S + $export.F * !require('./$.iter-detect')(function(iter){ Array.from(iter); }), 'Array', {\n  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)\n  from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){\n    var O       = toObject(arrayLike)\n      , C       = typeof this == 'function' ? this : Array\n      , $$      = arguments\n      , $$len   = $$.length\n      , mapfn   = $$len > 1 ? $$[1] : undefined\n      , mapping = mapfn !== undefined\n      , index   = 0\n      , iterFn  = getIterFn(O)\n      , length, result, step, iterator;\n    if(mapping)mapfn = ctx(mapfn, $$len > 2 ? $$[2] : undefined, 2);\n    // if object isn't iterable or it's array with default iterator - use simple case\n    if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){\n      for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){\n        result[index] = mapping ? call(iterator, mapfn, [step.value, index], true) : step.value;\n      }\n    } else {\n      length = toLength(O.length);\n      for(result = new C(length); length > index; index++){\n        result[index] = mapping ? mapfn(O[index], index) : O[index];\n      }\n    }\n    result.length = index;\n    return result;\n  }\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.from.js\n ** module id = 285\n ** module chunks = 0\n **/","// call something on iterator step with safe closing on error\nvar anObject = require('./$.an-object');\nmodule.exports = function(iterator, fn, value, entries){\n  try {\n    return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n  // 7.4.6 IteratorClose(iterator, completion)\n  } catch(e){\n    var ret = iterator['return'];\n    if(ret !== undefined)anObject(ret.call(iterator));\n    throw e;\n  }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iter-call.js\n ** module id = 286\n ** module chunks = 0\n **/","// check on default Array iterator\nvar Iterators  = require('./$.iterators')\n  , ITERATOR   = require('./$.wks')('iterator')\n  , ArrayProto = Array.prototype;\n\nmodule.exports = function(it){\n  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.is-array-iter.js\n ** module id = 287\n ** module chunks = 0\n **/","var classof   = require('./$.classof')\n  , ITERATOR  = require('./$.wks')('iterator')\n  , Iterators = require('./$.iterators');\nmodule.exports = require('./$.core').getIteratorMethod = function(it){\n  if(it != undefined)return it[ITERATOR]\n    || it['@@iterator']\n    || Iterators[classof(it)];\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/core.get-iterator-method.js\n ** module id = 288\n ** module chunks = 0\n **/","var ITERATOR     = require('./$.wks')('iterator')\n  , SAFE_CLOSING = false;\n\ntry {\n  var riter = [7][ITERATOR]();\n  riter['return'] = function(){ SAFE_CLOSING = true; };\n  Array.from(riter, function(){ throw 2; });\n} catch(e){ /* empty */ }\n\nmodule.exports = function(exec, skipClosing){\n  if(!skipClosing && !SAFE_CLOSING)return false;\n  var safe = false;\n  try {\n    var arr  = [7]\n      , iter = arr[ITERATOR]();\n    iter.next = function(){ safe = true; };\n    arr[ITERATOR] = function(){ return iter; };\n    exec(arr);\n  } catch(e){ /* empty */ }\n  return safe;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iter-detect.js\n ** module id = 289\n ** module chunks = 0\n **/","'use strict';\nvar $export = require('./$.export');\n\n// WebKit Array.of isn't generic\n$export($export.S + $export.F * require('./$.fails')(function(){\n  function F(){}\n  return !(Array.of.call(F) instanceof F);\n}), 'Array', {\n  // 22.1.2.3 Array.of( ...items)\n  of: function of(/* ...args */){\n    var index  = 0\n      , $$     = arguments\n      , $$len  = $$.length\n      , result = new (typeof this == 'function' ? this : Array)($$len);\n    while($$len > index)result[index] = $$[index++];\n    result.length = $$len;\n    return result;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.of.js\n ** module id = 290\n ** module chunks = 0\n **/","'use strict';\nvar addToUnscopables = require('./$.add-to-unscopables')\n  , step             = require('./$.iter-step')\n  , Iterators        = require('./$.iterators')\n  , toIObject        = require('./$.to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./$.iter-define')(Array, 'Array', function(iterated, kind){\n  this._t = toIObject(iterated); // target\n  this._i = 0;                   // next index\n  this._k = kind;                // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function(){\n  var O     = this._t\n    , kind  = this._k\n    , index = this._i++;\n  if(!O || index >= O.length){\n    this._t = undefined;\n    return step(1);\n  }\n  if(kind == 'keys'  )return step(0, index);\n  if(kind == 'values')return step(0, O[index]);\n  return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.iterator.js\n ** module id = 291\n ** module chunks = 0\n **/","// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = require('./$.wks')('unscopables')\n  , ArrayProto  = Array.prototype;\nif(ArrayProto[UNSCOPABLES] == undefined)require('./$.hide')(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function(key){\n  ArrayProto[UNSCOPABLES][key] = true;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.add-to-unscopables.js\n ** module id = 292\n ** module chunks = 0\n **/","module.exports = function(done, value){\n  return {value: value, done: !!done};\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.iter-step.js\n ** module id = 293\n ** module chunks = 0\n **/","require('./$.set-species')('Array');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.species.js\n ** module id = 294\n ** module chunks = 0\n **/","'use strict';\nvar global      = require('./$.global')\n  , $           = require('./$')\n  , DESCRIPTORS = require('./$.descriptors')\n  , SPECIES     = require('./$.wks')('species');\n\nmodule.exports = function(KEY){\n  var C = global[KEY];\n  if(DESCRIPTORS && C && !C[SPECIES])$.setDesc(C, SPECIES, {\n    configurable: true,\n    get: function(){ return this; }\n  });\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.set-species.js\n ** module id = 295\n ** module chunks = 0\n **/","// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)\nvar $export = require('./$.export');\n\n$export($export.P, 'Array', {copyWithin: require('./$.array-copy-within')});\n\nrequire('./$.add-to-unscopables')('copyWithin');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.copy-within.js\n ** module id = 296\n ** module chunks = 0\n **/","// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)\n'use strict';\nvar toObject = require('./$.to-object')\n  , toIndex  = require('./$.to-index')\n  , toLength = require('./$.to-length');\n\nmodule.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){\n  var O     = toObject(this)\n    , len   = toLength(O.length)\n    , to    = toIndex(target, len)\n    , from  = toIndex(start, len)\n    , $$    = arguments\n    , end   = $$.length > 2 ? $$[2] : undefined\n    , count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to)\n    , inc   = 1;\n  if(from < to && to < from + count){\n    inc  = -1;\n    from += count - 1;\n    to   += count - 1;\n  }\n  while(count-- > 0){\n    if(from in O)O[to] = O[from];\n    else delete O[to];\n    to   += inc;\n    from += inc;\n  } return O;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.array-copy-within.js\n ** module id = 297\n ** module chunks = 0\n **/","// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)\nvar $export = require('./$.export');\n\n$export($export.P, 'Array', {fill: require('./$.array-fill')});\n\nrequire('./$.add-to-unscopables')('fill');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.fill.js\n ** module id = 298\n ** module chunks = 0\n **/","// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)\n'use strict';\nvar toObject = require('./$.to-object')\n  , toIndex  = require('./$.to-index')\n  , toLength = require('./$.to-length');\nmodule.exports = [].fill || function fill(value /*, start = 0, end = @length */){\n  var O      = toObject(this)\n    , length = toLength(O.length)\n    , $$     = arguments\n    , $$len  = $$.length\n    , index  = toIndex($$len > 1 ? $$[1] : undefined, length)\n    , end    = $$len > 2 ? $$[2] : undefined\n    , endPos = end === undefined ? length : toIndex(end, length);\n  while(endPos > index)O[index++] = value;\n  return O;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.array-fill.js\n ** module id = 299\n ** module chunks = 0\n **/","'use strict';\n// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)\nvar $export = require('./$.export')\n  , $find   = require('./$.array-methods')(5)\n  , KEY     = 'find'\n  , forced  = true;\n// Shouldn't skip holes\nif(KEY in [])Array(1)[KEY](function(){ forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  find: function find(callbackfn/*, that = undefined */){\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\nrequire('./$.add-to-unscopables')(KEY);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.find.js\n ** module id = 300\n ** module chunks = 0\n **/","'use strict';\n// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)\nvar $export = require('./$.export')\n  , $find   = require('./$.array-methods')(6)\n  , KEY     = 'findIndex'\n  , forced  = true;\n// Shouldn't skip holes\nif(KEY in [])Array(1)[KEY](function(){ forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  findIndex: function findIndex(callbackfn/*, that = undefined */){\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\nrequire('./$.add-to-unscopables')(KEY);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.array.find-index.js\n ** module id = 301\n ** module chunks = 0\n **/","var $        = require('./$')\n  , global   = require('./$.global')\n  , isRegExp = require('./$.is-regexp')\n  , $flags   = require('./$.flags')\n  , $RegExp  = global.RegExp\n  , Base     = $RegExp\n  , proto    = $RegExp.prototype\n  , re1      = /a/g\n  , re2      = /a/g\n  // \"new\" creates a new object, old webkit buggy here\n  , CORRECT_NEW = new $RegExp(re1) !== re1;\n\nif(require('./$.descriptors') && (!CORRECT_NEW || require('./$.fails')(function(){\n  re2[require('./$.wks')('match')] = false;\n  // RegExp constructor can alter flags and IsRegExp works correct with @@match\n  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';\n}))){\n  $RegExp = function RegExp(p, f){\n    var piRE = isRegExp(p)\n      , fiU  = f === undefined;\n    return !(this instanceof $RegExp) && piRE && p.constructor === $RegExp && fiU ? p\n      : CORRECT_NEW\n        ? new Base(piRE && !fiU ? p.source : p, f)\n        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f);\n  };\n  $.each.call($.getNames(Base), function(key){\n    key in $RegExp || $.setDesc($RegExp, key, {\n      configurable: true,\n      get: function(){ return Base[key]; },\n      set: function(it){ Base[key] = it; }\n    });\n  });\n  proto.constructor = $RegExp;\n  $RegExp.prototype = proto;\n  require('./$.redefine')(global, 'RegExp', $RegExp);\n}\n\nrequire('./$.set-species')('RegExp');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.regexp.constructor.js\n ** module id = 302\n ** module chunks = 0\n **/","'use strict';\n// 21.2.5.3 get RegExp.prototype.flags\nvar anObject = require('./$.an-object');\nmodule.exports = function(){\n  var that   = anObject(this)\n    , result = '';\n  if(that.global)     result += 'g';\n  if(that.ignoreCase) result += 'i';\n  if(that.multiline)  result += 'm';\n  if(that.unicode)    result += 'u';\n  if(that.sticky)     result += 'y';\n  return result;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.flags.js\n ** module id = 303\n ** module chunks = 0\n **/","// 21.2.5.3 get RegExp.prototype.flags()\nvar $ = require('./$');\nif(require('./$.descriptors') && /./g.flags != 'g')$.setDesc(RegExp.prototype, 'flags', {\n  configurable: true,\n  get: require('./$.flags')\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.regexp.flags.js\n ** module id = 304\n ** module chunks = 0\n **/","// @@match logic\nrequire('./$.fix-re-wks')('match', 1, function(defined, MATCH){\n  // 21.1.3.11 String.prototype.match(regexp)\n  return function match(regexp){\n    'use strict';\n    var O  = defined(this)\n      , fn = regexp == undefined ? undefined : regexp[MATCH];\n    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.regexp.match.js\n ** module id = 305\n ** module chunks = 0\n **/","'use strict';\nvar hide     = require('./$.hide')\n  , redefine = require('./$.redefine')\n  , fails    = require('./$.fails')\n  , defined  = require('./$.defined')\n  , wks      = require('./$.wks');\n\nmodule.exports = function(KEY, length, exec){\n  var SYMBOL   = wks(KEY)\n    , original = ''[KEY];\n  if(fails(function(){\n    var O = {};\n    O[SYMBOL] = function(){ return 7; };\n    return ''[KEY](O) != 7;\n  })){\n    redefine(String.prototype, KEY, exec(defined, SYMBOL, original));\n    hide(RegExp.prototype, SYMBOL, length == 2\n      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n      // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n      ? function(string, arg){ return original.call(string, this, arg); }\n      // 21.2.5.6 RegExp.prototype[@@match](string)\n      // 21.2.5.9 RegExp.prototype[@@search](string)\n      : function(string){ return original.call(string, this); }\n    );\n  }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.fix-re-wks.js\n ** module id = 306\n ** module chunks = 0\n **/","// @@replace logic\nrequire('./$.fix-re-wks')('replace', 2, function(defined, REPLACE, $replace){\n  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)\n  return function replace(searchValue, replaceValue){\n    'use strict';\n    var O  = defined(this)\n      , fn = searchValue == undefined ? undefined : searchValue[REPLACE];\n    return fn !== undefined\n      ? fn.call(searchValue, O, replaceValue)\n      : $replace.call(String(O), searchValue, replaceValue);\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.regexp.replace.js\n ** module id = 307\n ** module chunks = 0\n **/","// @@search logic\nrequire('./$.fix-re-wks')('search', 1, function(defined, SEARCH){\n  // 21.1.3.15 String.prototype.search(regexp)\n  return function search(regexp){\n    'use strict';\n    var O  = defined(this)\n      , fn = regexp == undefined ? undefined : regexp[SEARCH];\n    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.regexp.search.js\n ** module id = 308\n ** module chunks = 0\n **/","// @@split logic\nrequire('./$.fix-re-wks')('split', 2, function(defined, SPLIT, $split){\n  // 21.1.3.17 String.prototype.split(separator, limit)\n  return function split(separator, limit){\n    'use strict';\n    var O  = defined(this)\n      , fn = separator == undefined ? undefined : separator[SPLIT];\n    return fn !== undefined\n      ? fn.call(separator, O, limit)\n      : $split.call(String(O), separator, limit);\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.regexp.split.js\n ** module id = 309\n ** module chunks = 0\n **/","'use strict';\nvar $          = require('./$')\n  , LIBRARY    = require('./$.library')\n  , global     = require('./$.global')\n  , ctx        = require('./$.ctx')\n  , classof    = require('./$.classof')\n  , $export    = require('./$.export')\n  , isObject   = require('./$.is-object')\n  , anObject   = require('./$.an-object')\n  , aFunction  = require('./$.a-function')\n  , strictNew  = require('./$.strict-new')\n  , forOf      = require('./$.for-of')\n  , setProto   = require('./$.set-proto').set\n  , same       = require('./$.same-value')\n  , SPECIES    = require('./$.wks')('species')\n  , speciesConstructor = require('./$.species-constructor')\n  , asap       = require('./$.microtask')\n  , PROMISE    = 'Promise'\n  , process    = global.process\n  , isNode     = classof(process) == 'process'\n  , P          = global[PROMISE]\n  , Wrapper;\n\nvar testResolve = function(sub){\n  var test = new P(function(){});\n  if(sub)test.constructor = Object;\n  return P.resolve(test) === test;\n};\n\nvar USE_NATIVE = function(){\n  var works = false;\n  function P2(x){\n    var self = new P(x);\n    setProto(self, P2.prototype);\n    return self;\n  }\n  try {\n    works = P && P.resolve && testResolve();\n    setProto(P2, P);\n    P2.prototype = $.create(P.prototype, {constructor: {value: P2}});\n    // actual Firefox has broken subclass support, test that\n    if(!(P2.resolve(5).then(function(){}) instanceof P2)){\n      works = false;\n    }\n    // actual V8 bug, https://code.google.com/p/v8/issues/detail?id=4162\n    if(works && require('./$.descriptors')){\n      var thenableThenGotten = false;\n      P.resolve($.setDesc({}, 'then', {\n        get: function(){ thenableThenGotten = true; }\n      }));\n      works = thenableThenGotten;\n    }\n  } catch(e){ works = false; }\n  return works;\n}();\n\n// helpers\nvar sameConstructor = function(a, b){\n  // library wrapper special case\n  if(LIBRARY && a === P && b === Wrapper)return true;\n  return same(a, b);\n};\nvar getConstructor = function(C){\n  var S = anObject(C)[SPECIES];\n  return S != undefined ? S : C;\n};\nvar isThenable = function(it){\n  var then;\n  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar PromiseCapability = function(C){\n  var resolve, reject;\n  this.promise = new C(function($$resolve, $$reject){\n    if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');\n    resolve = $$resolve;\n    reject  = $$reject;\n  });\n  this.resolve = aFunction(resolve),\n  this.reject  = aFunction(reject)\n};\nvar perform = function(exec){\n  try {\n    exec();\n  } catch(e){\n    return {error: e};\n  }\n};\nvar notify = function(record, isReject){\n  if(record.n)return;\n  record.n = true;\n  var chain = record.c;\n  asap(function(){\n    var value = record.v\n      , ok    = record.s == 1\n      , i     = 0;\n    var run = function(reaction){\n      var handler = ok ? reaction.ok : reaction.fail\n        , resolve = reaction.resolve\n        , reject  = reaction.reject\n        , result, then;\n      try {\n        if(handler){\n          if(!ok)record.h = true;\n          result = handler === true ? value : handler(value);\n          if(result === reaction.promise){\n            reject(TypeError('Promise-chain cycle'));\n          } else if(then = isThenable(result)){\n            then.call(result, resolve, reject);\n          } else resolve(result);\n        } else reject(value);\n      } catch(e){\n        reject(e);\n      }\n    };\n    while(chain.length > i)run(chain[i++]); // variable length - can't use forEach\n    chain.length = 0;\n    record.n = false;\n    if(isReject)setTimeout(function(){\n      var promise = record.p\n        , handler, console;\n      if(isUnhandled(promise)){\n        if(isNode){\n          process.emit('unhandledRejection', value, promise);\n        } else if(handler = global.onunhandledrejection){\n          handler({promise: promise, reason: value});\n        } else if((console = global.console) && console.error){\n          console.error('Unhandled promise rejection', value);\n        }\n      } record.a = undefined;\n    }, 1);\n  });\n};\nvar isUnhandled = function(promise){\n  var record = promise._d\n    , chain  = record.a || record.c\n    , i      = 0\n    , reaction;\n  if(record.h)return false;\n  while(chain.length > i){\n    reaction = chain[i++];\n    if(reaction.fail || !isUnhandled(reaction.promise))return false;\n  } return true;\n};\nvar $reject = function(value){\n  var record = this;\n  if(record.d)return;\n  record.d = true;\n  record = record.r || record; // unwrap\n  record.v = value;\n  record.s = 2;\n  record.a = record.c.slice();\n  notify(record, true);\n};\nvar $resolve = function(value){\n  var record = this\n    , then;\n  if(record.d)return;\n  record.d = true;\n  record = record.r || record; // unwrap\n  try {\n    if(record.p === value)throw TypeError(\"Promise can't be resolved itself\");\n    if(then = isThenable(value)){\n      asap(function(){\n        var wrapper = {r: record, d: false}; // wrap\n        try {\n          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n        } catch(e){\n          $reject.call(wrapper, e);\n        }\n      });\n    } else {\n      record.v = value;\n      record.s = 1;\n      notify(record, false);\n    }\n  } catch(e){\n    $reject.call({r: record, d: false}, e); // wrap\n  }\n};\n\n// constructor polyfill\nif(!USE_NATIVE){\n  // 25.4.3.1 Promise(executor)\n  P = function Promise(executor){\n    aFunction(executor);\n    var record = this._d = {\n      p: strictNew(this, P, PROMISE),         // <- promise\n      c: [],                                  // <- awaiting reactions\n      a: undefined,                           // <- checked in isUnhandled reactions\n      s: 0,                                   // <- state\n      d: false,                               // <- done\n      v: undefined,                           // <- value\n      h: false,                               // <- handled rejection\n      n: false                                // <- notify\n    };\n    try {\n      executor(ctx($resolve, record, 1), ctx($reject, record, 1));\n    } catch(err){\n      $reject.call(record, err);\n    }\n  };\n  require('./$.redefine-all')(P.prototype, {\n    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n    then: function then(onFulfilled, onRejected){\n      var reaction = new PromiseCapability(speciesConstructor(this, P))\n        , promise  = reaction.promise\n        , record   = this._d;\n      reaction.ok   = typeof onFulfilled == 'function' ? onFulfilled : true;\n      reaction.fail = typeof onRejected == 'function' && onRejected;\n      record.c.push(reaction);\n      if(record.a)record.a.push(reaction);\n      if(record.s)notify(record, false);\n      return promise;\n    },\n    // 25.4.5.1 Promise.prototype.catch(onRejected)\n    'catch': function(onRejected){\n      return this.then(undefined, onRejected);\n    }\n  });\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: P});\nrequire('./$.set-to-string-tag')(P, PROMISE);\nrequire('./$.set-species')(PROMISE);\nWrapper = require('./$.core')[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n  // 25.4.4.5 Promise.reject(r)\n  reject: function reject(r){\n    var capability = new PromiseCapability(this)\n      , $$reject   = capability.reject;\n    $$reject(r);\n    return capability.promise;\n  }\n});\n$export($export.S + $export.F * (!USE_NATIVE || testResolve(true)), PROMISE, {\n  // 25.4.4.6 Promise.resolve(x)\n  resolve: function resolve(x){\n    // instanceof instead of internal slot check because we should fix it without replacement native Promise core\n    if(x instanceof P && sameConstructor(x.constructor, this))return x;\n    var capability = new PromiseCapability(this)\n      , $$resolve  = capability.resolve;\n    $$resolve(x);\n    return capability.promise;\n  }\n});\n$export($export.S + $export.F * !(USE_NATIVE && require('./$.iter-detect')(function(iter){\n  P.all(iter)['catch'](function(){});\n})), PROMISE, {\n  // 25.4.4.1 Promise.all(iterable)\n  all: function all(iterable){\n    var C          = getConstructor(this)\n      , capability = new PromiseCapability(C)\n      , resolve    = capability.resolve\n      , reject     = capability.reject\n      , values     = [];\n    var abrupt = perform(function(){\n      forOf(iterable, false, values.push, values);\n      var remaining = values.length\n        , results   = Array(remaining);\n      if(remaining)$.each.call(values, function(promise, index){\n        var alreadyCalled = false;\n        C.resolve(promise).then(function(value){\n          if(alreadyCalled)return;\n          alreadyCalled = true;\n          results[index] = value;\n          --remaining || resolve(results);\n        }, reject);\n      });\n      else resolve(results);\n    });\n    if(abrupt)reject(abrupt.error);\n    return capability.promise;\n  },\n  // 25.4.4.4 Promise.race(iterable)\n  race: function race(iterable){\n    var C          = getConstructor(this)\n      , capability = new PromiseCapability(C)\n      , reject     = capability.reject;\n    var abrupt = perform(function(){\n      forOf(iterable, false, function(promise){\n        C.resolve(promise).then(capability.resolve, reject);\n      });\n    });\n    if(abrupt)reject(abrupt.error);\n    return capability.promise;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.promise.js\n ** module id = 310\n ** module chunks = 0\n **/","module.exports = function(it, Constructor, name){\n  if(!(it instanceof Constructor))throw TypeError(name + \": use the 'new' operator!\");\n  return it;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.strict-new.js\n ** module id = 311\n ** module chunks = 0\n **/","var ctx         = require('./$.ctx')\n  , call        = require('./$.iter-call')\n  , isArrayIter = require('./$.is-array-iter')\n  , anObject    = require('./$.an-object')\n  , toLength    = require('./$.to-length')\n  , getIterFn   = require('./core.get-iterator-method');\nmodule.exports = function(iterable, entries, fn, that){\n  var iterFn = getIterFn(iterable)\n    , f      = ctx(fn, that, entries ? 2 : 1)\n    , index  = 0\n    , length, step, iterator;\n  if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');\n  // fast case for arrays with default iterator\n  if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){\n    entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n  } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){\n    call(iterator, f, step.value, entries);\n  }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.for-of.js\n ** module id = 312\n ** module chunks = 0\n **/","// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject  = require('./$.an-object')\n  , aFunction = require('./$.a-function')\n  , SPECIES   = require('./$.wks')('species');\nmodule.exports = function(O, D){\n  var C = anObject(O).constructor, S;\n  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.species-constructor.js\n ** module id = 313\n ** module chunks = 0\n **/","var global    = require('./$.global')\n  , macrotask = require('./$.task').set\n  , Observer  = global.MutationObserver || global.WebKitMutationObserver\n  , process   = global.process\n  , Promise   = global.Promise\n  , isNode    = require('./$.cof')(process) == 'process'\n  , head, last, notify;\n\nvar flush = function(){\n  var parent, domain, fn;\n  if(isNode && (parent = process.domain)){\n    process.domain = null;\n    parent.exit();\n  }\n  while(head){\n    domain = head.domain;\n    fn     = head.fn;\n    if(domain)domain.enter();\n    fn(); // <- currently we use it only for Promise - try / catch not required\n    if(domain)domain.exit();\n    head = head.next;\n  } last = undefined;\n  if(parent)parent.enter();\n};\n\n// Node.js\nif(isNode){\n  notify = function(){\n    process.nextTick(flush);\n  };\n// browsers with MutationObserver\n} else if(Observer){\n  var toggle = 1\n    , node   = document.createTextNode('');\n  new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new\n  notify = function(){\n    node.data = toggle = -toggle;\n  };\n// environments with maybe non-completely correct, but existent Promise\n} else if(Promise && Promise.resolve){\n  notify = function(){\n    Promise.resolve().then(flush);\n  };\n// for other environments - macrotask based on:\n// - setImmediate\n// - MessageChannel\n// - window.postMessag\n// - onreadystatechange\n// - setTimeout\n} else {\n  notify = function(){\n    // strange IE + webpack dev server bug - use .call(global)\n    macrotask.call(global, flush);\n  };\n}\n\nmodule.exports = function asap(fn){\n  var task = {fn: fn, next: undefined, domain: isNode && process.domain};\n  if(last)last.next = task;\n  if(!head){\n    head = task;\n    notify();\n  } last = task;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.microtask.js\n ** module id = 314\n ** module chunks = 0\n **/","var ctx                = require('./$.ctx')\n  , invoke             = require('./$.invoke')\n  , html               = require('./$.html')\n  , cel                = require('./$.dom-create')\n  , global             = require('./$.global')\n  , process            = global.process\n  , setTask            = global.setImmediate\n  , clearTask          = global.clearImmediate\n  , MessageChannel     = global.MessageChannel\n  , counter            = 0\n  , queue              = {}\n  , ONREADYSTATECHANGE = 'onreadystatechange'\n  , defer, channel, port;\nvar run = function(){\n  var id = +this;\n  if(queue.hasOwnProperty(id)){\n    var fn = queue[id];\n    delete queue[id];\n    fn();\n  }\n};\nvar listner = function(event){\n  run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif(!setTask || !clearTask){\n  setTask = function setImmediate(fn){\n    var args = [], i = 1;\n    while(arguments.length > i)args.push(arguments[i++]);\n    queue[++counter] = function(){\n      invoke(typeof fn == 'function' ? fn : Function(fn), args);\n    };\n    defer(counter);\n    return counter;\n  };\n  clearTask = function clearImmediate(id){\n    delete queue[id];\n  };\n  // Node.js 0.8-\n  if(require('./$.cof')(process) == 'process'){\n    defer = function(id){\n      process.nextTick(ctx(run, id, 1));\n    };\n  // Browsers with MessageChannel, includes WebWorkers\n  } else if(MessageChannel){\n    channel = new MessageChannel;\n    port    = channel.port2;\n    channel.port1.onmessage = listner;\n    defer = ctx(port.postMessage, port, 1);\n  // Browsers with postMessage, skip WebWorkers\n  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){\n    defer = function(id){\n      global.postMessage(id + '', '*');\n    };\n    global.addEventListener('message', listner, false);\n  // IE8-\n  } else if(ONREADYSTATECHANGE in cel('script')){\n    defer = function(id){\n      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){\n        html.removeChild(this);\n        run.call(id);\n      };\n    };\n  // Rest old browsers\n  } else {\n    defer = function(id){\n      setTimeout(ctx(run, id, 1), 0);\n    };\n  }\n}\nmodule.exports = {\n  set:   setTask,\n  clear: clearTask\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.task.js\n ** module id = 315\n ** module chunks = 0\n **/","var redefine = require('./$.redefine');\nmodule.exports = function(target, src){\n  for(var key in src)redefine(target, key, src[key]);\n  return target;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.redefine-all.js\n ** module id = 316\n ** module chunks = 0\n **/","'use strict';\nvar strong = require('./$.collection-strong');\n\n// 23.1 Map Objects\nrequire('./$.collection')('Map', function(get){\n  return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.1.3.6 Map.prototype.get(key)\n  get: function get(key){\n    var entry = strong.getEntry(this, key);\n    return entry && entry.v;\n  },\n  // 23.1.3.9 Map.prototype.set(key, value)\n  set: function set(key, value){\n    return strong.def(this, key === 0 ? 0 : key, value);\n  }\n}, strong, true);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.map.js\n ** module id = 317\n ** module chunks = 0\n **/","'use strict';\nvar $            = require('./$')\n  , hide         = require('./$.hide')\n  , redefineAll  = require('./$.redefine-all')\n  , ctx          = require('./$.ctx')\n  , strictNew    = require('./$.strict-new')\n  , defined      = require('./$.defined')\n  , forOf        = require('./$.for-of')\n  , $iterDefine  = require('./$.iter-define')\n  , step         = require('./$.iter-step')\n  , ID           = require('./$.uid')('id')\n  , $has         = require('./$.has')\n  , isObject     = require('./$.is-object')\n  , setSpecies   = require('./$.set-species')\n  , DESCRIPTORS  = require('./$.descriptors')\n  , isExtensible = Object.isExtensible || isObject\n  , SIZE         = DESCRIPTORS ? '_s' : 'size'\n  , id           = 0;\n\nvar fastKey = function(it, create){\n  // return primitive with prefix\n  if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n  if(!$has(it, ID)){\n    // can't set id to frozen object\n    if(!isExtensible(it))return 'F';\n    // not necessary to add id\n    if(!create)return 'E';\n    // add missing object id\n    hide(it, ID, ++id);\n  // return object id with prefix\n  } return 'O' + it[ID];\n};\n\nvar getEntry = function(that, key){\n  // fast case\n  var index = fastKey(key), entry;\n  if(index !== 'F')return that._i[index];\n  // frozen object case\n  for(entry = that._f; entry; entry = entry.n){\n    if(entry.k == key)return entry;\n  }\n};\n\nmodule.exports = {\n  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){\n    var C = wrapper(function(that, iterable){\n      strictNew(that, C, NAME);\n      that._i = $.create(null); // index\n      that._f = undefined;      // first entry\n      that._l = undefined;      // last entry\n      that[SIZE] = 0;           // size\n      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);\n    });\n    redefineAll(C.prototype, {\n      // 23.1.3.1 Map.prototype.clear()\n      // 23.2.3.2 Set.prototype.clear()\n      clear: function clear(){\n        for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){\n          entry.r = true;\n          if(entry.p)entry.p = entry.p.n = undefined;\n          delete data[entry.i];\n        }\n        that._f = that._l = undefined;\n        that[SIZE] = 0;\n      },\n      // 23.1.3.3 Map.prototype.delete(key)\n      // 23.2.3.4 Set.prototype.delete(value)\n      'delete': function(key){\n        var that  = this\n          , entry = getEntry(that, key);\n        if(entry){\n          var next = entry.n\n            , prev = entry.p;\n          delete that._i[entry.i];\n          entry.r = true;\n          if(prev)prev.n = next;\n          if(next)next.p = prev;\n          if(that._f == entry)that._f = next;\n          if(that._l == entry)that._l = prev;\n          that[SIZE]--;\n        } return !!entry;\n      },\n      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)\n      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)\n      forEach: function forEach(callbackfn /*, that = undefined */){\n        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)\n          , entry;\n        while(entry = entry ? entry.n : this._f){\n          f(entry.v, entry.k, this);\n          // revert to the last existing entry\n          while(entry && entry.r)entry = entry.p;\n        }\n      },\n      // 23.1.3.7 Map.prototype.has(key)\n      // 23.2.3.7 Set.prototype.has(value)\n      has: function has(key){\n        return !!getEntry(this, key);\n      }\n    });\n    if(DESCRIPTORS)$.setDesc(C.prototype, 'size', {\n      get: function(){\n        return defined(this[SIZE]);\n      }\n    });\n    return C;\n  },\n  def: function(that, key, value){\n    var entry = getEntry(that, key)\n      , prev, index;\n    // change existing entry\n    if(entry){\n      entry.v = value;\n    // create new entry\n    } else {\n      that._l = entry = {\n        i: index = fastKey(key, true), // <- index\n        k: key,                        // <- key\n        v: value,                      // <- value\n        p: prev = that._l,             // <- previous entry\n        n: undefined,                  // <- next entry\n        r: false                       // <- removed\n      };\n      if(!that._f)that._f = entry;\n      if(prev)prev.n = entry;\n      that[SIZE]++;\n      // add to index\n      if(index !== 'F')that._i[index] = entry;\n    } return that;\n  },\n  getEntry: getEntry,\n  setStrong: function(C, NAME, IS_MAP){\n    // add .keys, .values, .entries, [@@iterator]\n    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11\n    $iterDefine(C, NAME, function(iterated, kind){\n      this._t = iterated;  // target\n      this._k = kind;      // kind\n      this._l = undefined; // previous\n    }, function(){\n      var that  = this\n        , kind  = that._k\n        , entry = that._l;\n      // revert to the last existing entry\n      while(entry && entry.r)entry = entry.p;\n      // get next entry\n      if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){\n        // or finish the iteration\n        that._t = undefined;\n        return step(1);\n      }\n      // return step by kind\n      if(kind == 'keys'  )return step(0, entry.k);\n      if(kind == 'values')return step(0, entry.v);\n      return step(0, [entry.k, entry.v]);\n    }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);\n\n    // add [@@species], 23.1.2.2, 23.2.2.2\n    setSpecies(NAME);\n  }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.collection-strong.js\n ** module id = 318\n ** module chunks = 0\n **/","'use strict';\nvar global         = require('./$.global')\n  , $export        = require('./$.export')\n  , redefine       = require('./$.redefine')\n  , redefineAll    = require('./$.redefine-all')\n  , forOf          = require('./$.for-of')\n  , strictNew      = require('./$.strict-new')\n  , isObject       = require('./$.is-object')\n  , fails          = require('./$.fails')\n  , $iterDetect    = require('./$.iter-detect')\n  , setToStringTag = require('./$.set-to-string-tag');\n\nmodule.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){\n  var Base  = global[NAME]\n    , C     = Base\n    , ADDER = IS_MAP ? 'set' : 'add'\n    , proto = C && C.prototype\n    , O     = {};\n  var fixMethod = function(KEY){\n    var fn = proto[KEY];\n    redefine(proto, KEY,\n      KEY == 'delete' ? function(a){\n        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'has' ? function has(a){\n        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'get' ? function get(a){\n        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; }\n        : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; }\n    );\n  };\n  if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){\n    new C().entries().next();\n  }))){\n    // create collection constructor\n    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);\n    redefineAll(C.prototype, methods);\n  } else {\n    var instance             = new C\n      // early implementations not supports chaining\n      , HASNT_CHAINING       = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance\n      // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false\n      , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })\n      // most early implementations doesn't supports iterables, most modern - not close it correctly\n      , ACCEPT_ITERABLES     = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new\n      // for early implementations -0 and +0 not the same\n      , BUGGY_ZERO;\n    if(!ACCEPT_ITERABLES){ \n      C = wrapper(function(target, iterable){\n        strictNew(target, C, NAME);\n        var that = new Base;\n        if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);\n        return that;\n      });\n      C.prototype = proto;\n      proto.constructor = C;\n    }\n    IS_WEAK || instance.forEach(function(val, key){\n      BUGGY_ZERO = 1 / key === -Infinity;\n    });\n    if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){\n      fixMethod('delete');\n      fixMethod('has');\n      IS_MAP && fixMethod('get');\n    }\n    if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER);\n    // weak collections should not contains .clear method\n    if(IS_WEAK && proto.clear)delete proto.clear;\n  }\n\n  setToStringTag(C, NAME);\n\n  O[NAME] = C;\n  $export($export.G + $export.W + $export.F * (C != Base), O);\n\n  if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);\n\n  return C;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.collection.js\n ** module id = 319\n ** module chunks = 0\n **/","'use strict';\nvar strong = require('./$.collection-strong');\n\n// 23.2 Set Objects\nrequire('./$.collection')('Set', function(get){\n  return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.2.3.1 Set.prototype.add(value)\n  add: function add(value){\n    return strong.def(this, value = value === 0 ? 0 : value, value);\n  }\n}, strong);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.set.js\n ** module id = 320\n ** module chunks = 0\n **/","'use strict';\nvar $            = require('./$')\n  , redefine     = require('./$.redefine')\n  , weak         = require('./$.collection-weak')\n  , isObject     = require('./$.is-object')\n  , has          = require('./$.has')\n  , frozenStore  = weak.frozenStore\n  , WEAK         = weak.WEAK\n  , isExtensible = Object.isExtensible || isObject\n  , tmp          = {};\n\n// 23.3 WeakMap Objects\nvar $WeakMap = require('./$.collection')('WeakMap', function(get){\n  return function WeakMap(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.3.3.3 WeakMap.prototype.get(key)\n  get: function get(key){\n    if(isObject(key)){\n      if(!isExtensible(key))return frozenStore(this).get(key);\n      if(has(key, WEAK))return key[WEAK][this._i];\n    }\n  },\n  // 23.3.3.5 WeakMap.prototype.set(key, value)\n  set: function set(key, value){\n    return weak.def(this, key, value);\n  }\n}, weak, true, true);\n\n// IE11 WeakMap frozen keys fix\nif(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){\n  $.each.call(['delete', 'has', 'get', 'set'], function(key){\n    var proto  = $WeakMap.prototype\n      , method = proto[key];\n    redefine(proto, key, function(a, b){\n      // store frozen objects on leaky map\n      if(isObject(a) && !isExtensible(a)){\n        var result = frozenStore(this)[key](a, b);\n        return key == 'set' ? this : result;\n      // store all the rest on native weakmap\n      } return method.call(this, a, b);\n    });\n  });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.weak-map.js\n ** module id = 321\n ** module chunks = 0\n **/","'use strict';\nvar hide              = require('./$.hide')\n  , redefineAll       = require('./$.redefine-all')\n  , anObject          = require('./$.an-object')\n  , isObject          = require('./$.is-object')\n  , strictNew         = require('./$.strict-new')\n  , forOf             = require('./$.for-of')\n  , createArrayMethod = require('./$.array-methods')\n  , $has              = require('./$.has')\n  , WEAK              = require('./$.uid')('weak')\n  , isExtensible      = Object.isExtensible || isObject\n  , arrayFind         = createArrayMethod(5)\n  , arrayFindIndex    = createArrayMethod(6)\n  , id                = 0;\n\n// fallback for frozen keys\nvar frozenStore = function(that){\n  return that._l || (that._l = new FrozenStore);\n};\nvar FrozenStore = function(){\n  this.a = [];\n};\nvar findFrozen = function(store, key){\n  return arrayFind(store.a, function(it){\n    return it[0] === key;\n  });\n};\nFrozenStore.prototype = {\n  get: function(key){\n    var entry = findFrozen(this, key);\n    if(entry)return entry[1];\n  },\n  has: function(key){\n    return !!findFrozen(this, key);\n  },\n  set: function(key, value){\n    var entry = findFrozen(this, key);\n    if(entry)entry[1] = value;\n    else this.a.push([key, value]);\n  },\n  'delete': function(key){\n    var index = arrayFindIndex(this.a, function(it){\n      return it[0] === key;\n    });\n    if(~index)this.a.splice(index, 1);\n    return !!~index;\n  }\n};\n\nmodule.exports = {\n  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){\n    var C = wrapper(function(that, iterable){\n      strictNew(that, C, NAME);\n      that._i = id++;      // collection id\n      that._l = undefined; // leak store for frozen objects\n      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);\n    });\n    redefineAll(C.prototype, {\n      // 23.3.3.2 WeakMap.prototype.delete(key)\n      // 23.4.3.3 WeakSet.prototype.delete(value)\n      'delete': function(key){\n        if(!isObject(key))return false;\n        if(!isExtensible(key))return frozenStore(this)['delete'](key);\n        return $has(key, WEAK) && $has(key[WEAK], this._i) && delete key[WEAK][this._i];\n      },\n      // 23.3.3.4 WeakMap.prototype.has(key)\n      // 23.4.3.4 WeakSet.prototype.has(value)\n      has: function has(key){\n        if(!isObject(key))return false;\n        if(!isExtensible(key))return frozenStore(this).has(key);\n        return $has(key, WEAK) && $has(key[WEAK], this._i);\n      }\n    });\n    return C;\n  },\n  def: function(that, key, value){\n    if(!isExtensible(anObject(key))){\n      frozenStore(that).set(key, value);\n    } else {\n      $has(key, WEAK) || hide(key, WEAK, {});\n      key[WEAK][that._i] = value;\n    } return that;\n  },\n  frozenStore: frozenStore,\n  WEAK: WEAK\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.collection-weak.js\n ** module id = 322\n ** module chunks = 0\n **/","'use strict';\nvar weak = require('./$.collection-weak');\n\n// 23.4 WeakSet Objects\nrequire('./$.collection')('WeakSet', function(get){\n  return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.4.3.1 WeakSet.prototype.add(value)\n  add: function add(value){\n    return weak.def(this, value, true);\n  }\n}, weak, false, true);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.weak-set.js\n ** module id = 323\n ** module chunks = 0\n **/","// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)\nvar $export = require('./$.export')\n  , _apply  = Function.apply;\n\n$export($export.S, 'Reflect', {\n  apply: function apply(target, thisArgument, argumentsList){\n    return _apply.call(target, thisArgument, argumentsList);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.apply.js\n ** module id = 324\n ** module chunks = 0\n **/","// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])\nvar $         = require('./$')\n  , $export   = require('./$.export')\n  , aFunction = require('./$.a-function')\n  , anObject  = require('./$.an-object')\n  , isObject  = require('./$.is-object')\n  , bind      = Function.bind || require('./$.core').Function.prototype.bind;\n\n// MS Edge supports only 2 arguments\n// FF Nightly sets third argument as `new.target`, but does not create `this` from it\n$export($export.S + $export.F * require('./$.fails')(function(){\n  function F(){}\n  return !(Reflect.construct(function(){}, [], F) instanceof F);\n}), 'Reflect', {\n  construct: function construct(Target, args /*, newTarget*/){\n    aFunction(Target);\n    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);\n    if(Target == newTarget){\n      // w/o altered newTarget, optimization for 0-4 arguments\n      if(args != undefined)switch(anObject(args).length){\n        case 0: return new Target;\n        case 1: return new Target(args[0]);\n        case 2: return new Target(args[0], args[1]);\n        case 3: return new Target(args[0], args[1], args[2]);\n        case 4: return new Target(args[0], args[1], args[2], args[3]);\n      }\n      // w/o altered newTarget, lot of arguments case\n      var $args = [null];\n      $args.push.apply($args, args);\n      return new (bind.apply(Target, $args));\n    }\n    // with altered newTarget, not support built-in constructors\n    var proto    = newTarget.prototype\n      , instance = $.create(isObject(proto) ? proto : Object.prototype)\n      , result   = Function.apply.call(Target, instance, args);\n    return isObject(result) ? result : instance;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.construct.js\n ** module id = 325\n ** module chunks = 0\n **/","// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)\nvar $        = require('./$')\n  , $export  = require('./$.export')\n  , anObject = require('./$.an-object');\n\n// MS Edge has broken Reflect.defineProperty - throwing instead of returning false\n$export($export.S + $export.F * require('./$.fails')(function(){\n  Reflect.defineProperty($.setDesc({}, 1, {value: 1}), 1, {value: 2});\n}), 'Reflect', {\n  defineProperty: function defineProperty(target, propertyKey, attributes){\n    anObject(target);\n    try {\n      $.setDesc(target, propertyKey, attributes);\n      return true;\n    } catch(e){\n      return false;\n    }\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.define-property.js\n ** module id = 326\n ** module chunks = 0\n **/","// 26.1.4 Reflect.deleteProperty(target, propertyKey)\nvar $export  = require('./$.export')\n  , getDesc  = require('./$').getDesc\n  , anObject = require('./$.an-object');\n\n$export($export.S, 'Reflect', {\n  deleteProperty: function deleteProperty(target, propertyKey){\n    var desc = getDesc(anObject(target), propertyKey);\n    return desc && !desc.configurable ? false : delete target[propertyKey];\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.delete-property.js\n ** module id = 327\n ** module chunks = 0\n **/","'use strict';\n// 26.1.5 Reflect.enumerate(target)\nvar $export  = require('./$.export')\n  , anObject = require('./$.an-object');\nvar Enumerate = function(iterated){\n  this._t = anObject(iterated); // target\n  this._i = 0;                  // next index\n  var keys = this._k = []       // keys\n    , key;\n  for(key in iterated)keys.push(key);\n};\nrequire('./$.iter-create')(Enumerate, 'Object', function(){\n  var that = this\n    , keys = that._k\n    , key;\n  do {\n    if(that._i >= keys.length)return {value: undefined, done: true};\n  } while(!((key = keys[that._i++]) in that._t));\n  return {value: key, done: false};\n});\n\n$export($export.S, 'Reflect', {\n  enumerate: function enumerate(target){\n    return new Enumerate(target);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.enumerate.js\n ** module id = 328\n ** module chunks = 0\n **/","// 26.1.6 Reflect.get(target, propertyKey [, receiver])\nvar $        = require('./$')\n  , has      = require('./$.has')\n  , $export  = require('./$.export')\n  , isObject = require('./$.is-object')\n  , anObject = require('./$.an-object');\n\nfunction get(target, propertyKey/*, receiver*/){\n  var receiver = arguments.length < 3 ? target : arguments[2]\n    , desc, proto;\n  if(anObject(target) === receiver)return target[propertyKey];\n  if(desc = $.getDesc(target, propertyKey))return has(desc, 'value')\n    ? desc.value\n    : desc.get !== undefined\n      ? desc.get.call(receiver)\n      : undefined;\n  if(isObject(proto = $.getProto(target)))return get(proto, propertyKey, receiver);\n}\n\n$export($export.S, 'Reflect', {get: get});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.get.js\n ** module id = 329\n ** module chunks = 0\n **/","// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)\nvar $        = require('./$')\n  , $export  = require('./$.export')\n  , anObject = require('./$.an-object');\n\n$export($export.S, 'Reflect', {\n  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey){\n    return $.getDesc(anObject(target), propertyKey);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.get-own-property-descriptor.js\n ** module id = 330\n ** module chunks = 0\n **/","// 26.1.8 Reflect.getPrototypeOf(target)\nvar $export  = require('./$.export')\n  , getProto = require('./$').getProto\n  , anObject = require('./$.an-object');\n\n$export($export.S, 'Reflect', {\n  getPrototypeOf: function getPrototypeOf(target){\n    return getProto(anObject(target));\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.get-prototype-of.js\n ** module id = 331\n ** module chunks = 0\n **/","// 26.1.9 Reflect.has(target, propertyKey)\nvar $export = require('./$.export');\n\n$export($export.S, 'Reflect', {\n  has: function has(target, propertyKey){\n    return propertyKey in target;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.has.js\n ** module id = 332\n ** module chunks = 0\n **/","// 26.1.10 Reflect.isExtensible(target)\nvar $export       = require('./$.export')\n  , anObject      = require('./$.an-object')\n  , $isExtensible = Object.isExtensible;\n\n$export($export.S, 'Reflect', {\n  isExtensible: function isExtensible(target){\n    anObject(target);\n    return $isExtensible ? $isExtensible(target) : true;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.is-extensible.js\n ** module id = 333\n ** module chunks = 0\n **/","// 26.1.11 Reflect.ownKeys(target)\nvar $export = require('./$.export');\n\n$export($export.S, 'Reflect', {ownKeys: require('./$.own-keys')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.own-keys.js\n ** module id = 334\n ** module chunks = 0\n **/","// all object keys, includes non-enumerable and symbols\nvar $        = require('./$')\n  , anObject = require('./$.an-object')\n  , Reflect  = require('./$.global').Reflect;\nmodule.exports = Reflect && Reflect.ownKeys || function ownKeys(it){\n  var keys       = $.getNames(anObject(it))\n    , getSymbols = $.getSymbols;\n  return getSymbols ? keys.concat(getSymbols(it)) : keys;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.own-keys.js\n ** module id = 335\n ** module chunks = 0\n **/","// 26.1.12 Reflect.preventExtensions(target)\nvar $export            = require('./$.export')\n  , anObject           = require('./$.an-object')\n  , $preventExtensions = Object.preventExtensions;\n\n$export($export.S, 'Reflect', {\n  preventExtensions: function preventExtensions(target){\n    anObject(target);\n    try {\n      if($preventExtensions)$preventExtensions(target);\n      return true;\n    } catch(e){\n      return false;\n    }\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.prevent-extensions.js\n ** module id = 336\n ** module chunks = 0\n **/","// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])\nvar $          = require('./$')\n  , has        = require('./$.has')\n  , $export    = require('./$.export')\n  , createDesc = require('./$.property-desc')\n  , anObject   = require('./$.an-object')\n  , isObject   = require('./$.is-object');\n\nfunction set(target, propertyKey, V/*, receiver*/){\n  var receiver = arguments.length < 4 ? target : arguments[3]\n    , ownDesc  = $.getDesc(anObject(target), propertyKey)\n    , existingDescriptor, proto;\n  if(!ownDesc){\n    if(isObject(proto = $.getProto(target))){\n      return set(proto, propertyKey, V, receiver);\n    }\n    ownDesc = createDesc(0);\n  }\n  if(has(ownDesc, 'value')){\n    if(ownDesc.writable === false || !isObject(receiver))return false;\n    existingDescriptor = $.getDesc(receiver, propertyKey) || createDesc(0);\n    existingDescriptor.value = V;\n    $.setDesc(receiver, propertyKey, existingDescriptor);\n    return true;\n  }\n  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);\n}\n\n$export($export.S, 'Reflect', {set: set});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.set.js\n ** module id = 337\n ** module chunks = 0\n **/","// 26.1.14 Reflect.setPrototypeOf(target, proto)\nvar $export  = require('./$.export')\n  , setProto = require('./$.set-proto');\n\nif(setProto)$export($export.S, 'Reflect', {\n  setPrototypeOf: function setPrototypeOf(target, proto){\n    setProto.check(target, proto);\n    try {\n      setProto.set(target, proto);\n      return true;\n    } catch(e){\n      return false;\n    }\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es6.reflect.set-prototype-of.js\n ** module id = 338\n ** module chunks = 0\n **/","'use strict';\nvar $export   = require('./$.export')\n  , $includes = require('./$.array-includes')(true);\n\n$export($export.P, 'Array', {\n  // https://github.com/domenic/Array.prototype.includes\n  includes: function includes(el /*, fromIndex = 0 */){\n    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n\nrequire('./$.add-to-unscopables')('includes');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.array.includes.js\n ** module id = 339\n ** module chunks = 0\n **/","'use strict';\n// https://github.com/mathiasbynens/String.prototype.at\nvar $export = require('./$.export')\n  , $at     = require('./$.string-at')(true);\n\n$export($export.P, 'String', {\n  at: function at(pos){\n    return $at(this, pos);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.string.at.js\n ** module id = 340\n ** module chunks = 0\n **/","'use strict';\nvar $export = require('./$.export')\n  , $pad    = require('./$.string-pad');\n\n$export($export.P, 'String', {\n  padLeft: function padLeft(maxLength /*, fillString = ' ' */){\n    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.string.pad-left.js\n ** module id = 341\n ** module chunks = 0\n **/","// https://github.com/ljharb/proposal-string-pad-left-right\nvar toLength = require('./$.to-length')\n  , repeat   = require('./$.string-repeat')\n  , defined  = require('./$.defined');\n\nmodule.exports = function(that, maxLength, fillString, left){\n  var S            = String(defined(that))\n    , stringLength = S.length\n    , fillStr      = fillString === undefined ? ' ' : String(fillString)\n    , intMaxLength = toLength(maxLength);\n  if(intMaxLength <= stringLength)return S;\n  if(fillStr == '')fillStr = ' ';\n  var fillLen = intMaxLength - stringLength\n    , stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));\n  if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen);\n  return left ? stringFiller + S : S + stringFiller;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.string-pad.js\n ** module id = 342\n ** module chunks = 0\n **/","'use strict';\nvar $export = require('./$.export')\n  , $pad    = require('./$.string-pad');\n\n$export($export.P, 'String', {\n  padRight: function padRight(maxLength /*, fillString = ' ' */){\n    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.string.pad-right.js\n ** module id = 343\n ** module chunks = 0\n **/","'use strict';\n// https://github.com/sebmarkbage/ecmascript-string-left-right-trim\nrequire('./$.string-trim')('trimLeft', function($trim){\n  return function trimLeft(){\n    return $trim(this, 1);\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.string.trim-left.js\n ** module id = 344\n ** module chunks = 0\n **/","'use strict';\n// https://github.com/sebmarkbage/ecmascript-string-left-right-trim\nrequire('./$.string-trim')('trimRight', function($trim){\n  return function trimRight(){\n    return $trim(this, 2);\n  };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.string.trim-right.js\n ** module id = 345\n ** module chunks = 0\n **/","// https://github.com/benjamingr/RexExp.escape\nvar $export = require('./$.export')\n  , $re     = require('./$.replacer')(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\n$export($export.S, 'RegExp', {escape: function escape(it){ return $re(it); }});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.regexp.escape.js\n ** module id = 346\n ** module chunks = 0\n **/","module.exports = function(regExp, replace){\n  var replacer = replace === Object(replace) ? function(part){\n    return replace[part];\n  } : replace;\n  return function(it){\n    return String(it).replace(regExp, replacer);\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.replacer.js\n ** module id = 347\n ** module chunks = 0\n **/","// https://gist.github.com/WebReflection/9353781\nvar $          = require('./$')\n  , $export    = require('./$.export')\n  , ownKeys    = require('./$.own-keys')\n  , toIObject  = require('./$.to-iobject')\n  , createDesc = require('./$.property-desc');\n\n$export($export.S, 'Object', {\n  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){\n    var O       = toIObject(object)\n      , setDesc = $.setDesc\n      , getDesc = $.getDesc\n      , keys    = ownKeys(O)\n      , result  = {}\n      , i       = 0\n      , key, D;\n    while(keys.length > i){\n      D = getDesc(O, key = keys[i++]);\n      if(key in result)setDesc(result, key, createDesc(0, D));\n      else result[key] = D;\n    } return result;\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.object.get-own-property-descriptors.js\n ** module id = 348\n ** module chunks = 0\n **/","// http://goo.gl/XkBrjD\nvar $export = require('./$.export')\n  , $values = require('./$.object-to-array')(false);\n\n$export($export.S, 'Object', {\n  values: function values(it){\n    return $values(it);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.object.values.js\n ** module id = 349\n ** module chunks = 0\n **/","var $         = require('./$')\n  , toIObject = require('./$.to-iobject')\n  , isEnum    = $.isEnum;\nmodule.exports = function(isEntries){\n  return function(it){\n    var O      = toIObject(it)\n      , keys   = $.getKeys(O)\n      , length = keys.length\n      , i      = 0\n      , result = []\n      , key;\n    while(length > i)if(isEnum.call(O, key = keys[i++])){\n      result.push(isEntries ? [key, O[key]] : O[key]);\n    } return result;\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.object-to-array.js\n ** module id = 350\n ** module chunks = 0\n **/","// http://goo.gl/XkBrjD\nvar $export  = require('./$.export')\n  , $entries = require('./$.object-to-array')(true);\n\n$export($export.S, 'Object', {\n  entries: function entries(it){\n    return $entries(it);\n  }\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.object.entries.js\n ** module id = 351\n ** module chunks = 0\n **/","// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar $export  = require('./$.export');\n\n$export($export.P, 'Map', {toJSON: require('./$.collection-to-json')('Map')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.map.to-json.js\n ** module id = 352\n ** module chunks = 0\n **/","// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar forOf   = require('./$.for-of')\n  , classof = require('./$.classof');\nmodule.exports = function(NAME){\n  return function toJSON(){\n    if(classof(this) != NAME)throw TypeError(NAME + \"#toJSON isn't generic\");\n    var arr = [];\n    forOf(this, false, arr.push, arr);\n    return arr;\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.collection-to-json.js\n ** module id = 353\n ** module chunks = 0\n **/","// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar $export  = require('./$.export');\n\n$export($export.P, 'Set', {toJSON: require('./$.collection-to-json')('Set')});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/es7.set.to-json.js\n ** module id = 354\n ** module chunks = 0\n **/","// JavaScript 1.6 / Strawman array statics shim\nvar $       = require('./$')\n  , $export = require('./$.export')\n  , $ctx    = require('./$.ctx')\n  , $Array  = require('./$.core').Array || Array\n  , statics = {};\nvar setStatics = function(keys, length){\n  $.each.call(keys.split(','), function(key){\n    if(length == undefined && key in $Array)statics[key] = $Array[key];\n    else if(key in [])statics[key] = $ctx(Function.call, [][key], length);\n  });\n};\nsetStatics('pop,reverse,shift,keys,values,entries', 1);\nsetStatics('indexOf,every,some,forEach,map,filter,find,findIndex,includes', 3);\nsetStatics('join,slice,concat,push,splice,unshift,sort,lastIndexOf,' +\n           'reduce,reduceRight,copyWithin,fill');\n$export($export.S, 'Array', statics);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/js.array.statics.js\n ** module id = 355\n ** module chunks = 0\n **/","// ie9- setTimeout & setInterval additional parameters fix\nvar global     = require('./$.global')\n  , $export    = require('./$.export')\n  , invoke     = require('./$.invoke')\n  , partial    = require('./$.partial')\n  , navigator  = global.navigator\n  , MSIE       = !!navigator && /MSIE .\\./.test(navigator.userAgent); // <- dirty ie9- check\nvar wrap = function(set){\n  return MSIE ? function(fn, time /*, ...args */){\n    return set(invoke(\n      partial,\n      [].slice.call(arguments, 2),\n      typeof fn == 'function' ? fn : Function(fn)\n    ), time);\n  } : set;\n};\n$export($export.G + $export.B + $export.F * MSIE, {\n  setTimeout:  wrap(global.setTimeout),\n  setInterval: wrap(global.setInterval)\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/web.timers.js\n ** module id = 356\n ** module chunks = 0\n **/","'use strict';\nvar path      = require('./$.path')\n  , invoke    = require('./$.invoke')\n  , aFunction = require('./$.a-function');\nmodule.exports = function(/* ...pargs */){\n  var fn     = aFunction(this)\n    , length = arguments.length\n    , pargs  = Array(length)\n    , i      = 0\n    , _      = path._\n    , holder = false;\n  while(length > i)if((pargs[i] = arguments[i++]) === _)holder = true;\n  return function(/* ...args */){\n    var that  = this\n      , $$    = arguments\n      , $$len = $$.length\n      , j = 0, k = 0, args;\n    if(!holder && !$$len)return invoke(fn, pargs, that);\n    args = pargs.slice();\n    if(holder)for(;length > j; j++)if(args[j] === _)args[j] = $$[k++];\n    while($$len > k)args.push($$[k++]);\n    return invoke(fn, args, that);\n  };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.partial.js\n ** module id = 357\n ** module chunks = 0\n **/","module.exports = require('./$.global');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/$.path.js\n ** module id = 358\n ** module chunks = 0\n **/","var $export = require('./$.export')\n  , $task   = require('./$.task');\n$export($export.G + $export.B, {\n  setImmediate:   $task.set,\n  clearImmediate: $task.clear\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/web.immediate.js\n ** module id = 359\n ** module chunks = 0\n **/","require('./es6.array.iterator');\nvar global      = require('./$.global')\n  , hide        = require('./$.hide')\n  , Iterators   = require('./$.iterators')\n  , ITERATOR    = require('./$.wks')('iterator')\n  , NL          = global.NodeList\n  , HTC         = global.HTMLCollection\n  , NLProto     = NL && NL.prototype\n  , HTCProto    = HTC && HTC.prototype\n  , ArrayValues = Iterators.NodeList = Iterators.HTMLCollection = Iterators.Array;\nif(NLProto && !NLProto[ITERATOR])hide(NLProto, ITERATOR, ArrayValues);\nif(HTCProto && !HTCProto[ITERATOR])hide(HTCProto, ITERATOR, ArrayValues);\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/core-js/modules/web.dom.iterable.js\n ** module id = 360\n ** module chunks = 0\n **/","/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * https://raw.github.com/facebook/regenerator/master/LICENSE file. An\n * additional grant of patent rights can be found in the PATENTS file in\n * the same directory.\n */\n\n!(function(global) {\n  \"use strict\";\n\n  var hasOwn = Object.prototype.hasOwnProperty;\n  var undefined; // More compressible than void 0.\n  var iteratorSymbol =\n    typeof Symbol === \"function\" && Symbol.iterator || \"@@iterator\";\n\n  var inModule = typeof module === \"object\";\n  var runtime = global.regeneratorRuntime;\n  if (runtime) {\n    if (inModule) {\n      // If regeneratorRuntime is defined globally and we're in a module,\n      // make the exports object identical to regeneratorRuntime.\n      module.exports = runtime;\n    }\n    // Don't bother evaluating the rest of this file if the runtime was\n    // already defined globally.\n    return;\n  }\n\n  // Define the runtime globally (as expected by generated code) as either\n  // module.exports (if we're in a module) or a new, empty object.\n  runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n  function wrap(innerFn, outerFn, self, tryLocsList) {\n    // If outerFn provided, then outerFn.prototype instanceof Generator.\n    var generator = Object.create((outerFn || Generator).prototype);\n    var context = new Context(tryLocsList || []);\n\n    // The ._invoke method unifies the implementations of the .next,\n    // .throw, and .return methods.\n    generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n    return generator;\n  }\n  runtime.wrap = wrap;\n\n  // Try/catch helper to minimize deoptimizations. Returns a completion\n  // record like context.tryEntries[i].completion. This interface could\n  // have been (and was previously) designed to take a closure to be\n  // invoked without arguments, but in all the cases we care about we\n  // already have an existing method we want to call, so there's no need\n  // to create a new function object. We can even get away with assuming\n  // the method takes exactly one argument, since that happens to be true\n  // in every case, so we don't have to touch the arguments object. The\n  // only additional allocation required is the completion record, which\n  // has a stable shape and so hopefully should be cheap to allocate.\n  function tryCatch(fn, obj, arg) {\n    try {\n      return { type: \"normal\", arg: fn.call(obj, arg) };\n    } catch (err) {\n      return { type: \"throw\", arg: err };\n    }\n  }\n\n  var GenStateSuspendedStart = \"suspendedStart\";\n  var GenStateSuspendedYield = \"suspendedYield\";\n  var GenStateExecuting = \"executing\";\n  var GenStateCompleted = \"completed\";\n\n  // Returning this object from the innerFn has the same effect as\n  // breaking out of the dispatch switch statement.\n  var ContinueSentinel = {};\n\n  // Dummy constructor functions that we use as the .constructor and\n  // .constructor.prototype properties for functions that return Generator\n  // objects. For full spec compliance, you may wish to configure your\n  // minifier not to mangle the names of these two functions.\n  function Generator() {}\n  function GeneratorFunction() {}\n  function GeneratorFunctionPrototype() {}\n\n  var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype;\n  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n  GeneratorFunctionPrototype.constructor = GeneratorFunction;\n  GeneratorFunction.displayName = \"GeneratorFunction\";\n\n  // Helper for defining the .next, .throw, and .return methods of the\n  // Iterator interface in terms of a single ._invoke method.\n  function defineIteratorMethods(prototype) {\n    [\"next\", \"throw\", \"return\"].forEach(function(method) {\n      prototype[method] = function(arg) {\n        return this._invoke(method, arg);\n      };\n    });\n  }\n\n  runtime.isGeneratorFunction = function(genFun) {\n    var ctor = typeof genFun === \"function\" && genFun.constructor;\n    return ctor\n      ? ctor === GeneratorFunction ||\n        // For the native GeneratorFunction constructor, the best we can\n        // do is to check its .name property.\n        (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n      : false;\n  };\n\n  runtime.mark = function(genFun) {\n    if (Object.setPrototypeOf) {\n      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n    } else {\n      genFun.__proto__ = GeneratorFunctionPrototype;\n    }\n    genFun.prototype = Object.create(Gp);\n    return genFun;\n  };\n\n  // Within the body of any async function, `await x` is transformed to\n  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n  // `value instanceof AwaitArgument` to determine if the yielded value is\n  // meant to be awaited. Some may consider the name of this method too\n  // cutesy, but they are curmudgeons.\n  runtime.awrap = function(arg) {\n    return new AwaitArgument(arg);\n  };\n\n  function AwaitArgument(arg) {\n    this.arg = arg;\n  }\n\n  function AsyncIterator(generator) {\n    // This invoke function is written in a style that assumes some\n    // calling function (or Promise) will handle exceptions.\n    function invoke(method, arg) {\n      var result = generator[method](arg);\n      var value = result.value;\n      return value instanceof AwaitArgument\n        ? Promise.resolve(value.arg).then(invokeNext, invokeThrow)\n        : Promise.resolve(value).then(function(unwrapped) {\n            // When a yielded Promise is resolved, its final value becomes\n            // the .value of the Promise<{value,done}> result for the\n            // current iteration. If the Promise is rejected, however, the\n            // result for this iteration will be rejected with the same\n            // reason. Note that rejections of yielded Promises are not\n            // thrown back into the generator function, as is the case\n            // when an awaited Promise is rejected. This difference in\n            // behavior between yield and await is important, because it\n            // allows the consumer to decide what to do with the yielded\n            // rejection (swallow it and continue, manually .throw it back\n            // into the generator, abandon iteration, whatever). With\n            // await, by contrast, there is no opportunity to examine the\n            // rejection reason outside the generator function, so the\n            // only option is to throw it from the await expression, and\n            // let the generator function handle the exception.\n            result.value = unwrapped;\n            return result;\n          });\n    }\n\n    if (typeof process === \"object\" && process.domain) {\n      invoke = process.domain.bind(invoke);\n    }\n\n    var invokeNext = invoke.bind(generator, \"next\");\n    var invokeThrow = invoke.bind(generator, \"throw\");\n    var invokeReturn = invoke.bind(generator, \"return\");\n    var previousPromise;\n\n    function enqueue(method, arg) {\n      function callInvokeWithMethodAndArg() {\n        return invoke(method, arg);\n      }\n\n      return previousPromise =\n        // If enqueue has been called before, then we want to wait until\n        // all previous Promises have been resolved before calling invoke,\n        // so that results are always delivered in the correct order. If\n        // enqueue has not been called before, then it is important to\n        // call invoke immediately, without waiting on a callback to fire,\n        // so that the async generator function has the opportunity to do\n        // any necessary setup in a predictable way. This predictability\n        // is why the Promise constructor synchronously invokes its\n        // executor callback, and why async functions synchronously\n        // execute code before the first await. Since we implement simple\n        // async functions in terms of async generators, it is especially\n        // important to get this right, even though it requires care.\n        previousPromise ? previousPromise.then(\n          callInvokeWithMethodAndArg,\n          // Avoid propagating failures to Promises returned by later\n          // invocations of the iterator.\n          callInvokeWithMethodAndArg\n        ) : new Promise(function (resolve) {\n          resolve(callInvokeWithMethodAndArg());\n        });\n    }\n\n    // Define the unified helper method that is used to implement .next,\n    // .throw, and .return (see defineIteratorMethods).\n    this._invoke = enqueue;\n  }\n\n  defineIteratorMethods(AsyncIterator.prototype);\n\n  // Note that simple async functions are implemented on top of\n  // AsyncIterator objects; they just return a Promise for the value of\n  // the final result produced by the iterator.\n  runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n    var iter = new AsyncIterator(\n      wrap(innerFn, outerFn, self, tryLocsList)\n    );\n\n    return runtime.isGeneratorFunction(outerFn)\n      ? iter // If outerFn is a generator, return the full iterator.\n      : iter.next().then(function(result) {\n          return result.done ? result.value : iter.next();\n        });\n  };\n\n  function makeInvokeMethod(innerFn, self, context) {\n    var state = GenStateSuspendedStart;\n\n    return function invoke(method, arg) {\n      if (state === GenStateExecuting) {\n        throw new Error(\"Generator is already running\");\n      }\n\n      if (state === GenStateCompleted) {\n        if (method === \"throw\") {\n          throw arg;\n        }\n\n        // Be forgiving, per 25.3.3.3.3 of the spec:\n        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n        return doneResult();\n      }\n\n      while (true) {\n        var delegate = context.delegate;\n        if (delegate) {\n          if (method === \"return\" ||\n              (method === \"throw\" && delegate.iterator[method] === undefined)) {\n            // A return or throw (when the delegate iterator has no throw\n            // method) always terminates the yield* loop.\n            context.delegate = null;\n\n            // If the delegate iterator has a return method, give it a\n            // chance to clean up.\n            var returnMethod = delegate.iterator[\"return\"];\n            if (returnMethod) {\n              var record = tryCatch(returnMethod, delegate.iterator, arg);\n              if (record.type === \"throw\") {\n                // If the return method threw an exception, let that\n                // exception prevail over the original return or throw.\n                method = \"throw\";\n                arg = record.arg;\n                continue;\n              }\n            }\n\n            if (method === \"return\") {\n              // Continue with the outer return, now that the delegate\n              // iterator has been terminated.\n              continue;\n            }\n          }\n\n          var record = tryCatch(\n            delegate.iterator[method],\n            delegate.iterator,\n            arg\n          );\n\n          if (record.type === \"throw\") {\n            context.delegate = null;\n\n            // Like returning generator.throw(uncaught), but without the\n            // overhead of an extra function call.\n            method = \"throw\";\n            arg = record.arg;\n            continue;\n          }\n\n          // Delegate generator ran and handled its own exceptions so\n          // regardless of what the method was, we continue as if it is\n          // \"next\" with an undefined arg.\n          method = \"next\";\n          arg = undefined;\n\n          var info = record.arg;\n          if (info.done) {\n            context[delegate.resultName] = info.value;\n            context.next = delegate.nextLoc;\n          } else {\n            state = GenStateSuspendedYield;\n            return info;\n          }\n\n          context.delegate = null;\n        }\n\n        if (method === \"next\") {\n          context._sent = arg;\n\n          if (state === GenStateSuspendedYield) {\n            context.sent = arg;\n          } else {\n            context.sent = undefined;\n          }\n        } else if (method === \"throw\") {\n          if (state === GenStateSuspendedStart) {\n            state = GenStateCompleted;\n            throw arg;\n          }\n\n          if (context.dispatchException(arg)) {\n            // If the dispatched exception was caught by a catch block,\n            // then let that catch block handle the exception normally.\n            method = \"next\";\n            arg = undefined;\n          }\n\n        } else if (method === \"return\") {\n          context.abrupt(\"return\", arg);\n        }\n\n        state = GenStateExecuting;\n\n        var record = tryCatch(innerFn, self, context);\n        if (record.type === \"normal\") {\n          // If an exception is thrown from innerFn, we leave state ===\n          // GenStateExecuting and loop back for another invocation.\n          state = context.done\n            ? GenStateCompleted\n            : GenStateSuspendedYield;\n\n          var info = {\n            value: record.arg,\n            done: context.done\n          };\n\n          if (record.arg === ContinueSentinel) {\n            if (context.delegate && method === \"next\") {\n              // Deliberately forget the last sent value so that we don't\n              // accidentally pass it on to the delegate.\n              arg = undefined;\n            }\n          } else {\n            return info;\n          }\n\n        } else if (record.type === \"throw\") {\n          state = GenStateCompleted;\n          // Dispatch the exception by looping back around to the\n          // context.dispatchException(arg) call above.\n          method = \"throw\";\n          arg = record.arg;\n        }\n      }\n    };\n  }\n\n  // Define Generator.prototype.{next,throw,return} in terms of the\n  // unified ._invoke helper method.\n  defineIteratorMethods(Gp);\n\n  Gp[iteratorSymbol] = function() {\n    return this;\n  };\n\n  Gp.toString = function() {\n    return \"[object Generator]\";\n  };\n\n  function pushTryEntry(locs) {\n    var entry = { tryLoc: locs[0] };\n\n    if (1 in locs) {\n      entry.catchLoc = locs[1];\n    }\n\n    if (2 in locs) {\n      entry.finallyLoc = locs[2];\n      entry.afterLoc = locs[3];\n    }\n\n    this.tryEntries.push(entry);\n  }\n\n  function resetTryEntry(entry) {\n    var record = entry.completion || {};\n    record.type = \"normal\";\n    delete record.arg;\n    entry.completion = record;\n  }\n\n  function Context(tryLocsList) {\n    // The root entry object (effectively a try statement without a catch\n    // or a finally block) gives us a place to store values thrown from\n    // locations where there is no enclosing try statement.\n    this.tryEntries = [{ tryLoc: \"root\" }];\n    tryLocsList.forEach(pushTryEntry, this);\n    this.reset(true);\n  }\n\n  runtime.keys = function(object) {\n    var keys = [];\n    for (var key in object) {\n      keys.push(key);\n    }\n    keys.reverse();\n\n    // Rather than returning an object with a next method, we keep\n    // things simple and return the next function itself.\n    return function next() {\n      while (keys.length) {\n        var key = keys.pop();\n        if (key in object) {\n          next.value = key;\n          next.done = false;\n          return next;\n        }\n      }\n\n      // To avoid creating an additional object, we just hang the .value\n      // and .done properties off the next function object itself. This\n      // also ensures that the minifier will not anonymize the function.\n      next.done = true;\n      return next;\n    };\n  };\n\n  function values(iterable) {\n    if (iterable) {\n      var iteratorMethod = iterable[iteratorSymbol];\n      if (iteratorMethod) {\n        return iteratorMethod.call(iterable);\n      }\n\n      if (typeof iterable.next === \"function\") {\n        return iterable;\n      }\n\n      if (!isNaN(iterable.length)) {\n        var i = -1, next = function next() {\n          while (++i < iterable.length) {\n            if (hasOwn.call(iterable, i)) {\n              next.value = iterable[i];\n              next.done = false;\n              return next;\n            }\n          }\n\n          next.value = undefined;\n          next.done = true;\n\n          return next;\n        };\n\n        return next.next = next;\n      }\n    }\n\n    // Return an iterator with no values.\n    return { next: doneResult };\n  }\n  runtime.values = values;\n\n  function doneResult() {\n    return { value: undefined, done: true };\n  }\n\n  Context.prototype = {\n    constructor: Context,\n\n    reset: function(skipTempReset) {\n      this.prev = 0;\n      this.next = 0;\n      this.sent = undefined;\n      this.done = false;\n      this.delegate = null;\n\n      this.tryEntries.forEach(resetTryEntry);\n\n      if (!skipTempReset) {\n        for (var name in this) {\n          // Not sure about the optimal order of these conditions:\n          if (name.charAt(0) === \"t\" &&\n              hasOwn.call(this, name) &&\n              !isNaN(+name.slice(1))) {\n            this[name] = undefined;\n          }\n        }\n      }\n    },\n\n    stop: function() {\n      this.done = true;\n\n      var rootEntry = this.tryEntries[0];\n      var rootRecord = rootEntry.completion;\n      if (rootRecord.type === \"throw\") {\n        throw rootRecord.arg;\n      }\n\n      return this.rval;\n    },\n\n    dispatchException: function(exception) {\n      if (this.done) {\n        throw exception;\n      }\n\n      var context = this;\n      function handle(loc, caught) {\n        record.type = \"throw\";\n        record.arg = exception;\n        context.next = loc;\n        return !!caught;\n      }\n\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        var record = entry.completion;\n\n        if (entry.tryLoc === \"root\") {\n          // Exception thrown outside of any try block that could handle\n          // it, so set the completion value of the entire function to\n          // throw the exception.\n          return handle(\"end\");\n        }\n\n        if (entry.tryLoc <= this.prev) {\n          var hasCatch = hasOwn.call(entry, \"catchLoc\");\n          var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n          if (hasCatch && hasFinally) {\n            if (this.prev < entry.catchLoc) {\n              return handle(entry.catchLoc, true);\n            } else if (this.prev < entry.finallyLoc) {\n              return handle(entry.finallyLoc);\n            }\n\n          } else if (hasCatch) {\n            if (this.prev < entry.catchLoc) {\n              return handle(entry.catchLoc, true);\n            }\n\n          } else if (hasFinally) {\n            if (this.prev < entry.finallyLoc) {\n              return handle(entry.finallyLoc);\n            }\n\n          } else {\n            throw new Error(\"try statement without catch or finally\");\n          }\n        }\n      }\n    },\n\n    abrupt: function(type, arg) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.tryLoc <= this.prev &&\n            hasOwn.call(entry, \"finallyLoc\") &&\n            this.prev < entry.finallyLoc) {\n          var finallyEntry = entry;\n          break;\n        }\n      }\n\n      if (finallyEntry &&\n          (type === \"break\" ||\n           type === \"continue\") &&\n          finallyEntry.tryLoc <= arg &&\n          arg <= finallyEntry.finallyLoc) {\n        // Ignore the finally entry if control is not jumping to a\n        // location outside the try/catch block.\n        finallyEntry = null;\n      }\n\n      var record = finallyEntry ? finallyEntry.completion : {};\n      record.type = type;\n      record.arg = arg;\n\n      if (finallyEntry) {\n        this.next = finallyEntry.finallyLoc;\n      } else {\n        this.complete(record);\n      }\n\n      return ContinueSentinel;\n    },\n\n    complete: function(record, afterLoc) {\n      if (record.type === \"throw\") {\n        throw record.arg;\n      }\n\n      if (record.type === \"break\" ||\n          record.type === \"continue\") {\n        this.next = record.arg;\n      } else if (record.type === \"return\") {\n        this.rval = record.arg;\n        this.next = \"end\";\n      } else if (record.type === \"normal\" && afterLoc) {\n        this.next = afterLoc;\n      }\n    },\n\n    finish: function(finallyLoc) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.finallyLoc === finallyLoc) {\n          this.complete(entry.completion, entry.afterLoc);\n          resetTryEntry(entry);\n          return ContinueSentinel;\n        }\n      }\n    },\n\n    \"catch\": function(tryLoc) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.tryLoc === tryLoc) {\n          var record = entry.completion;\n          if (record.type === \"throw\") {\n            var thrown = record.arg;\n            resetTryEntry(entry);\n          }\n          return thrown;\n        }\n      }\n\n      // The context.catch method must only be called with a location\n      // argument that corresponds to a known catch block.\n      throw new Error(\"illegal catch attempt\");\n    },\n\n    delegateYield: function(iterable, resultName, nextLoc) {\n      this.delegate = {\n        iterator: values(iterable),\n        resultName: resultName,\n        nextLoc: nextLoc\n      };\n\n      return ContinueSentinel;\n    }\n  };\n})(\n  // Among the various tricks for obtaining a reference to the global\n  // object, this seems to be the most reliable technique that does not\n  // use indirect eval (which violates Content Security Policy).\n  typeof global === \"object\" ? global :\n  typeof window === \"object\" ? window :\n  typeof self === \"object\" ? self : this\n);\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-polyfill/~/babel-regenerator-runtime/runtime.js\n ** module id = 361\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/11/15.\n */\n'use strict';\n\nvar Alt = require('alt');\nvar alt = new Alt();\n\nexport default alt;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/alt.js\n **/","/* global window */\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\nvar _bind = Function.prototype.bind;\n\nvar _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nvar _flux = require('flux');\n\nvar _utilsStateFunctions = require('./utils/StateFunctions');\n\nvar StateFunctions = _interopRequireWildcard(_utilsStateFunctions);\n\nvar _utilsFunctions = require('../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\nvar _store = require('./store');\n\nvar store = _interopRequireWildcard(_store);\n\nvar _utilsAltUtils = require('./utils/AltUtils');\n\nvar utils = _interopRequireWildcard(_utilsAltUtils);\n\nvar _actions = require('./actions');\n\nvar _actions2 = _interopRequireDefault(_actions);\n\nvar Alt = (function () {\n  function Alt() {\n    var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n    _classCallCheck(this, Alt);\n\n    this.config = config;\n    this.serialize = config.serialize || JSON.stringify;\n    this.deserialize = config.deserialize || JSON.parse;\n    this.dispatcher = config.dispatcher || new _flux.Dispatcher();\n    this.batchingFunction = config.batchingFunction || function (callback) {\n      return callback();\n    };\n    this.actions = { global: {} };\n    this.stores = {};\n    this.storeTransforms = config.storeTransforms || [];\n    this.trapAsync = false;\n    this._actionsRegistry = {};\n    this._initSnapshot = {};\n    this._lastSnapshot = {};\n  }\n\n  _createClass(Alt, [{\n    key: 'dispatch',\n    value: function dispatch(action, data, details) {\n      var _this = this;\n\n      this.batchingFunction(function () {\n        var id = Math.random().toString(18).substr(2, 16);\n\n        // support straight dispatching of FSA-style actions\n        if (action.hasOwnProperty('type') && action.hasOwnProperty('payload')) {\n          var fsaDetails = {\n            id: action.type,\n            namespace: action.type,\n            name: action.type\n          };\n          return _this.dispatcher.dispatch(utils.fsa(id, action.type, action.payload, fsaDetails));\n        }\n\n        if (action.id && action.dispatch) {\n          return utils.dispatch(id, action, data, _this);\n        }\n\n        return _this.dispatcher.dispatch(utils.fsa(id, action, data, details));\n      });\n    }\n  }, {\n    key: 'createUnsavedStore',\n    value: function createUnsavedStore(StoreModel) {\n      var key = StoreModel.displayName || '';\n      store.createStoreConfig(this.config, StoreModel);\n      var Store = store.transformStore(this.storeTransforms, StoreModel);\n\n      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n        args[_key - 1] = arguments[_key];\n      }\n\n      return fn.isFunction(Store) ? store.createStoreFromClass.apply(store, [this, Store, key].concat(args)) : store.createStoreFromObject(this, Store, key);\n    }\n  }, {\n    key: 'createStore',\n    value: function createStore(StoreModel, iden) {\n      var key = iden || StoreModel.displayName || StoreModel.name || '';\n      store.createStoreConfig(this.config, StoreModel);\n      var Store = store.transformStore(this.storeTransforms, StoreModel);\n\n      /* istanbul ignore next */\n      if (module.hot) delete this.stores[key];\n\n      if (this.stores[key] || !key) {\n        if (this.stores[key]) {\n          utils.warn('A store named ' + key + ' already exists, double check your store ' + 'names or pass in your own custom identifier for each store');\n        } else {\n          utils.warn('Store name was not specified');\n        }\n\n        key = utils.uid(this.stores, key);\n      }\n\n      for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {\n        args[_key2 - 2] = arguments[_key2];\n      }\n\n      var storeInstance = fn.isFunction(Store) ? store.createStoreFromClass.apply(store, [this, Store, key].concat(args)) : store.createStoreFromObject(this, Store, key);\n\n      this.stores[key] = storeInstance;\n      StateFunctions.saveInitialSnapshot(this, key);\n\n      return storeInstance;\n    }\n  }, {\n    key: 'generateActions',\n    value: function generateActions() {\n      var actions = { name: 'global' };\n\n      for (var _len3 = arguments.length, actionNames = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n        actionNames[_key3] = arguments[_key3];\n      }\n\n      return this.createActions(actionNames.reduce(function (obj, action) {\n        obj[action] = utils.dispatchIdentity;\n        return obj;\n      }, actions));\n    }\n  }, {\n    key: 'createAction',\n    value: function createAction(name, implementation, obj) {\n      return (0, _actions2['default'])(this, 'global', name, implementation, obj);\n    }\n  }, {\n    key: 'createActions',\n    value: function createActions(ActionsClass) {\n      var _arguments2 = arguments,\n          _this2 = this;\n\n      var exportObj = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n      var actions = {};\n      var key = utils.uid(this._actionsRegistry, ActionsClass.displayName || ActionsClass.name || 'Unknown');\n\n      if (fn.isFunction(ActionsClass)) {\n        var _len4, argsForConstructor, _key4;\n\n        (function () {\n          fn.assign(actions, utils.getInternalMethods(ActionsClass, true));\n\n          var ActionsGenerator = (function (_ActionsClass) {\n            _inherits(ActionsGenerator, _ActionsClass);\n\n            function ActionsGenerator() {\n              _classCallCheck(this, ActionsGenerator);\n\n              for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {\n                args[_key5] = arguments[_key5];\n              }\n\n              _get(Object.getPrototypeOf(ActionsGenerator.prototype), 'constructor', this).apply(this, args);\n            }\n\n            _createClass(ActionsGenerator, [{\n              key: 'generateActions',\n              value: function generateActions() {\n                for (var _len6 = arguments.length, actionNames = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n                  actionNames[_key6] = arguments[_key6];\n                }\n\n                actionNames.forEach(function (actionName) {\n                  actions[actionName] = utils.dispatchIdentity;\n                });\n              }\n            }]);\n\n            return ActionsGenerator;\n          })(ActionsClass);\n\n          for (_len4 = _arguments2.length, argsForConstructor = Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {\n            argsForConstructor[_key4 - 2] = _arguments2[_key4];\n          }\n\n          fn.assign(actions, new (_bind.apply(ActionsGenerator, [null].concat(_toConsumableArray(argsForConstructor))))());\n        })();\n      } else {\n        fn.assign(actions, ActionsClass);\n      }\n\n      this.actions[key] = this.actions[key] || {};\n\n      fn.eachObject(function (actionName, action) {\n        if (!fn.isFunction(action)) {\n          return;\n        }\n\n        // create the action\n        exportObj[actionName] = (0, _actions2['default'])(_this2, key, actionName, action, exportObj);\n\n        // generate a constant\n        var constant = utils.formatAsConstant(actionName);\n        exportObj[constant] = exportObj[actionName].id;\n      }, [actions]);\n      return exportObj;\n    }\n  }, {\n    key: 'takeSnapshot',\n    value: function takeSnapshot() {\n      for (var _len7 = arguments.length, storeNames = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {\n        storeNames[_key7] = arguments[_key7];\n      }\n\n      var state = StateFunctions.snapshot(this, storeNames);\n      fn.assign(this._lastSnapshot, state);\n      return this.serialize(state);\n    }\n  }, {\n    key: 'rollback',\n    value: function rollback() {\n      StateFunctions.setAppState(this, this.serialize(this._lastSnapshot), function (storeInst) {\n        storeInst.lifecycle('rollback');\n        storeInst.emitChange();\n      });\n    }\n  }, {\n    key: 'recycle',\n    value: function recycle() {\n      for (var _len8 = arguments.length, storeNames = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {\n        storeNames[_key8] = arguments[_key8];\n      }\n\n      var initialSnapshot = storeNames.length ? StateFunctions.filterSnapshots(this, this._initSnapshot, storeNames) : this._initSnapshot;\n\n      StateFunctions.setAppState(this, this.serialize(initialSnapshot), function (storeInst) {\n        storeInst.lifecycle('init');\n        storeInst.emitChange();\n      });\n    }\n  }, {\n    key: 'flush',\n    value: function flush() {\n      var state = this.serialize(StateFunctions.snapshot(this));\n      this.recycle();\n      return state;\n    }\n  }, {\n    key: 'bootstrap',\n    value: function bootstrap(data) {\n      StateFunctions.setAppState(this, data, function (storeInst, state) {\n        storeInst.lifecycle('bootstrap', state);\n        storeInst.emitChange();\n      });\n    }\n  }, {\n    key: 'prepare',\n    value: function prepare(storeInst, payload) {\n      var data = {};\n      if (!storeInst.displayName) {\n        throw new ReferenceError('Store provided does not have a name');\n      }\n      data[storeInst.displayName] = payload;\n      return this.serialize(data);\n    }\n\n    // Instance type methods for injecting alt into your application as context\n\n  }, {\n    key: 'addActions',\n    value: function addActions(name, ActionsClass) {\n      for (var _len9 = arguments.length, args = Array(_len9 > 2 ? _len9 - 2 : 0), _key9 = 2; _key9 < _len9; _key9++) {\n        args[_key9 - 2] = arguments[_key9];\n      }\n\n      this.actions[name] = Array.isArray(ActionsClass) ? this.generateActions.apply(this, ActionsClass) : this.createActions.apply(this, [ActionsClass].concat(args));\n    }\n  }, {\n    key: 'addStore',\n    value: function addStore(name, StoreModel) {\n      for (var _len10 = arguments.length, args = Array(_len10 > 2 ? _len10 - 2 : 0), _key10 = 2; _key10 < _len10; _key10++) {\n        args[_key10 - 2] = arguments[_key10];\n      }\n\n      this.createStore.apply(this, [StoreModel, name].concat(args));\n    }\n  }, {\n    key: 'getActions',\n    value: function getActions(name) {\n      return this.actions[name];\n    }\n  }, {\n    key: 'getStore',\n    value: function getStore(name) {\n      return this.stores[name];\n    }\n  }], [{\n    key: 'debug',\n    value: function debug(name, alt) {\n      var key = 'alt.js.org';\n      if (typeof window !== 'undefined') {\n        window[key] = window[key] || [];\n        window[key].push({ name: name, alt: alt });\n      }\n      return alt;\n    }\n  }]);\n\n  return Alt;\n})();\n\nexports['default'] = Alt;\nmodule.exports = exports['default'];\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/index.js\n ** module id = 363\n ** module chunks = 0\n **/","/**\n * Copyright (c) 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\nmodule.exports.Dispatcher = require('./lib/Dispatcher')\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/~/flux/index.js\n ** module id = 364\n ** module chunks = 0\n **/","/*\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule Dispatcher\n * @typechecks\n */\n\n\"use strict\";\n\nvar invariant = require('./invariant');\n\nvar _lastID = 1;\nvar _prefix = 'ID_';\n\n/**\n * Dispatcher is used to broadcast payloads to registered callbacks. This is\n * different from generic pub-sub systems in two ways:\n *\n *   1) Callbacks are not subscribed to particular events. Every payload is\n *      dispatched to every registered callback.\n *   2) Callbacks can be deferred in whole or part until other callbacks have\n *      been executed.\n *\n * For example, consider this hypothetical flight destination form, which\n * selects a default city when a country is selected:\n *\n *   var flightDispatcher = new Dispatcher();\n *\n *   // Keeps track of which country is selected\n *   var CountryStore = {country: null};\n *\n *   // Keeps track of which city is selected\n *   var CityStore = {city: null};\n *\n *   // Keeps track of the base flight price of the selected city\n *   var FlightPriceStore = {price: null}\n *\n * When a user changes the selected city, we dispatch the payload:\n *\n *   flightDispatcher.dispatch({\n *     actionType: 'city-update',\n *     selectedCity: 'paris'\n *   });\n *\n * This payload is digested by `CityStore`:\n *\n *   flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'city-update') {\n *       CityStore.city = payload.selectedCity;\n *     }\n *   });\n *\n * When the user selects a country, we dispatch the payload:\n *\n *   flightDispatcher.dispatch({\n *     actionType: 'country-update',\n *     selectedCountry: 'australia'\n *   });\n *\n * This payload is digested by both stores:\n *\n *    CountryStore.dispatchToken = flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'country-update') {\n *       CountryStore.country = payload.selectedCountry;\n *     }\n *   });\n *\n * When the callback to update `CountryStore` is registered, we save a reference\n * to the returned token. Using this token with `waitFor()`, we can guarantee\n * that `CountryStore` is updated before the callback that updates `CityStore`\n * needs to query its data.\n *\n *   CityStore.dispatchToken = flightDispatcher.register(function(payload) {\n *     if (payload.actionType === 'country-update') {\n *       // `CountryStore.country` may not be updated.\n *       flightDispatcher.waitFor([CountryStore.dispatchToken]);\n *       // `CountryStore.country` is now guaranteed to be updated.\n *\n *       // Select the default city for the new country\n *       CityStore.city = getDefaultCityForCountry(CountryStore.country);\n *     }\n *   });\n *\n * The usage of `waitFor()` can be chained, for example:\n *\n *   FlightPriceStore.dispatchToken =\n *     flightDispatcher.register(function(payload) {\n *       switch (payload.actionType) {\n *         case 'country-update':\n *           flightDispatcher.waitFor([CityStore.dispatchToken]);\n *           FlightPriceStore.price =\n *             getFlightPriceStore(CountryStore.country, CityStore.city);\n *           break;\n *\n *         case 'city-update':\n *           FlightPriceStore.price =\n *             FlightPriceStore(CountryStore.country, CityStore.city);\n *           break;\n *     }\n *   });\n *\n * The `country-update` payload will be guaranteed to invoke the stores'\n * registered callbacks in order: `CountryStore`, `CityStore`, then\n * `FlightPriceStore`.\n */\n\n  function Dispatcher() {\n    this.$Dispatcher_callbacks = {};\n    this.$Dispatcher_isPending = {};\n    this.$Dispatcher_isHandled = {};\n    this.$Dispatcher_isDispatching = false;\n    this.$Dispatcher_pendingPayload = null;\n  }\n\n  /**\n   * Registers a callback to be invoked with every dispatched payload. Returns\n   * a token that can be used with `waitFor()`.\n   *\n   * @param {function} callback\n   * @return {string}\n   */\n  Dispatcher.prototype.register=function(callback) {\n    var id = _prefix + _lastID++;\n    this.$Dispatcher_callbacks[id] = callback;\n    return id;\n  };\n\n  /**\n   * Removes a callback based on its token.\n   *\n   * @param {string} id\n   */\n  Dispatcher.prototype.unregister=function(id) {\n    invariant(\n      this.$Dispatcher_callbacks[id],\n      'Dispatcher.unregister(...): `%s` does not map to a registered callback.',\n      id\n    );\n    delete this.$Dispatcher_callbacks[id];\n  };\n\n  /**\n   * Waits for the callbacks specified to be invoked before continuing execution\n   * of the current callback. This method should only be used by a callback in\n   * response to a dispatched payload.\n   *\n   * @param {array<string>} ids\n   */\n  Dispatcher.prototype.waitFor=function(ids) {\n    invariant(\n      this.$Dispatcher_isDispatching,\n      'Dispatcher.waitFor(...): Must be invoked while dispatching.'\n    );\n    for (var ii = 0; ii < ids.length; ii++) {\n      var id = ids[ii];\n      if (this.$Dispatcher_isPending[id]) {\n        invariant(\n          this.$Dispatcher_isHandled[id],\n          'Dispatcher.waitFor(...): Circular dependency detected while ' +\n          'waiting for `%s`.',\n          id\n        );\n        continue;\n      }\n      invariant(\n        this.$Dispatcher_callbacks[id],\n        'Dispatcher.waitFor(...): `%s` does not map to a registered callback.',\n        id\n      );\n      this.$Dispatcher_invokeCallback(id);\n    }\n  };\n\n  /**\n   * Dispatches a payload to all registered callbacks.\n   *\n   * @param {object} payload\n   */\n  Dispatcher.prototype.dispatch=function(payload) {\n    invariant(\n      !this.$Dispatcher_isDispatching,\n      'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.'\n    );\n    this.$Dispatcher_startDispatching(payload);\n    try {\n      for (var id in this.$Dispatcher_callbacks) {\n        if (this.$Dispatcher_isPending[id]) {\n          continue;\n        }\n        this.$Dispatcher_invokeCallback(id);\n      }\n    } finally {\n      this.$Dispatcher_stopDispatching();\n    }\n  };\n\n  /**\n   * Is this Dispatcher currently dispatching.\n   *\n   * @return {boolean}\n   */\n  Dispatcher.prototype.isDispatching=function() {\n    return this.$Dispatcher_isDispatching;\n  };\n\n  /**\n   * Call the callback stored with the given id. Also do some internal\n   * bookkeeping.\n   *\n   * @param {string} id\n   * @internal\n   */\n  Dispatcher.prototype.$Dispatcher_invokeCallback=function(id) {\n    this.$Dispatcher_isPending[id] = true;\n    this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload);\n    this.$Dispatcher_isHandled[id] = true;\n  };\n\n  /**\n   * Set up bookkeeping needed when dispatching.\n   *\n   * @param {object} payload\n   * @internal\n   */\n  Dispatcher.prototype.$Dispatcher_startDispatching=function(payload) {\n    for (var id in this.$Dispatcher_callbacks) {\n      this.$Dispatcher_isPending[id] = false;\n      this.$Dispatcher_isHandled[id] = false;\n    }\n    this.$Dispatcher_pendingPayload = payload;\n    this.$Dispatcher_isDispatching = true;\n  };\n\n  /**\n   * Clear bookkeeping used for dispatching.\n   *\n   * @internal\n   */\n  Dispatcher.prototype.$Dispatcher_stopDispatching=function() {\n    this.$Dispatcher_pendingPayload = null;\n    this.$Dispatcher_isDispatching = false;\n  };\n\n\nmodule.exports = Dispatcher;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/~/flux/lib/Dispatcher.js\n ** module id = 365\n ** module chunks = 0\n **/","/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule invariant\n */\n\n\"use strict\";\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar invariant = function(condition, format, a, b, c, d, e, f) {\n  if (false) {\n    if (format === undefined) {\n      throw new Error('invariant requires an error message argument');\n    }\n  }\n\n  if (!condition) {\n    var error;\n    if (format === undefined) {\n      error = new Error(\n        'Minified exception occurred; use the non-minified dev environment ' +\n        'for the full error message and additional helpful warnings.'\n      );\n    } else {\n      var args = [a, b, c, d, e, f];\n      var argIndex = 0;\n      error = new Error(\n        'Invariant Violation: ' +\n        format.replace(/%s/g, function() { return args[argIndex++]; })\n      );\n    }\n\n    error.framesToPop = 1; // we don't care about invariant's own frame\n    throw error;\n  }\n};\n\nmodule.exports = invariant;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/~/flux/lib/invariant.js\n ** module id = 366\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\nexports.setAppState = setAppState;\nexports.snapshot = snapshot;\nexports.saveInitialSnapshot = saveInitialSnapshot;\nexports.filterSnapshots = filterSnapshots;\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _utilsFunctions = require('../../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\nfunction setAppState(instance, data, onStore) {\n  var obj = instance.deserialize(data);\n  fn.eachObject(function (key, value) {\n    var store = instance.stores[key];\n    if (store) {\n      (function () {\n        var config = store.StoreModel.config;\n\n        var state = store.state;\n        if (config.onDeserialize) obj[key] = config.onDeserialize(value) || value;\n        if (fn.isMutableObject(state)) {\n          fn.eachObject(function (k) {\n            return delete state[k];\n          }, [state]);\n          fn.assign(state, obj[key]);\n        } else {\n          store.state = obj[key];\n        }\n        onStore(store, store.state);\n      })();\n    }\n  }, [obj]);\n}\n\nfunction snapshot(instance) {\n  var storeNames = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n  var stores = storeNames.length ? storeNames : Object.keys(instance.stores);\n  return stores.reduce(function (obj, storeHandle) {\n    var storeName = storeHandle.displayName || storeHandle;\n    var store = instance.stores[storeName];\n    var config = store.StoreModel.config;\n\n    store.lifecycle('snapshot');\n    var customSnapshot = config.onSerialize && config.onSerialize(store.state);\n    obj[storeName] = customSnapshot ? customSnapshot : store.getState();\n    return obj;\n  }, {});\n}\n\nfunction saveInitialSnapshot(instance, key) {\n  var state = instance.deserialize(instance.serialize(instance.stores[key].state));\n  instance._initSnapshot[key] = state;\n  instance._lastSnapshot[key] = state;\n}\n\nfunction filterSnapshots(instance, state, stores) {\n  return stores.reduce(function (obj, store) {\n    var storeName = store.displayName || store;\n    if (!state[storeName]) {\n      throw new ReferenceError(storeName + ' is not a valid store');\n    }\n    obj[storeName] = state[storeName];\n    return obj;\n  }, {});\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/utils/StateFunctions.js\n ** module id = 367\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\nexports.isMutableObject = isMutableObject;\nexports.isPromise = isPromise;\nexports.eachObject = eachObject;\nexports.assign = assign;\nvar isFunction = function isFunction(x) {\n  return typeof x === 'function';\n};\n\nexports.isFunction = isFunction;\n\nfunction isMutableObject(target) {\n  var Ctor = target.constructor;\n\n  return !!target && typeof target === 'object' && !Object.isFrozen(target) && Object.prototype.toString.call(target) === '[object Object]' && isFunction(Ctor) && (Ctor instanceof Ctor || target.type === 'AltStore');\n}\n\nfunction isPromise(obj) {\n  return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';\n}\n\nfunction eachObject(f, o) {\n  o.forEach(function (from) {\n    Object.keys(Object(from)).forEach(function (key) {\n      f(key, from[key]);\n    });\n  });\n}\n\nfunction assign(target) {\n  for (var _len = arguments.length, source = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n    source[_key - 1] = arguments[_key];\n  }\n\n  eachObject(function (key, value) {\n    return target[key] = value;\n  }, source);\n  return target;\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/utils/functions.js\n ** module id = 368\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\nvar _bind = Function.prototype.bind;\n\nvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\nexports.createStoreConfig = createStoreConfig;\nexports.transformStore = transformStore;\nexports.createStoreFromObject = createStoreFromObject;\nexports.createStoreFromClass = createStoreFromClass;\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar _utilsAltUtils = require('../utils/AltUtils');\n\nvar utils = _interopRequireWildcard(_utilsAltUtils);\n\nvar _utilsFunctions = require('../../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\nvar _AltStore = require('./AltStore');\n\nvar _AltStore2 = _interopRequireDefault(_AltStore);\n\nvar _StoreMixin = require('./StoreMixin');\n\nvar _StoreMixin2 = _interopRequireDefault(_StoreMixin);\n\nfunction doSetState(store, storeInstance, state) {\n  if (!state) {\n    return;\n  }\n\n  var config = storeInstance.StoreModel.config;\n\n  var nextState = fn.isFunction(state) ? state(storeInstance.state) : state;\n\n  storeInstance.state = config.setState.call(store, storeInstance.state, nextState);\n\n  if (!store.alt.dispatcher.isDispatching()) {\n    store.emitChange();\n  }\n}\n\nfunction createPrototype(proto, alt, key, extras) {\n  return fn.assign(proto, _StoreMixin2['default'], {\n    displayName: key,\n    alt: alt,\n    dispatcher: alt.dispatcher,\n    preventDefault: function preventDefault() {\n      this.getInstance().preventDefault = true;\n    },\n    boundListeners: [],\n    lifecycleEvents: {},\n    actionListeners: {},\n    actionListenerHandlers: {},\n    publicMethods: {},\n    handlesOwnErrors: false\n  }, extras);\n}\n\nfunction createStoreConfig(globalConfig, StoreModel) {\n  StoreModel.config = fn.assign({\n    getState: function getState(state) {\n      if (Array.isArray(state)) {\n        return state.slice();\n      } else if (fn.isMutableObject(state)) {\n        return fn.assign({}, state);\n      }\n\n      return state;\n    },\n    setState: function setState(currentState, nextState) {\n      if (fn.isMutableObject(nextState)) {\n        return fn.assign(currentState, nextState);\n      }\n      return nextState;\n    }\n  }, globalConfig, StoreModel.config);\n}\n\nfunction transformStore(transforms, StoreModel) {\n  return transforms.reduce(function (Store, transform) {\n    return transform(Store);\n  }, StoreModel);\n}\n\nfunction createStoreFromObject(alt, StoreModel, key) {\n  var storeInstance = undefined;\n\n  var StoreProto = createPrototype({}, alt, key, fn.assign({\n    getInstance: function getInstance() {\n      return storeInstance;\n    },\n    setState: function setState(nextState) {\n      doSetState(this, storeInstance, nextState);\n    }\n  }, StoreModel));\n\n  // bind the store listeners\n  /* istanbul ignore else */\n  if (StoreProto.bindListeners) {\n    _StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.bindListeners);\n  }\n  /* istanbul ignore else */\n  if (StoreProto.observe) {\n    _StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.observe(alt));\n  }\n\n  // bind the lifecycle events\n  /* istanbul ignore else */\n  if (StoreProto.lifecycle) {\n    fn.eachObject(function (eventName, event) {\n      _StoreMixin2['default'].on.call(StoreProto, eventName, event);\n    }, [StoreProto.lifecycle]);\n  }\n\n  // create the instance and fn.assign the public methods to the instance\n  storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state !== undefined ? StoreProto.state : {}, StoreModel), StoreProto.publicMethods, {\n    displayName: key,\n    config: StoreModel.config\n  });\n\n  return storeInstance;\n}\n\nfunction createStoreFromClass(alt, StoreModel, key) {\n  var storeInstance = undefined;\n  var config = StoreModel.config;\n\n  // Creating a class here so we don't overload the provided store's\n  // prototype with the mixin behaviour and I'm extending from StoreModel\n  // so we can inherit any extensions from the provided store.\n\n  var Store = (function (_StoreModel) {\n    _inherits(Store, _StoreModel);\n\n    function Store() {\n      _classCallCheck(this, Store);\n\n      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n        args[_key2] = arguments[_key2];\n      }\n\n      _get(Object.getPrototypeOf(Store.prototype), 'constructor', this).apply(this, args);\n    }\n\n    return Store;\n  })(StoreModel);\n\n  createPrototype(Store.prototype, alt, key, {\n    type: 'AltStore',\n    getInstance: function getInstance() {\n      return storeInstance;\n    },\n    setState: function setState(nextState) {\n      doSetState(this, storeInstance, nextState);\n    }\n  });\n\n  for (var _len = arguments.length, argsForClass = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {\n    argsForClass[_key - 3] = arguments[_key];\n  }\n\n  var store = new (_bind.apply(Store, [null].concat(argsForClass)))();\n\n  if (config.bindListeners) store.bindListeners(config.bindListeners);\n  if (config.datasource) store.registerAsync(config.datasource);\n\n  storeInstance = fn.assign(new _AltStore2['default'](alt, store, store.state !== undefined ? store.state : store, StoreModel), utils.getInternalMethods(StoreModel), config.publicMethods, { displayName: key });\n\n  return storeInstance;\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/store/index.js\n ** module id = 369\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.getInternalMethods = getInternalMethods;\nexports.warn = warn;\nexports.uid = uid;\nexports.formatAsConstant = formatAsConstant;\nexports.dispatchIdentity = dispatchIdentity;\nexports.fsa = fsa;\nexports.dispatch = dispatch;\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _utilsFunctions = require('../../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\n/*eslint-disable*/\nvar builtIns = Object.getOwnPropertyNames(NoopClass);\nvar builtInProto = Object.getOwnPropertyNames(NoopClass.prototype);\n/*eslint-enable*/\n\nfunction getInternalMethods(Obj, isProto) {\n  var excluded = isProto ? builtInProto : builtIns;\n  var obj = isProto ? Obj.prototype : Obj;\n  return Object.getOwnPropertyNames(obj).reduce(function (value, m) {\n    if (excluded.indexOf(m) !== -1) {\n      return value;\n    }\n\n    value[m] = obj[m];\n    return value;\n  }, {});\n}\n\nfunction warn(msg) {\n  /* istanbul ignore else */\n  /*eslint-disable*/\n  if (typeof console !== 'undefined') {\n    console.warn(new ReferenceError(msg));\n  }\n  /*eslint-enable*/\n}\n\nfunction uid(container, name) {\n  var count = 0;\n  var key = name;\n  while (Object.hasOwnProperty.call(container, key)) {\n    key = name + String(++count);\n  }\n  return key;\n}\n\nfunction formatAsConstant(name) {\n  return name.replace(/[a-z]([A-Z])/g, function (i) {\n    return i[0] + '_' + i[1].toLowerCase();\n  }).toUpperCase();\n}\n\nfunction dispatchIdentity(x) {\n  for (var _len = arguments.length, a = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n    a[_key - 1] = arguments[_key];\n  }\n\n  this.dispatch(a.length ? [x].concat(a) : x);\n}\n\nfunction fsa(id, type, payload, details) {\n  return {\n    type: type,\n    payload: payload,\n    meta: _extends({\n      dispatchId: id\n    }, details),\n\n    id: id,\n    action: type,\n    data: payload,\n    details: details\n  };\n}\n\nfunction dispatch(id, actionObj, payload, alt) {\n  var data = actionObj.dispatch(payload);\n  if (data === undefined) return null;\n\n  var type = actionObj.id;\n  var namespace = type;\n  var name = type;\n  var details = { id: type, namespace: namespace, name: name };\n\n  var dispatchLater = function dispatchLater(x) {\n    return alt.dispatch(type, x, details);\n  };\n\n  if (fn.isFunction(data)) return data(dispatchLater, alt);\n\n  // XXX standardize this\n  return alt.dispatcher.dispatch(fsa(id, type, data, details));\n}\n\n/* istanbul ignore next */\nfunction NoopClass() {}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/utils/AltUtils.js\n ** module id = 370\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nvar _utilsFunctions = require('../../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\nvar _transmitter = require('transmitter');\n\nvar _transmitter2 = _interopRequireDefault(_transmitter);\n\nvar AltStore = (function () {\n  function AltStore(alt, model, state, StoreModel) {\n    var _this = this;\n\n    _classCallCheck(this, AltStore);\n\n    var lifecycleEvents = model.lifecycleEvents;\n    this.transmitter = (0, _transmitter2['default'])();\n    this.lifecycle = function (event, x) {\n      if (lifecycleEvents[event]) lifecycleEvents[event].push(x);\n    };\n    this.state = state;\n\n    this.alt = alt;\n    this.preventDefault = false;\n    this.displayName = model.displayName;\n    this.boundListeners = model.boundListeners;\n    this.StoreModel = StoreModel;\n    this.reduce = model.reduce || function (x) {\n      return x;\n    };\n\n    var output = model.output || function (x) {\n      return x;\n    };\n\n    this.emitChange = function () {\n      return _this.transmitter.push(output(_this.state));\n    };\n\n    var handleDispatch = function handleDispatch(f, payload) {\n      try {\n        return f();\n      } catch (e) {\n        if (model.handlesOwnErrors) {\n          _this.lifecycle('error', {\n            error: e,\n            payload: payload,\n            state: _this.state\n          });\n          return false;\n        }\n\n        throw e;\n      }\n    };\n\n    fn.assign(this, model.publicMethods);\n\n    // Register dispatcher\n    this.dispatchToken = alt.dispatcher.register(function (payload) {\n      _this.preventDefault = false;\n\n      _this.lifecycle('beforeEach', {\n        payload: payload,\n        state: _this.state\n      });\n\n      var actionHandlers = model.actionListeners[payload.action];\n\n      if (actionHandlers || model.otherwise) {\n        var result = undefined;\n\n        if (actionHandlers) {\n          result = handleDispatch(function () {\n            return actionHandlers.filter(Boolean).every(function (handler) {\n              return handler.call(model, payload.data, payload.action) !== false;\n            });\n          }, payload);\n        } else {\n          result = handleDispatch(function () {\n            return model.otherwise(payload.data, payload.action);\n          }, payload);\n        }\n\n        if (result !== false && !_this.preventDefault) _this.emitChange();\n      }\n\n      if (model.reduce) {\n        handleDispatch(function () {\n          var value = model.reduce(_this.state, payload);\n          if (value !== undefined) _this.state = value;\n        }, payload);\n        if (!_this.preventDefault) _this.emitChange();\n      }\n\n      _this.lifecycle('afterEach', {\n        payload: payload,\n        state: _this.state\n      });\n    });\n\n    this.lifecycle('init');\n  }\n\n  _createClass(AltStore, [{\n    key: 'listen',\n    value: function listen(cb) {\n      var _this2 = this;\n\n      if (!fn.isFunction(cb)) throw new TypeError('listen expects a function');\n      this.transmitter.subscribe(cb);\n      return function () {\n        return _this2.unlisten(cb);\n      };\n    }\n  }, {\n    key: 'unlisten',\n    value: function unlisten(cb) {\n      this.lifecycle('unlisten');\n      this.transmitter.unsubscribe(cb);\n    }\n  }, {\n    key: 'getState',\n    value: function getState() {\n      return this.StoreModel.config.getState.call(this, this.state);\n    }\n  }]);\n\n  return AltStore;\n})();\n\nexports['default'] = AltStore;\nmodule.exports = exports['default'];\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/store/AltStore.js\n ** module id = 371\n ** module chunks = 0\n **/","\"use strict\";\n\nfunction transmitter() {\n  var subscriptions = [];\n\n  var unsubscribe = function unsubscribe(onChange) {\n    var id = subscriptions.indexOf(onChange);\n    if (id >= 0) subscriptions.splice(id, 1);\n  };\n\n  var subscribe = function subscribe(onChange) {\n    subscriptions.push(onChange);\n    var dispose = function dispose() {\n      return unsubscribe(onChange);\n    };\n    return { dispose: dispose };\n  };\n\n  var push = function push(value) {\n    subscriptions.forEach(function (subscription) {\n      return subscription(value);\n    });\n  };\n\n  return { subscribe: subscribe, push: push, unsubscribe: unsubscribe };\n}\n\nmodule.exports = transmitter;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/~/transmitter/dist/transmitter.js\n ** module id = 372\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _transmitter = require('transmitter');\n\nvar _transmitter2 = _interopRequireDefault(_transmitter);\n\nvar _utilsFunctions = require('../../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\nvar StoreMixin = {\n  waitFor: function waitFor() {\n    for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {\n      sources[_key] = arguments[_key];\n    }\n\n    if (!sources.length) {\n      throw new ReferenceError('Dispatch tokens not provided');\n    }\n\n    var sourcesArray = sources;\n    if (sources.length === 1) {\n      sourcesArray = Array.isArray(sources[0]) ? sources[0] : sources;\n    }\n\n    var tokens = sourcesArray.map(function (source) {\n      return source.dispatchToken || source;\n    });\n\n    this.dispatcher.waitFor(tokens);\n  },\n\n  exportAsync: function exportAsync(asyncMethods) {\n    this.registerAsync(asyncMethods);\n  },\n\n  registerAsync: function registerAsync(asyncDef) {\n    var _this = this;\n\n    var loadCounter = 0;\n\n    var asyncMethods = fn.isFunction(asyncDef) ? asyncDef(this.alt) : asyncDef;\n\n    var toExport = Object.keys(asyncMethods).reduce(function (publicMethods, methodName) {\n      var desc = asyncMethods[methodName];\n      var spec = fn.isFunction(desc) ? desc(_this) : desc;\n\n      var validHandlers = ['success', 'error', 'loading'];\n      validHandlers.forEach(function (handler) {\n        if (spec[handler] && !spec[handler].id) {\n          throw new Error(handler + ' handler must be an action function');\n        }\n      });\n\n      publicMethods[methodName] = function () {\n        for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n          args[_key2] = arguments[_key2];\n        }\n\n        var state = _this.getInstance().getState();\n        var value = spec.local && spec.local.apply(spec, [state].concat(args));\n        var shouldFetch = spec.shouldFetch ? spec.shouldFetch.apply(spec, [state].concat(args))\n        /*eslint-disable*/\n        : value == null;\n        /*eslint-enable*/\n        var intercept = spec.interceptResponse || function (x) {\n          return x;\n        };\n\n        var makeActionHandler = function makeActionHandler(action, isError) {\n          return function (x) {\n            var fire = function fire() {\n              loadCounter -= 1;\n              action(intercept(x, action, args));\n              if (isError) throw x;\n            };\n            return _this.alt.trapAsync ? function () {\n              return fire();\n            } : fire();\n          };\n        };\n\n        // if we don't have it in cache then fetch it\n        if (shouldFetch) {\n          loadCounter += 1;\n          /* istanbul ignore else */\n          if (spec.loading) spec.loading(intercept(null, spec.loading, args));\n          return spec.remote.apply(spec, [state].concat(args)).then(makeActionHandler(spec.success), makeActionHandler(spec.error, 1));\n        }\n\n        // otherwise emit the change now\n        _this.emitChange();\n        return value;\n      };\n\n      return publicMethods;\n    }, {});\n\n    this.exportPublicMethods(toExport);\n    this.exportPublicMethods({\n      isLoading: function isLoading() {\n        return loadCounter > 0;\n      }\n    });\n  },\n\n  exportPublicMethods: function exportPublicMethods(methods) {\n    var _this2 = this;\n\n    fn.eachObject(function (methodName, value) {\n      if (!fn.isFunction(value)) {\n        throw new TypeError('exportPublicMethods expects a function');\n      }\n\n      _this2.publicMethods[methodName] = value;\n    }, [methods]);\n  },\n\n  emitChange: function emitChange() {\n    this.getInstance().emitChange();\n  },\n\n  on: function on(lifecycleEvent, handler) {\n    if (lifecycleEvent === 'error') this.handlesOwnErrors = true;\n    var bus = this.lifecycleEvents[lifecycleEvent] || (0, _transmitter2['default'])();\n    this.lifecycleEvents[lifecycleEvent] = bus;\n    return bus.subscribe(handler.bind(this));\n  },\n\n  bindAction: function bindAction(symbol, handler) {\n    if (!symbol) {\n      throw new ReferenceError('Invalid action reference passed in');\n    }\n    if (!fn.isFunction(handler)) {\n      throw new TypeError('bindAction expects a function');\n    }\n\n    if (handler.length > 1) {\n      throw new TypeError('Action handler in store ' + this.displayName + ' for ' + ((symbol.id || symbol).toString() + ' was defined with ') + 'two parameters. Only a single parameter is passed through the ' + 'dispatcher, did you mean to pass in an Object instead?');\n    }\n\n    // You can pass in the constant or the function itself\n    var key = symbol.id ? symbol.id : symbol;\n    this.actionListeners[key] = this.actionListeners[key] || [];\n    this.actionListenerHandlers[key] = this.actionListenerHandlers[key] || [];\n\n    if (this.actionListenerHandlers[key].indexOf(handler) === -1) {\n      this.actionListenerHandlers[key].push(handler);\n      this.actionListeners[key].push(handler.bind(this));\n    }\n\n    this.boundListeners.push(key);\n  },\n\n  bindActions: function bindActions(actions) {\n    var _this3 = this;\n\n    fn.eachObject(function (action, symbol) {\n      var matchFirstCharacter = /./;\n      var assumedEventHandler = action.replace(matchFirstCharacter, function (x) {\n        return 'on' + x[0].toUpperCase();\n      });\n\n      if (_this3[action] && _this3[assumedEventHandler]) {\n        // If you have both action and onAction\n        throw new ReferenceError('You have multiple action handlers bound to an action: ' + (action + ' and ' + assumedEventHandler));\n      }\n\n      var handler = _this3[action] || _this3[assumedEventHandler];\n      if (handler) {\n        _this3.bindAction(symbol, handler);\n      }\n    }, [actions]);\n  },\n\n  bindListeners: function bindListeners(obj) {\n    var _this4 = this;\n\n    fn.eachObject(function (methodName, symbol) {\n      var listener = _this4[methodName];\n\n      if (!listener) {\n        throw new ReferenceError(methodName + ' defined but does not exist in ' + _this4.displayName);\n      }\n\n      if (Array.isArray(symbol)) {\n        symbol.forEach(function (action) {\n          _this4.bindAction(action, listener);\n        });\n      } else {\n        _this4.bindAction(symbol, listener);\n      }\n    }, [obj]);\n  }\n};\n\nexports['default'] = StoreMixin;\nmodule.exports = exports['default'];\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/store/StoreMixin.js\n ** module id = 373\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nexports['default'] = makeAction;\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nvar _utilsFunctions = require('../../utils/functions');\n\nvar fn = _interopRequireWildcard(_utilsFunctions);\n\nvar _utilsAltUtils = require('../utils/AltUtils');\n\nvar utils = _interopRequireWildcard(_utilsAltUtils);\n\nvar AltAction = (function () {\n  function AltAction(alt, id, action, actions, actionDetails) {\n    _classCallCheck(this, AltAction);\n\n    this.id = id;\n    this._dispatch = action.bind(this);\n    this.actions = actions;\n    this.actionDetails = actionDetails;\n    this.alt = alt;\n  }\n\n  _createClass(AltAction, [{\n    key: 'dispatch',\n    value: function dispatch(data) {\n      this.dispatched = true;\n      this.alt.dispatch(this.id, data, this.actionDetails);\n    }\n  }]);\n\n  return AltAction;\n})();\n\nfunction makeAction(alt, namespace, name, implementation, obj) {\n  var id = utils.uid(alt._actionsRegistry, namespace + '.' + name);\n  alt._actionsRegistry[id] = 1;\n\n  var data = { id: id, namespace: namespace, name: name };\n\n  // Wrap the action so we can provide a dispatch method\n  var newAction = new AltAction(alt, id, implementation, obj, data);\n\n  var dispatch = function dispatch(payload) {\n    return alt.dispatch(id, payload, data);\n  };\n\n  // the action itself\n  var action = function action() {\n    newAction.dispatched = false;\n    var result = newAction._dispatch.apply(newAction, arguments);\n    // async functions that return promises should not be dispatched\n    if (!newAction.dispatched && result !== undefined && !fn.isPromise(result)) {\n      if (fn.isFunction(result)) {\n        result(dispatch, alt);\n      } else {\n        dispatch(result);\n      }\n    }\n\n    return result;\n  };\n  action.defer = function () {\n    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    setTimeout(function () {\n      newAction._dispatch.apply(null, args);\n    });\n  };\n  action.id = id;\n  action.data = data;\n\n  // ensure each reference is unique in the namespace\n  var container = alt.actions[namespace];\n  var namespaceId = utils.uid(container, name);\n  container[namespaceId] = action;\n\n  return action;\n}\n\nmodule.exports = exports['default'];\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/alt/lib/actions/index.js\n ** module id = 374\n ** module chunks = 0\n **/","'use strict';\n\nvar isReactClassish = require('./isReactClassish'),\n    isReactElementish = require('./isReactElementish');\n\nfunction makeExportsHot(m, React) {\n  if (isReactElementish(m.exports, React)) {\n    // React elements are never valid React classes\n    return false;\n  }\n\n  var freshExports = m.exports,\n      exportsReactClass = isReactClassish(m.exports, React),\n      foundReactClasses = false;\n\n  if (exportsReactClass) {\n    m.exports = m.makeHot(m.exports, '__MODULE_EXPORTS');\n    foundReactClasses = true;\n  }\n\n  for (var key in m.exports) {\n    if (!Object.prototype.hasOwnProperty.call(freshExports, key)) {\n      continue;\n    }\n\n    if (exportsReactClass && key === 'type') {\n      // React 0.12 also puts classes under `type` property for compat.\n      // Skip to avoid updating twice.\n      continue;\n    }\n\n    var value;\n    try {\n      value = freshExports[key];\n    } catch (err) {\n      continue;\n    }\n\n    if (!isReactClassish(value, React)) {\n      continue;\n    }\n\n    if (Object.getOwnPropertyDescriptor(m.exports, key).writable) {\n      m.exports[key] = m.makeHot(value, '__MODULE_EXPORTS_' + key);\n      foundReactClasses = true;\n    } else {\n      console.warn(\"Can't make class \" + key + \" hot reloadable due to being read-only. To fix this you can try two solutions. First, you can exclude files or directories (for example, /node_modules/) using 'exclude' option in loader configuration. Second, if you are using Babel, you can enable loose mode for `es6.modules` using the 'loose' option. See: http://babeljs.io/docs/advanced/loose/ and http://babeljs.io/docs/usage/options/\");\n    }\n  }\n\n  return foundReactClasses;\n}\n\nmodule.exports = makeExportsHot;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/makeExportsHot.js\n ** module id = 375\n ** module chunks = 0\n **/","function hasRender(Class) {\n  var prototype = Class.prototype;\n  if (!prototype) {\n    return false;\n  }\n\n  return typeof prototype.render === 'function';\n}\n\nfunction descendsFromReactComponent(Class, React) {\n  if (!React.Component) {\n    return false;\n  }\n\n  var Base = Object.getPrototypeOf(Class);\n  while (Base) {\n    if (Base === React.Component) {\n      return true;\n    }\n\n    Base = Object.getPrototypeOf(Base);\n  }\n\n  return false;\n}\n\nfunction isReactClassish(Class, React) {\n  if (typeof Class !== 'function') {\n    return false;\n  }\n\n  // React 0.13\n  if (hasRender(Class) || descendsFromReactComponent(Class, React)) {\n    return true;\n  }\n\n  // React 0.12 and earlier\n  if (Class.type && hasRender(Class.type)) {\n    return true;\n  }\n\n  return false;\n}\n\nmodule.exports = isReactClassish;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/isReactClassish.js\n ** module id = 376\n ** module chunks = 0\n **/","var isReactClassish = require('./isReactClassish');\n\nfunction isReactElementish(obj, React) {\n  if (!obj) {\n    return false;\n  }\n\n  return Object.prototype.toString.call(obj.props) === '[object Object]' &&\n         isReactClassish(obj.type, React);\n}\n\nmodule.exports = isReactElementish;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-hot-loader/isReactElementish.js\n ** module id = 377\n ** module chunks = 0\n **/","/**\n * Created by onvelocity on 2/12/16.\n */\n'use strict';\nimport d3 from 'd3'\nimport guid from './guid'\nimport DescriptorModel from './model/DescriptorModel'\nexport default class UID {\n\n\tstatic get propertyName() {\n\t\treturn ':uid';\n\t}\n\n\tstatic create() {\n\t\treturn guid();\n\t}\n\n\tstatic from(obj) {\n\t\tif (!obj || /undefined|null/.test(obj)) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj instanceof DescriptorModel) {\n\t\t\t// a descriptor instance\n\t\t\treturn obj.uid;\n\t\t}\n\t\tif (obj.dataset && obj.dataset.uid) {\n\t\t\t// DOM Element\n\t\t\tobj = obj.dataset.uid;\n\t\t} else if (obj.__data__ && obj.__data__.uid) {\n\t\t\t// d3 managed element\n\t\t\tobj = obj.__data__.uid;\n\t\t} else if (obj instanceof Element) {\n\t\t\tobj = d3.select(obj).attr('data-uid');\n\t\t}\n\t\tif (!obj || /undefined|null/.test(obj)) {\n\t\t\treturn;\n\t\t}\n\t\tconst uid = typeof obj === 'object' ? obj[UID.propertyName] || (obj.meta && obj.meta[UID.propertyName]) : obj;\n\t\tif (typeof uid === 'string') {\n\t\t\treturn uid;\n\t\t}\n\t}\n\n\tstatic hasUniqueId(obj) {\n\t\treturn !!UID.from(obj);\n\t}\n\n\tstatic assignUniqueId(obj) {\n\t\treturn obj[UID.propertyName] = UID.create();\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/UniqueId.js\n **/","!function() {\n  var d3 = {\n    version: \"3.5.10\"\n  };\n  var d3_arraySlice = [].slice, d3_array = function(list) {\n    return d3_arraySlice.call(list);\n  };\n  var d3_document = this.document;\n  function d3_documentElement(node) {\n    return node && (node.ownerDocument || node.document || node).documentElement;\n  }\n  function d3_window(node) {\n    return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView);\n  }\n  if (d3_document) {\n    try {\n      d3_array(d3_document.documentElement.childNodes)[0].nodeType;\n    } catch (e) {\n      d3_array = function(list) {\n        var i = list.length, array = new Array(i);\n        while (i--) array[i] = list[i];\n        return array;\n      };\n    }\n  }\n  if (!Date.now) Date.now = function() {\n    return +new Date();\n  };\n  if (d3_document) {\n    try {\n      d3_document.createElement(\"DIV\").style.setProperty(\"opacity\", 0, \"\");\n    } catch (error) {\n      var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;\n      d3_element_prototype.setAttribute = function(name, value) {\n        d3_element_setAttribute.call(this, name, value + \"\");\n      };\n      d3_element_prototype.setAttributeNS = function(space, local, value) {\n        d3_element_setAttributeNS.call(this, space, local, value + \"\");\n      };\n      d3_style_prototype.setProperty = function(name, value, priority) {\n        d3_style_setProperty.call(this, name, value + \"\", priority);\n      };\n    }\n  }\n  d3.ascending = d3_ascending;\n  function d3_ascending(a, b) {\n    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n  }\n  d3.descending = function(a, b) {\n    return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n  };\n  d3.min = function(array, f) {\n    var i = -1, n = array.length, a, b;\n    if (arguments.length === 1) {\n      while (++i < n) if ((b = array[i]) != null && b >= b) {\n        a = b;\n        break;\n      }\n      while (++i < n) if ((b = array[i]) != null && a > b) a = b;\n    } else {\n      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {\n        a = b;\n        break;\n      }\n      while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;\n    }\n    return a;\n  };\n  d3.max = function(array, f) {\n    var i = -1, n = array.length, a, b;\n    if (arguments.length === 1) {\n      while (++i < n) if ((b = array[i]) != null && b >= b) {\n        a = b;\n        break;\n      }\n      while (++i < n) if ((b = array[i]) != null && b > a) a = b;\n    } else {\n      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {\n        a = b;\n        break;\n      }\n      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;\n    }\n    return a;\n  };\n  d3.extent = function(array, f) {\n    var i = -1, n = array.length, a, b, c;\n    if (arguments.length === 1) {\n      while (++i < n) if ((b = array[i]) != null && b >= b) {\n        a = c = b;\n        break;\n      }\n      while (++i < n) if ((b = array[i]) != null) {\n        if (a > b) a = b;\n        if (c < b) c = b;\n      }\n    } else {\n      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {\n        a = c = b;\n        break;\n      }\n      while (++i < n) if ((b = f.call(array, array[i], i)) != null) {\n        if (a > b) a = b;\n        if (c < b) c = b;\n      }\n    }\n    return [ a, c ];\n  };\n  function d3_number(x) {\n    return x === null ? NaN : +x;\n  }\n  function d3_numeric(x) {\n    return !isNaN(x);\n  }\n  d3.sum = function(array, f) {\n    var s = 0, n = array.length, a, i = -1;\n    if (arguments.length === 1) {\n      while (++i < n) if (d3_numeric(a = +array[i])) s += a;\n    } else {\n      while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a;\n    }\n    return s;\n  };\n  d3.mean = function(array, f) {\n    var s = 0, n = array.length, a, i = -1, j = n;\n    if (arguments.length === 1) {\n      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;\n    } else {\n      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;\n    }\n    if (j) return s / j;\n  };\n  d3.quantile = function(values, p) {\n    var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;\n    return e ? v + e * (values[h] - v) : v;\n  };\n  d3.median = function(array, f) {\n    var numbers = [], n = array.length, a, i = -1;\n    if (arguments.length === 1) {\n      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a);\n    } else {\n      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a);\n    }\n    if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5);\n  };\n  d3.variance = function(array, f) {\n    var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0;\n    if (arguments.length === 1) {\n      while (++i < n) {\n        if (d3_numeric(a = d3_number(array[i]))) {\n          d = a - m;\n          m += d / ++j;\n          s += d * (a - m);\n        }\n      }\n    } else {\n      while (++i < n) {\n        if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) {\n          d = a - m;\n          m += d / ++j;\n          s += d * (a - m);\n        }\n      }\n    }\n    if (j > 1) return s / (j - 1);\n  };\n  d3.deviation = function() {\n    var v = d3.variance.apply(this, arguments);\n    return v ? Math.sqrt(v) : v;\n  };\n  function d3_bisector(compare) {\n    return {\n      left: function(a, x, lo, hi) {\n        if (arguments.length < 3) lo = 0;\n        if (arguments.length < 4) hi = a.length;\n        while (lo < hi) {\n          var mid = lo + hi >>> 1;\n          if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid;\n        }\n        return lo;\n      },\n      right: function(a, x, lo, hi) {\n        if (arguments.length < 3) lo = 0;\n        if (arguments.length < 4) hi = a.length;\n        while (lo < hi) {\n          var mid = lo + hi >>> 1;\n          if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1;\n        }\n        return lo;\n      }\n    };\n  }\n  var d3_bisect = d3_bisector(d3_ascending);\n  d3.bisectLeft = d3_bisect.left;\n  d3.bisect = d3.bisectRight = d3_bisect.right;\n  d3.bisector = function(f) {\n    return d3_bisector(f.length === 1 ? function(d, x) {\n      return d3_ascending(f(d), x);\n    } : f);\n  };\n  d3.shuffle = function(array, i0, i1) {\n    if ((m = arguments.length) < 3) {\n      i1 = array.length;\n      if (m < 2) i0 = 0;\n    }\n    var m = i1 - i0, t, i;\n    while (m) {\n      i = Math.random() * m-- | 0;\n      t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t;\n    }\n    return array;\n  };\n  d3.permute = function(array, indexes) {\n    var i = indexes.length, permutes = new Array(i);\n    while (i--) permutes[i] = array[indexes[i]];\n    return permutes;\n  };\n  d3.pairs = function(array) {\n    var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);\n    while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];\n    return pairs;\n  };\n  d3.zip = function() {\n    if (!(n = arguments.length)) return [];\n    for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {\n      for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {\n        zip[j] = arguments[j][i];\n      }\n    }\n    return zips;\n  };\n  function d3_zipLength(d) {\n    return d.length;\n  }\n  d3.transpose = function(matrix) {\n    return d3.zip.apply(d3, matrix);\n  };\n  d3.keys = function(map) {\n    var keys = [];\n    for (var key in map) keys.push(key);\n    return keys;\n  };\n  d3.values = function(map) {\n    var values = [];\n    for (var key in map) values.push(map[key]);\n    return values;\n  };\n  d3.entries = function(map) {\n    var entries = [];\n    for (var key in map) entries.push({\n      key: key,\n      value: map[key]\n    });\n    return entries;\n  };\n  d3.merge = function(arrays) {\n    var n = arrays.length, m, i = -1, j = 0, merged, array;\n    while (++i < n) j += arrays[i].length;\n    merged = new Array(j);\n    while (--n >= 0) {\n      array = arrays[n];\n      m = array.length;\n      while (--m >= 0) {\n        merged[--j] = array[m];\n      }\n    }\n    return merged;\n  };\n  var abs = Math.abs;\n  d3.range = function(start, stop, step) {\n    if (arguments.length < 3) {\n      step = 1;\n      if (arguments.length < 2) {\n        stop = start;\n        start = 0;\n      }\n    }\n    if ((stop - start) / step === Infinity) throw new Error(\"infinite range\");\n    var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;\n    start *= k, stop *= k, step *= k;\n    if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);\n    return range;\n  };\n  function d3_range_integerScale(x) {\n    var k = 1;\n    while (x * k % 1) k *= 10;\n    return k;\n  }\n  function d3_class(ctor, properties) {\n    for (var key in properties) {\n      Object.defineProperty(ctor.prototype, key, {\n        value: properties[key],\n        enumerable: false\n      });\n    }\n  }\n  d3.map = function(object, f) {\n    var map = new d3_Map();\n    if (object instanceof d3_Map) {\n      object.forEach(function(key, value) {\n        map.set(key, value);\n      });\n    } else if (Array.isArray(object)) {\n      var i = -1, n = object.length, o;\n      if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o);\n    } else {\n      for (var key in object) map.set(key, object[key]);\n    }\n    return map;\n  };\n  function d3_Map() {\n    this._ = Object.create(null);\n  }\n  var d3_map_proto = \"__proto__\", d3_map_zero = \"\\x00\";\n  d3_class(d3_Map, {\n    has: d3_map_has,\n    get: function(key) {\n      return this._[d3_map_escape(key)];\n    },\n    set: function(key, value) {\n      return this._[d3_map_escape(key)] = value;\n    },\n    remove: d3_map_remove,\n    keys: d3_map_keys,\n    values: function() {\n      var values = [];\n      for (var key in this._) values.push(this._[key]);\n      return values;\n    },\n    entries: function() {\n      var entries = [];\n      for (var key in this._) entries.push({\n        key: d3_map_unescape(key),\n        value: this._[key]\n      });\n      return entries;\n    },\n    size: d3_map_size,\n    empty: d3_map_empty,\n    forEach: function(f) {\n      for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]);\n    }\n  });\n  function d3_map_escape(key) {\n    return (key += \"\") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key;\n  }\n  function d3_map_unescape(key) {\n    return (key += \"\")[0] === d3_map_zero ? key.slice(1) : key;\n  }\n  function d3_map_has(key) {\n    return d3_map_escape(key) in this._;\n  }\n  function d3_map_remove(key) {\n    return (key = d3_map_escape(key)) in this._ && delete this._[key];\n  }\n  function d3_map_keys() {\n    var keys = [];\n    for (var key in this._) keys.push(d3_map_unescape(key));\n    return keys;\n  }\n  function d3_map_size() {\n    var size = 0;\n    for (var key in this._) ++size;\n    return size;\n  }\n  function d3_map_empty() {\n    for (var key in this._) return false;\n    return true;\n  }\n  d3.nest = function() {\n    var nest = {}, keys = [], sortKeys = [], sortValues, rollup;\n    function map(mapType, array, depth) {\n      if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;\n      var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;\n      while (++i < n) {\n        if (values = valuesByKey.get(keyValue = key(object = array[i]))) {\n          values.push(object);\n        } else {\n          valuesByKey.set(keyValue, [ object ]);\n        }\n      }\n      if (mapType) {\n        object = mapType();\n        setter = function(keyValue, values) {\n          object.set(keyValue, map(mapType, values, depth));\n        };\n      } else {\n        object = {};\n        setter = function(keyValue, values) {\n          object[keyValue] = map(mapType, values, depth);\n        };\n      }\n      valuesByKey.forEach(setter);\n      return object;\n    }\n    function entries(map, depth) {\n      if (depth >= keys.length) return map;\n      var array = [], sortKey = sortKeys[depth++];\n      map.forEach(function(key, keyMap) {\n        array.push({\n          key: key,\n          values: entries(keyMap, depth)\n        });\n      });\n      return sortKey ? array.sort(function(a, b) {\n        return sortKey(a.key, b.key);\n      }) : array;\n    }\n    nest.map = function(array, mapType) {\n      return map(mapType, array, 0);\n    };\n    nest.entries = function(array) {\n      return entries(map(d3.map, array, 0), 0);\n    };\n    nest.key = function(d) {\n      keys.push(d);\n      return nest;\n    };\n    nest.sortKeys = function(order) {\n      sortKeys[keys.length - 1] = order;\n      return nest;\n    };\n    nest.sortValues = function(order) {\n      sortValues = order;\n      return nest;\n    };\n    nest.rollup = function(f) {\n      rollup = f;\n      return nest;\n    };\n    return nest;\n  };\n  d3.set = function(array) {\n    var set = new d3_Set();\n    if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);\n    return set;\n  };\n  function d3_Set() {\n    this._ = Object.create(null);\n  }\n  d3_class(d3_Set, {\n    has: d3_map_has,\n    add: function(key) {\n      this._[d3_map_escape(key += \"\")] = true;\n      return key;\n    },\n    remove: d3_map_remove,\n    values: d3_map_keys,\n    size: d3_map_size,\n    empty: d3_map_empty,\n    forEach: function(f) {\n      for (var key in this._) f.call(this, d3_map_unescape(key));\n    }\n  });\n  d3.behavior = {};\n  function d3_identity(d) {\n    return d;\n  }\n  d3.rebind = function(target, source) {\n    var i = 1, n = arguments.length, method;\n    while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);\n    return target;\n  };\n  function d3_rebind(target, source, method) {\n    return function() {\n      var value = method.apply(source, arguments);\n      return value === source ? target : value;\n    };\n  }\n  function d3_vendorSymbol(object, name) {\n    if (name in object) return name;\n    name = name.charAt(0).toUpperCase() + name.slice(1);\n    for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {\n      var prefixName = d3_vendorPrefixes[i] + name;\n      if (prefixName in object) return prefixName;\n    }\n  }\n  var d3_vendorPrefixes = [ \"webkit\", \"ms\", \"moz\", \"Moz\", \"o\", \"O\" ];\n  function d3_noop() {}\n  d3.dispatch = function() {\n    var dispatch = new d3_dispatch(), i = -1, n = arguments.length;\n    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);\n    return dispatch;\n  };\n  function d3_dispatch() {}\n  d3_dispatch.prototype.on = function(type, listener) {\n    var i = type.indexOf(\".\"), name = \"\";\n    if (i >= 0) {\n      name = type.slice(i + 1);\n      type = type.slice(0, i);\n    }\n    if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);\n    if (arguments.length === 2) {\n      if (listener == null) for (type in this) {\n        if (this.hasOwnProperty(type)) this[type].on(name, null);\n      }\n      return this;\n    }\n  };\n  function d3_dispatch_event(dispatch) {\n    var listeners = [], listenerByName = new d3_Map();\n    function event() {\n      var z = listeners, i = -1, n = z.length, l;\n      while (++i < n) if (l = z[i].on) l.apply(this, arguments);\n      return dispatch;\n    }\n    event.on = function(name, listener) {\n      var l = listenerByName.get(name), i;\n      if (arguments.length < 2) return l && l.on;\n      if (l) {\n        l.on = null;\n        listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));\n        listenerByName.remove(name);\n      }\n      if (listener) listeners.push(listenerByName.set(name, {\n        on: listener\n      }));\n      return dispatch;\n    };\n    return event;\n  }\n  d3.event = null;\n  function d3_eventPreventDefault() {\n    d3.event.preventDefault();\n  }\n  function d3_eventSource() {\n    var e = d3.event, s;\n    while (s = e.sourceEvent) e = s;\n    return e;\n  }\n  function d3_eventDispatch(target) {\n    var dispatch = new d3_dispatch(), i = 0, n = arguments.length;\n    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);\n    dispatch.of = function(thiz, argumentz) {\n      return function(e1) {\n        try {\n          var e0 = e1.sourceEvent = d3.event;\n          e1.target = target;\n          d3.event = e1;\n          dispatch[e1.type].apply(thiz, argumentz);\n        } finally {\n          d3.event = e0;\n        }\n      };\n    };\n    return dispatch;\n  }\n  d3.requote = function(s) {\n    return s.replace(d3_requote_re, \"\\\\$&\");\n  };\n  var d3_requote_re = /[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;\n  var d3_subclass = {}.__proto__ ? function(object, prototype) {\n    object.__proto__ = prototype;\n  } : function(object, prototype) {\n    for (var property in prototype) object[property] = prototype[property];\n  };\n  function d3_selection(groups) {\n    d3_subclass(groups, d3_selectionPrototype);\n    return groups;\n  }\n  var d3_select = function(s, n) {\n    return n.querySelector(s);\n  }, d3_selectAll = function(s, n) {\n    return n.querySelectorAll(s);\n  }, d3_selectMatches = function(n, s) {\n    var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, \"matchesSelector\")];\n    d3_selectMatches = function(n, s) {\n      return d3_selectMatcher.call(n, s);\n    };\n    return d3_selectMatches(n, s);\n  };\n  if (typeof Sizzle === \"function\") {\n    d3_select = function(s, n) {\n      return Sizzle(s, n)[0] || null;\n    };\n    d3_selectAll = Sizzle;\n    d3_selectMatches = Sizzle.matchesSelector;\n  }\n  d3.selection = function() {\n    return d3.select(d3_document.documentElement);\n  };\n  var d3_selectionPrototype = d3.selection.prototype = [];\n  d3_selectionPrototype.select = function(selector) {\n    var subgroups = [], subgroup, subnode, group, node;\n    selector = d3_selection_selector(selector);\n    for (var j = -1, m = this.length; ++j < m; ) {\n      subgroups.push(subgroup = []);\n      subgroup.parentNode = (group = this[j]).parentNode;\n      for (var i = -1, n = group.length; ++i < n; ) {\n        if (node = group[i]) {\n          subgroup.push(subnode = selector.call(node, node.__data__, i, j));\n          if (subnode && \"__data__\" in node) subnode.__data__ = node.__data__;\n        } else {\n          subgroup.push(null);\n        }\n      }\n    }\n    return d3_selection(subgroups);\n  };\n  function d3_selection_selector(selector) {\n    return typeof selector === \"function\" ? selector : function() {\n      return d3_select(selector, this);\n    };\n  }\n  d3_selectionPrototype.selectAll = function(selector) {\n    var subgroups = [], subgroup, node;\n    selector = d3_selection_selectorAll(selector);\n    for (var j = -1, m = this.length; ++j < m; ) {\n      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {\n        if (node = group[i]) {\n          subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));\n          subgroup.parentNode = node;\n        }\n      }\n    }\n    return d3_selection(subgroups);\n  };\n  function d3_selection_selectorAll(selector) {\n    return typeof selector === \"function\" ? selector : function() {\n      return d3_selectAll(selector, this);\n    };\n  }\n  var d3_nsPrefix = {\n    svg: \"http://www.w3.org/2000/svg\",\n    xhtml: \"http://www.w3.org/1999/xhtml\",\n    xlink: \"http://www.w3.org/1999/xlink\",\n    xml: \"http://www.w3.org/XML/1998/namespace\",\n    xmlns: \"http://www.w3.org/2000/xmlns/\"\n  };\n  d3.ns = {\n    prefix: d3_nsPrefix,\n    qualify: function(name) {\n      var i = name.indexOf(\":\"), prefix = name;\n      if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n      return d3_nsPrefix.hasOwnProperty(prefix) ? {\n        space: d3_nsPrefix[prefix],\n        local: name\n      } : name;\n    }\n  };\n  d3_selectionPrototype.attr = function(name, value) {\n    if (arguments.length < 2) {\n      if (typeof name === \"string\") {\n        var node = this.node();\n        name = d3.ns.qualify(name);\n        return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);\n      }\n      for (value in name) this.each(d3_selection_attr(value, name[value]));\n      return this;\n    }\n    return this.each(d3_selection_attr(name, value));\n  };\n  function d3_selection_attr(name, value) {\n    name = d3.ns.qualify(name);\n    function attrNull() {\n      this.removeAttribute(name);\n    }\n    function attrNullNS() {\n      this.removeAttributeNS(name.space, name.local);\n    }\n    function attrConstant() {\n      this.setAttribute(name, value);\n    }\n    function attrConstantNS() {\n      this.setAttributeNS(name.space, name.local, value);\n    }\n    function attrFunction() {\n      var x = value.apply(this, arguments);\n      if (x == null) this.removeAttribute(name); else this.setAttribute(name, x);\n    }\n    function attrFunctionNS() {\n      var x = value.apply(this, arguments);\n      if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);\n    }\n    return value == null ? name.local ? attrNullNS : attrNull : typeof value === \"function\" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;\n  }\n  function d3_collapse(s) {\n    return s.trim().replace(/\\s+/g, \" \");\n  }\n  d3_selectionPrototype.classed = function(name, value) {\n    if (arguments.length < 2) {\n      if (typeof name === \"string\") {\n        var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;\n        if (value = node.classList) {\n          while (++i < n) if (!value.contains(name[i])) return false;\n        } else {\n          value = node.getAttribute(\"class\");\n          while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;\n        }\n        return true;\n      }\n      for (value in name) this.each(d3_selection_classed(value, name[value]));\n      return this;\n    }\n    return this.each(d3_selection_classed(name, value));\n  };\n  function d3_selection_classedRe(name) {\n    return new RegExp(\"(?:^|\\\\s+)\" + d3.requote(name) + \"(?:\\\\s+|$)\", \"g\");\n  }\n  function d3_selection_classes(name) {\n    return (name + \"\").trim().split(/^|\\s+/);\n  }\n  function d3_selection_classed(name, value) {\n    name = d3_selection_classes(name).map(d3_selection_classedName);\n    var n = name.length;\n    function classedConstant() {\n      var i = -1;\n      while (++i < n) name[i](this, value);\n    }\n    function classedFunction() {\n      var i = -1, x = value.apply(this, arguments);\n      while (++i < n) name[i](this, x);\n    }\n    return typeof value === \"function\" ? classedFunction : classedConstant;\n  }\n  function d3_selection_classedName(name) {\n    var re = d3_selection_classedRe(name);\n    return function(node, value) {\n      if (c = node.classList) return value ? c.add(name) : c.remove(name);\n      var c = node.getAttribute(\"class\") || \"\";\n      if (value) {\n        re.lastIndex = 0;\n        if (!re.test(c)) node.setAttribute(\"class\", d3_collapse(c + \" \" + name));\n      } else {\n        node.setAttribute(\"class\", d3_collapse(c.replace(re, \" \")));\n      }\n    };\n  }\n  d3_selectionPrototype.style = function(name, value, priority) {\n    var n = arguments.length;\n    if (n < 3) {\n      if (typeof name !== \"string\") {\n        if (n < 2) value = \"\";\n        for (priority in name) this.each(d3_selection_style(priority, name[priority], value));\n        return this;\n      }\n      if (n < 2) {\n        var node = this.node();\n        return d3_window(node).getComputedStyle(node, null).getPropertyValue(name);\n      }\n      priority = \"\";\n    }\n    return this.each(d3_selection_style(name, value, priority));\n  };\n  function d3_selection_style(name, value, priority) {\n    function styleNull() {\n      this.style.removeProperty(name);\n    }\n    function styleConstant() {\n      this.style.setProperty(name, value, priority);\n    }\n    function styleFunction() {\n      var x = value.apply(this, arguments);\n      if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority);\n    }\n    return value == null ? styleNull : typeof value === \"function\" ? styleFunction : styleConstant;\n  }\n  d3_selectionPrototype.property = function(name, value) {\n    if (arguments.length < 2) {\n      if (typeof name === \"string\") return this.node()[name];\n      for (value in name) this.each(d3_selection_property(value, name[value]));\n      return this;\n    }\n    return this.each(d3_selection_property(name, value));\n  };\n  function d3_selection_property(name, value) {\n    function propertyNull() {\n      delete this[name];\n    }\n    function propertyConstant() {\n      this[name] = value;\n    }\n    function propertyFunction() {\n      var x = value.apply(this, arguments);\n      if (x == null) delete this[name]; else this[name] = x;\n    }\n    return value == null ? propertyNull : typeof value === \"function\" ? propertyFunction : propertyConstant;\n  }\n  d3_selectionPrototype.text = function(value) {\n    return arguments.length ? this.each(typeof value === \"function\" ? function() {\n      var v = value.apply(this, arguments);\n      this.textContent = v == null ? \"\" : v;\n    } : value == null ? function() {\n      this.textContent = \"\";\n    } : function() {\n      this.textContent = value;\n    }) : this.node().textContent;\n  };\n  d3_selectionPrototype.html = function(value) {\n    return arguments.length ? this.each(typeof value === \"function\" ? function() {\n      var v = value.apply(this, arguments);\n      this.innerHTML = v == null ? \"\" : v;\n    } : value == null ? function() {\n      this.innerHTML = \"\";\n    } : function() {\n      this.innerHTML = value;\n    }) : this.node().innerHTML;\n  };\n  d3_selectionPrototype.append = function(name) {\n    name = d3_selection_creator(name);\n    return this.select(function() {\n      return this.appendChild(name.apply(this, arguments));\n    });\n  };\n  function d3_selection_creator(name) {\n    function create() {\n      var document = this.ownerDocument, namespace = this.namespaceURI;\n      return namespace ? document.createElementNS(namespace, name) : document.createElement(name);\n    }\n    function createNS() {\n      return this.ownerDocument.createElementNS(name.space, name.local);\n    }\n    return typeof name === \"function\" ? name : (name = d3.ns.qualify(name)).local ? createNS : create;\n  }\n  d3_selectionPrototype.insert = function(name, before) {\n    name = d3_selection_creator(name);\n    before = d3_selection_selector(before);\n    return this.select(function() {\n      return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);\n    });\n  };\n  d3_selectionPrototype.remove = function() {\n    return this.each(d3_selectionRemove);\n  };\n  function d3_selectionRemove() {\n    var parent = this.parentNode;\n    if (parent) parent.removeChild(this);\n  }\n  d3_selectionPrototype.data = function(value, key) {\n    var i = -1, n = this.length, group, node;\n    if (!arguments.length) {\n      value = new Array(n = (group = this[0]).length);\n      while (++i < n) {\n        if (node = group[i]) {\n          value[i] = node.__data__;\n        }\n      }\n      return value;\n    }\n    function bind(group, groupData) {\n      var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;\n      if (key) {\n        var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue;\n        for (i = -1; ++i < n; ) {\n          if (node = group[i]) {\n            if (nodeByKeyValue.has(keyValue = key.call(node, node.__data__, i))) {\n              exitNodes[i] = node;\n            } else {\n              nodeByKeyValue.set(keyValue, node);\n            }\n            keyValues[i] = keyValue;\n          }\n        }\n        for (i = -1; ++i < m; ) {\n          if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) {\n            enterNodes[i] = d3_selection_dataNode(nodeData);\n          } else if (node !== true) {\n            updateNodes[i] = node;\n            node.__data__ = nodeData;\n          }\n          nodeByKeyValue.set(keyValue, true);\n        }\n        for (i = -1; ++i < n; ) {\n          if (i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true) {\n            exitNodes[i] = group[i];\n          }\n        }\n      } else {\n        for (i = -1; ++i < n0; ) {\n          node = group[i];\n          nodeData = groupData[i];\n          if (node) {\n            node.__data__ = nodeData;\n            updateNodes[i] = node;\n          } else {\n            enterNodes[i] = d3_selection_dataNode(nodeData);\n          }\n        }\n        for (;i < m; ++i) {\n          enterNodes[i] = d3_selection_dataNode(groupData[i]);\n        }\n        for (;i < n; ++i) {\n          exitNodes[i] = group[i];\n        }\n      }\n      enterNodes.update = updateNodes;\n      enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;\n      enter.push(enterNodes);\n      update.push(updateNodes);\n      exit.push(exitNodes);\n    }\n    var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);\n    if (typeof value === \"function\") {\n      while (++i < n) {\n        bind(group = this[i], value.call(group, group.parentNode.__data__, i));\n      }\n    } else {\n      while (++i < n) {\n        bind(group = this[i], value);\n      }\n    }\n    update.enter = function() {\n      return enter;\n    };\n    update.exit = function() {\n      return exit;\n    };\n    return update;\n  };\n  function d3_selection_dataNode(data) {\n    return {\n      __data__: data\n    };\n  }\n  d3_selectionPrototype.datum = function(value) {\n    return arguments.length ? this.property(\"__data__\", value) : this.property(\"__data__\");\n  };\n  d3_selectionPrototype.filter = function(filter) {\n    var subgroups = [], subgroup, group, node;\n    if (typeof filter !== \"function\") filter = d3_selection_filter(filter);\n    for (var j = 0, m = this.length; j < m; j++) {\n      subgroups.push(subgroup = []);\n      subgroup.parentNode = (group = this[j]).parentNode;\n      for (var i = 0, n = group.length; i < n; i++) {\n        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {\n          subgroup.push(node);\n        }\n      }\n    }\n    return d3_selection(subgroups);\n  };\n  function d3_selection_filter(selector) {\n    return function() {\n      return d3_selectMatches(this, selector);\n    };\n  }\n  d3_selectionPrototype.order = function() {\n    for (var j = -1, m = this.length; ++j < m; ) {\n      for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {\n        if (node = group[i]) {\n          if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);\n          next = node;\n        }\n      }\n    }\n    return this;\n  };\n  d3_selectionPrototype.sort = function(comparator) {\n    comparator = d3_selection_sortComparator.apply(this, arguments);\n    for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);\n    return this.order();\n  };\n  function d3_selection_sortComparator(comparator) {\n    if (!arguments.length) comparator = d3_ascending;\n    return function(a, b) {\n      return a && b ? comparator(a.__data__, b.__data__) : !a - !b;\n    };\n  }\n  d3_selectionPrototype.each = function(callback) {\n    return d3_selection_each(this, function(node, i, j) {\n      callback.call(node, node.__data__, i, j);\n    });\n  };\n  function d3_selection_each(groups, callback) {\n    for (var j = 0, m = groups.length; j < m; j++) {\n      for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {\n        if (node = group[i]) callback(node, i, j);\n      }\n    }\n    return groups;\n  }\n  d3_selectionPrototype.call = function(callback) {\n    var args = d3_array(arguments);\n    callback.apply(args[0] = this, args);\n    return this;\n  };\n  d3_selectionPrototype.empty = function() {\n    return !this.node();\n  };\n  d3_selectionPrototype.node = function() {\n    for (var j = 0, m = this.length; j < m; j++) {\n      for (var group = this[j], i = 0, n = group.length; i < n; i++) {\n        var node = group[i];\n        if (node) return node;\n      }\n    }\n    return null;\n  };\n  d3_selectionPrototype.size = function() {\n    var n = 0;\n    d3_selection_each(this, function() {\n      ++n;\n    });\n    return n;\n  };\n  function d3_selection_enter(selection) {\n    d3_subclass(selection, d3_selection_enterPrototype);\n    return selection;\n  }\n  var d3_selection_enterPrototype = [];\n  d3.selection.enter = d3_selection_enter;\n  d3.selection.enter.prototype = d3_selection_enterPrototype;\n  d3_selection_enterPrototype.append = d3_selectionPrototype.append;\n  d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;\n  d3_selection_enterPrototype.node = d3_selectionPrototype.node;\n  d3_selection_enterPrototype.call = d3_selectionPrototype.call;\n  d3_selection_enterPrototype.size = d3_selectionPrototype.size;\n  d3_selection_enterPrototype.select = function(selector) {\n    var subgroups = [], subgroup, subnode, upgroup, group, node;\n    for (var j = -1, m = this.length; ++j < m; ) {\n      upgroup = (group = this[j]).update;\n      subgroups.push(subgroup = []);\n      subgroup.parentNode = group.parentNode;\n      for (var i = -1, n = group.length; ++i < n; ) {\n        if (node = group[i]) {\n          subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));\n          subnode.__data__ = node.__data__;\n        } else {\n          subgroup.push(null);\n        }\n      }\n    }\n    return d3_selection(subgroups);\n  };\n  d3_selection_enterPrototype.insert = function(name, before) {\n    if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);\n    return d3_selectionPrototype.insert.call(this, name, before);\n  };\n  function d3_selection_enterInsertBefore(enter) {\n    var i0, j0;\n    return function(d, i, j) {\n      var group = enter[j].update, n = group.length, node;\n      if (j != j0) j0 = j, i0 = 0;\n      if (i >= i0) i0 = i + 1;\n      while (!(node = group[i0]) && ++i0 < n) ;\n      return node;\n    };\n  }\n  d3.select = function(node) {\n    var group;\n    if (typeof node === \"string\") {\n      group = [ d3_select(node, d3_document) ];\n      group.parentNode = d3_document.documentElement;\n    } else {\n      group = [ node ];\n      group.parentNode = d3_documentElement(node);\n    }\n    return d3_selection([ group ]);\n  };\n  d3.selectAll = function(nodes) {\n    var group;\n    if (typeof nodes === \"string\") {\n      group = d3_array(d3_selectAll(nodes, d3_document));\n      group.parentNode = d3_document.documentElement;\n    } else {\n      group = d3_array(nodes);\n      group.parentNode = null;\n    }\n    return d3_selection([ group ]);\n  };\n  d3_selectionPrototype.on = function(type, listener, capture) {\n    var n = arguments.length;\n    if (n < 3) {\n      if (typeof type !== \"string\") {\n        if (n < 2) listener = false;\n        for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));\n        return this;\n      }\n      if (n < 2) return (n = this.node()[\"__on\" + type]) && n._;\n      capture = false;\n    }\n    return this.each(d3_selection_on(type, listener, capture));\n  };\n  function d3_selection_on(type, listener, capture) {\n    var name = \"__on\" + type, i = type.indexOf(\".\"), wrap = d3_selection_onListener;\n    if (i > 0) type = type.slice(0, i);\n    var filter = d3_selection_onFilters.get(type);\n    if (filter) type = filter, wrap = d3_selection_onFilter;\n    function onRemove() {\n      var l = this[name];\n      if (l) {\n        this.removeEventListener(type, l, l.$);\n        delete this[name];\n      }\n    }\n    function onAdd() {\n      var l = wrap(listener, d3_array(arguments));\n      onRemove.call(this);\n      this.addEventListener(type, this[name] = l, l.$ = capture);\n      l._ = listener;\n    }\n    function removeAll() {\n      var re = new RegExp(\"^__on([^.]+)\" + d3.requote(type) + \"$\"), match;\n      for (var name in this) {\n        if (match = name.match(re)) {\n          var l = this[name];\n          this.removeEventListener(match[1], l, l.$);\n          delete this[name];\n        }\n      }\n    }\n    return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;\n  }\n  var d3_selection_onFilters = d3.map({\n    mouseenter: \"mouseover\",\n    mouseleave: \"mouseout\"\n  });\n  if (d3_document) {\n    d3_selection_onFilters.forEach(function(k) {\n      if (\"on\" + k in d3_document) d3_selection_onFilters.remove(k);\n    });\n  }\n  function d3_selection_onListener(listener, argumentz) {\n    return function(e) {\n      var o = d3.event;\n      d3.event = e;\n      argumentz[0] = this.__data__;\n      try {\n        listener.apply(this, argumentz);\n      } finally {\n        d3.event = o;\n      }\n    };\n  }\n  function d3_selection_onFilter(listener, argumentz) {\n    var l = d3_selection_onListener(listener, argumentz);\n    return function(e) {\n      var target = this, related = e.relatedTarget;\n      if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {\n        l.call(target, e);\n      }\n    };\n  }\n  var d3_event_dragSelect, d3_event_dragId = 0;\n  function d3_event_dragSuppress(node) {\n    var name = \".dragsuppress-\" + ++d3_event_dragId, click = \"click\" + name, w = d3.select(d3_window(node)).on(\"touchmove\" + name, d3_eventPreventDefault).on(\"dragstart\" + name, d3_eventPreventDefault).on(\"selectstart\" + name, d3_eventPreventDefault);\n    if (d3_event_dragSelect == null) {\n      d3_event_dragSelect = \"onselectstart\" in node ? false : d3_vendorSymbol(node.style, \"userSelect\");\n    }\n    if (d3_event_dragSelect) {\n      var style = d3_documentElement(node).style, select = style[d3_event_dragSelect];\n      style[d3_event_dragSelect] = \"none\";\n    }\n    return function(suppressClick) {\n      w.on(name, null);\n      if (d3_event_dragSelect) style[d3_event_dragSelect] = select;\n      if (suppressClick) {\n        var off = function() {\n          w.on(click, null);\n        };\n        w.on(click, function() {\n          d3_eventPreventDefault();\n          off();\n        }, true);\n        setTimeout(off, 0);\n      }\n    };\n  }\n  d3.mouse = function(container) {\n    return d3_mousePoint(container, d3_eventSource());\n  };\n  var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0;\n  function d3_mousePoint(container, e) {\n    if (e.changedTouches) e = e.changedTouches[0];\n    var svg = container.ownerSVGElement || container;\n    if (svg.createSVGPoint) {\n      var point = svg.createSVGPoint();\n      if (d3_mouse_bug44083 < 0) {\n        var window = d3_window(container);\n        if (window.scrollX || window.scrollY) {\n          svg = d3.select(\"body\").append(\"svg\").style({\n            position: \"absolute\",\n            top: 0,\n            left: 0,\n            margin: 0,\n            padding: 0,\n            border: \"none\"\n          }, \"important\");\n          var ctm = svg[0][0].getScreenCTM();\n          d3_mouse_bug44083 = !(ctm.f || ctm.e);\n          svg.remove();\n        }\n      }\n      if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, \n      point.y = e.clientY;\n      point = point.matrixTransform(container.getScreenCTM().inverse());\n      return [ point.x, point.y ];\n    }\n    var rect = container.getBoundingClientRect();\n    return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];\n  }\n  d3.touch = function(container, touches, identifier) {\n    if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches;\n    if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) {\n      if ((touch = touches[i]).identifier === identifier) {\n        return d3_mousePoint(container, touch);\n      }\n    }\n  };\n  d3.behavior.drag = function() {\n    var event = d3_eventDispatch(drag, \"drag\", \"dragstart\", \"dragend\"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, \"mousemove\", \"mouseup\"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, \"touchmove\", \"touchend\");\n    function drag() {\n      this.on(\"mousedown.drag\", mousedown).on(\"touchstart.drag\", touchstart);\n    }\n    function dragstart(id, position, subject, move, end) {\n      return function() {\n        var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = \".drag\" + (dragId == null ? \"\" : \"-\" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId);\n        if (origin) {\n          dragOffset = origin.apply(that, arguments);\n          dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];\n        } else {\n          dragOffset = [ 0, 0 ];\n        }\n        dispatch({\n          type: \"dragstart\"\n        });\n        function moved() {\n          var position1 = position(parent, dragId), dx, dy;\n          if (!position1) return;\n          dx = position1[0] - position0[0];\n          dy = position1[1] - position0[1];\n          dragged |= dx | dy;\n          position0 = position1;\n          dispatch({\n            type: \"drag\",\n            x: position1[0] + dragOffset[0],\n            y: position1[1] + dragOffset[1],\n            dx: dx,\n            dy: dy\n          });\n        }\n        function ended() {\n          if (!position(parent, dragId)) return;\n          dragSubject.on(move + dragName, null).on(end + dragName, null);\n          dragRestore(dragged);\n          dispatch({\n            type: \"dragend\"\n          });\n        }\n      };\n    }\n    drag.origin = function(x) {\n      if (!arguments.length) return origin;\n      origin = x;\n      return drag;\n    };\n    return d3.rebind(drag, event, \"on\");\n  };\n  function d3_behavior_dragTouchId() {\n    return d3.event.changedTouches[0].identifier;\n  }\n  d3.touches = function(container, touches) {\n    if (arguments.length < 2) touches = d3_eventSource().touches;\n    return touches ? d3_array(touches).map(function(touch) {\n      var point = d3_mousePoint(container, touch);\n      point.identifier = touch.identifier;\n      return point;\n    }) : [];\n  };\n  var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π;\n  function d3_sgn(x) {\n    return x > 0 ? 1 : x < 0 ? -1 : 0;\n  }\n  function d3_cross2d(a, b, c) {\n    return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n  }\n  function d3_acos(x) {\n    return x > 1 ? 0 : x < -1 ? π : Math.acos(x);\n  }\n  function d3_asin(x) {\n    return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);\n  }\n  function d3_sinh(x) {\n    return ((x = Math.exp(x)) - 1 / x) / 2;\n  }\n  function d3_cosh(x) {\n    return ((x = Math.exp(x)) + 1 / x) / 2;\n  }\n  function d3_tanh(x) {\n    return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n  }\n  function d3_haversin(x) {\n    return (x = Math.sin(x / 2)) * x;\n  }\n  var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;\n  d3.interpolateZoom = function(p0, p1) {\n    var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S;\n    if (d2 < ε2) {\n      S = Math.log(w1 / w0) / ρ;\n      i = function(t) {\n        return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * t * S) ];\n      };\n    } else {\n      var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n      S = (r1 - r0) / ρ;\n      i = function(t) {\n        var s = t * S, coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));\n        return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];\n      };\n    }\n    i.duration = S * 1e3;\n    return i;\n  };\n  d3.behavior.zoom = function() {\n    var view = {\n      x: 0,\n      y: 0,\n      k: 1\n    }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = \"mousedown.zoom\", mousemove = \"mousemove.zoom\", mouseup = \"mouseup.zoom\", mousewheelTimer, touchstart = \"touchstart.zoom\", touchtime, event = d3_eventDispatch(zoom, \"zoomstart\", \"zoom\", \"zoomend\"), x0, x1, y0, y1;\n    if (!d3_behavior_zoomWheel) {\n      d3_behavior_zoomWheel = \"onwheel\" in d3_document ? (d3_behavior_zoomDelta = function() {\n        return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);\n      }, \"wheel\") : \"onmousewheel\" in d3_document ? (d3_behavior_zoomDelta = function() {\n        return d3.event.wheelDelta;\n      }, \"mousewheel\") : (d3_behavior_zoomDelta = function() {\n        return -d3.event.detail;\n      }, \"MozMousePixelScroll\");\n    }\n    function zoom(g) {\n      g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + \".zoom\", mousewheeled).on(\"dblclick.zoom\", dblclicked).on(touchstart, touchstarted);\n    }\n    zoom.event = function(g) {\n      g.each(function() {\n        var dispatch = event.of(this, arguments), view1 = view;\n        if (d3_transitionInheritId) {\n          d3.select(this).transition().each(\"start.zoom\", function() {\n            view = this.__chart__ || {\n              x: 0,\n              y: 0,\n              k: 1\n            };\n            zoomstarted(dispatch);\n          }).tween(\"zoom:zoom\", function() {\n            var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);\n            return function(t) {\n              var l = i(t), k = dx / l[2];\n              this.__chart__ = view = {\n                x: cx - l[0] * k,\n                y: cy - l[1] * k,\n                k: k\n              };\n              zoomed(dispatch);\n            };\n          }).each(\"interrupt.zoom\", function() {\n            zoomended(dispatch);\n          }).each(\"end.zoom\", function() {\n            zoomended(dispatch);\n          });\n        } else {\n          this.__chart__ = view;\n          zoomstarted(dispatch);\n          zoomed(dispatch);\n          zoomended(dispatch);\n        }\n      });\n    };\n    zoom.translate = function(_) {\n      if (!arguments.length) return [ view.x, view.y ];\n      view = {\n        x: +_[0],\n        y: +_[1],\n        k: view.k\n      };\n      rescale();\n      return zoom;\n    };\n    zoom.scale = function(_) {\n      if (!arguments.length) return view.k;\n      view = {\n        x: view.x,\n        y: view.y,\n        k: null\n      };\n      scaleTo(+_);\n      rescale();\n      return zoom;\n    };\n    zoom.scaleExtent = function(_) {\n      if (!arguments.length) return scaleExtent;\n      scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];\n      return zoom;\n    };\n    zoom.center = function(_) {\n      if (!arguments.length) return center;\n      center = _ && [ +_[0], +_[1] ];\n      return zoom;\n    };\n    zoom.size = function(_) {\n      if (!arguments.length) return size;\n      size = _ && [ +_[0], +_[1] ];\n      return zoom;\n    };\n    zoom.duration = function(_) {\n      if (!arguments.length) return duration;\n      duration = +_;\n      return zoom;\n    };\n    zoom.x = function(z) {\n      if (!arguments.length) return x1;\n      x1 = z;\n      x0 = z.copy();\n      view = {\n        x: 0,\n        y: 0,\n        k: 1\n      };\n      return zoom;\n    };\n    zoom.y = function(z) {\n      if (!arguments.length) return y1;\n      y1 = z;\n      y0 = z.copy();\n      view = {\n        x: 0,\n        y: 0,\n        k: 1\n      };\n      return zoom;\n    };\n    function location(p) {\n      return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];\n    }\n    function point(l) {\n      return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];\n    }\n    function scaleTo(s) {\n      view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));\n    }\n    function translateTo(p, l) {\n      l = point(l);\n      view.x += p[0] - l[0];\n      view.y += p[1] - l[1];\n    }\n    function zoomTo(that, p, l, k) {\n      that.__chart__ = {\n        x: view.x,\n        y: view.y,\n        k: view.k\n      };\n      scaleTo(Math.pow(2, k));\n      translateTo(center0 = p, l);\n      that = d3.select(that);\n      if (duration > 0) that = that.transition().duration(duration);\n      that.call(zoom.event);\n    }\n    function rescale() {\n      if (x1) x1.domain(x0.range().map(function(x) {\n        return (x - view.x) / view.k;\n      }).map(x0.invert));\n      if (y1) y1.domain(y0.range().map(function(y) {\n        return (y - view.y) / view.k;\n      }).map(y0.invert));\n    }\n    function zoomstarted(dispatch) {\n      if (!zooming++) dispatch({\n        type: \"zoomstart\"\n      });\n    }\n    function zoomed(dispatch) {\n      rescale();\n      dispatch({\n        type: \"zoom\",\n        scale: view.k,\n        translate: [ view.x, view.y ]\n      });\n    }\n    function zoomended(dispatch) {\n      if (!--zooming) dispatch({\n        type: \"zoomend\"\n      }), center0 = null;\n    }\n    function mousedowned() {\n      var that = this, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that);\n      d3_selection_interrupt.call(that);\n      zoomstarted(dispatch);\n      function moved() {\n        dragged = 1;\n        translateTo(d3.mouse(that), location0);\n        zoomed(dispatch);\n      }\n      function ended() {\n        subject.on(mousemove, null).on(mouseup, null);\n        dragRestore(dragged);\n        zoomended(dispatch);\n      }\n    }\n    function touchstarted() {\n      var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = \".zoom-\" + d3.event.changedTouches[0].identifier, touchmove = \"touchmove\" + zoomName, touchend = \"touchend\" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that);\n      started();\n      zoomstarted(dispatch);\n      subject.on(mousedown, null).on(touchstart, started);\n      function relocate() {\n        var touches = d3.touches(that);\n        scale0 = view.k;\n        touches.forEach(function(t) {\n          if (t.identifier in locations0) locations0[t.identifier] = location(t);\n        });\n        return touches;\n      }\n      function started() {\n        var target = d3.event.target;\n        d3.select(target).on(touchmove, moved).on(touchend, ended);\n        targets.push(target);\n        var changed = d3.event.changedTouches;\n        for (var i = 0, n = changed.length; i < n; ++i) {\n          locations0[changed[i].identifier] = null;\n        }\n        var touches = relocate(), now = Date.now();\n        if (touches.length === 1) {\n          if (now - touchtime < 500) {\n            var p = touches[0];\n            zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1);\n            d3_eventPreventDefault();\n          }\n          touchtime = now;\n        } else if (touches.length > 1) {\n          var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];\n          distance0 = dx * dx + dy * dy;\n        }\n      }\n      function moved() {\n        var touches = d3.touches(that), p0, l0, p1, l1;\n        d3_selection_interrupt.call(that);\n        for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {\n          p1 = touches[i];\n          if (l1 = locations0[p1.identifier]) {\n            if (l0) break;\n            p0 = p1, l0 = l1;\n          }\n        }\n        if (l1) {\n          var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);\n          p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];\n          l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];\n          scaleTo(scale1 * scale0);\n        }\n        touchtime = null;\n        translateTo(p0, l0);\n        zoomed(dispatch);\n      }\n      function ended() {\n        if (d3.event.touches.length) {\n          var changed = d3.event.changedTouches;\n          for (var i = 0, n = changed.length; i < n; ++i) {\n            delete locations0[changed[i].identifier];\n          }\n          for (var identifier in locations0) {\n            return void relocate();\n          }\n        }\n        d3.selectAll(targets).on(zoomName, null);\n        subject.on(mousedown, mousedowned).on(touchstart, touchstarted);\n        dragRestore();\n        zoomended(dispatch);\n      }\n    }\n    function mousewheeled() {\n      var dispatch = event.of(this, arguments);\n      if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), \n      translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch);\n      mousewheelTimer = setTimeout(function() {\n        mousewheelTimer = null;\n        zoomended(dispatch);\n      }, 50);\n      d3_eventPreventDefault();\n      scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);\n      translateTo(center0, translate0);\n      zoomed(dispatch);\n    }\n    function dblclicked() {\n      var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2;\n      zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1);\n    }\n    return d3.rebind(zoom, event, \"on\");\n  };\n  var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel;\n  d3.color = d3_color;\n  function d3_color() {}\n  d3_color.prototype.toString = function() {\n    return this.rgb() + \"\";\n  };\n  d3.hsl = d3_hsl;\n  function d3_hsl(h, s, l) {\n    return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse(\"\" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l);\n  }\n  var d3_hslPrototype = d3_hsl.prototype = new d3_color();\n  d3_hslPrototype.brighter = function(k) {\n    k = Math.pow(.7, arguments.length ? k : 1);\n    return new d3_hsl(this.h, this.s, this.l / k);\n  };\n  d3_hslPrototype.darker = function(k) {\n    k = Math.pow(.7, arguments.length ? k : 1);\n    return new d3_hsl(this.h, this.s, k * this.l);\n  };\n  d3_hslPrototype.rgb = function() {\n    return d3_hsl_rgb(this.h, this.s, this.l);\n  };\n  function d3_hsl_rgb(h, s, l) {\n    var m1, m2;\n    h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;\n    s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;\n    l = l < 0 ? 0 : l > 1 ? 1 : l;\n    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;\n    m1 = 2 * l - m2;\n    function v(h) {\n      if (h > 360) h -= 360; else if (h < 0) h += 360;\n      if (h < 60) return m1 + (m2 - m1) * h / 60;\n      if (h < 180) return m2;\n      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;\n      return m1;\n    }\n    function vv(h) {\n      return Math.round(v(h) * 255);\n    }\n    return new d3_rgb(vv(h + 120), vv(h), vv(h - 120));\n  }\n  d3.hcl = d3_hcl;\n  function d3_hcl(h, c, l) {\n    return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l);\n  }\n  var d3_hclPrototype = d3_hcl.prototype = new d3_color();\n  d3_hclPrototype.brighter = function(k) {\n    return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));\n  };\n  d3_hclPrototype.darker = function(k) {\n    return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));\n  };\n  d3_hclPrototype.rgb = function() {\n    return d3_hcl_lab(this.h, this.c, this.l).rgb();\n  };\n  function d3_hcl_lab(h, c, l) {\n    if (isNaN(h)) h = 0;\n    if (isNaN(c)) c = 0;\n    return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);\n  }\n  d3.lab = d3_lab;\n  function d3_lab(l, a, b) {\n    return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b);\n  }\n  var d3_lab_K = 18;\n  var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;\n  var d3_labPrototype = d3_lab.prototype = new d3_color();\n  d3_labPrototype.brighter = function(k) {\n    return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);\n  };\n  d3_labPrototype.darker = function(k) {\n    return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);\n  };\n  d3_labPrototype.rgb = function() {\n    return d3_lab_rgb(this.l, this.a, this.b);\n  };\n  function d3_lab_rgb(l, a, b) {\n    var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;\n    x = d3_lab_xyz(x) * d3_lab_X;\n    y = d3_lab_xyz(y) * d3_lab_Y;\n    z = d3_lab_xyz(z) * d3_lab_Z;\n    return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));\n  }\n  function d3_lab_hcl(l, a, b) {\n    return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l);\n  }\n  function d3_lab_xyz(x) {\n    return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;\n  }\n  function d3_xyz_lab(x) {\n    return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;\n  }\n  function d3_xyz_rgb(r) {\n    return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));\n  }\n  d3.rgb = d3_rgb;\n  function d3_rgb(r, g, b) {\n    return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse(\"\" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b);\n  }\n  function d3_rgbNumber(value) {\n    return new d3_rgb(value >> 16, value >> 8 & 255, value & 255);\n  }\n  function d3_rgbString(value) {\n    return d3_rgbNumber(value) + \"\";\n  }\n  var d3_rgbPrototype = d3_rgb.prototype = new d3_color();\n  d3_rgbPrototype.brighter = function(k) {\n    k = Math.pow(.7, arguments.length ? k : 1);\n    var r = this.r, g = this.g, b = this.b, i = 30;\n    if (!r && !g && !b) return new d3_rgb(i, i, i);\n    if (r && r < i) r = i;\n    if (g && g < i) g = i;\n    if (b && b < i) b = i;\n    return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k));\n  };\n  d3_rgbPrototype.darker = function(k) {\n    k = Math.pow(.7, arguments.length ? k : 1);\n    return new d3_rgb(k * this.r, k * this.g, k * this.b);\n  };\n  d3_rgbPrototype.hsl = function() {\n    return d3_rgb_hsl(this.r, this.g, this.b);\n  };\n  d3_rgbPrototype.toString = function() {\n    return \"#\" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);\n  };\n  function d3_rgb_hex(v) {\n    return v < 16 ? \"0\" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);\n  }\n  function d3_rgb_parse(format, rgb, hsl) {\n    var r = 0, g = 0, b = 0, m1, m2, color;\n    m1 = /([a-z]+)\\((.*)\\)/.exec(format = format.toLowerCase());\n    if (m1) {\n      m2 = m1[2].split(\",\");\n      switch (m1[1]) {\n       case \"hsl\":\n        {\n          return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);\n        }\n\n       case \"rgb\":\n        {\n          return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));\n        }\n      }\n    }\n    if (color = d3_rgb_names.get(format)) {\n      return rgb(color.r, color.g, color.b);\n    }\n    if (format != null && format.charAt(0) === \"#\" && !isNaN(color = parseInt(format.slice(1), 16))) {\n      if (format.length === 4) {\n        r = (color & 3840) >> 4;\n        r = r >> 4 | r;\n        g = color & 240;\n        g = g >> 4 | g;\n        b = color & 15;\n        b = b << 4 | b;\n      } else if (format.length === 7) {\n        r = (color & 16711680) >> 16;\n        g = (color & 65280) >> 8;\n        b = color & 255;\n      }\n    }\n    return rgb(r, g, b);\n  }\n  function d3_rgb_hsl(r, g, b) {\n    var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;\n    if (d) {\n      s = l < .5 ? d / (max + min) : d / (2 - max - min);\n      if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;\n      h *= 60;\n    } else {\n      h = NaN;\n      s = l > 0 && l < 1 ? 0 : h;\n    }\n    return new d3_hsl(h, s, l);\n  }\n  function d3_rgb_lab(r, g, b) {\n    r = d3_rgb_xyz(r);\n    g = d3_rgb_xyz(g);\n    b = d3_rgb_xyz(b);\n    var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);\n    return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));\n  }\n  function d3_rgb_xyz(r) {\n    return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);\n  }\n  function d3_rgb_parseNumber(c) {\n    var f = parseFloat(c);\n    return c.charAt(c.length - 1) === \"%\" ? Math.round(f * 2.55) : f;\n  }\n  var d3_rgb_names = d3.map({\n    aliceblue: 15792383,\n    antiquewhite: 16444375,\n    aqua: 65535,\n    aquamarine: 8388564,\n    azure: 15794175,\n    beige: 16119260,\n    bisque: 16770244,\n    black: 0,\n    blanchedalmond: 16772045,\n    blue: 255,\n    blueviolet: 9055202,\n    brown: 10824234,\n    burlywood: 14596231,\n    cadetblue: 6266528,\n    chartreuse: 8388352,\n    chocolate: 13789470,\n    coral: 16744272,\n    cornflowerblue: 6591981,\n    cornsilk: 16775388,\n    crimson: 14423100,\n    cyan: 65535,\n    darkblue: 139,\n    darkcyan: 35723,\n    darkgoldenrod: 12092939,\n    darkgray: 11119017,\n    darkgreen: 25600,\n    darkgrey: 11119017,\n    darkkhaki: 12433259,\n    darkmagenta: 9109643,\n    darkolivegreen: 5597999,\n    darkorange: 16747520,\n    darkorchid: 10040012,\n    darkred: 9109504,\n    darksalmon: 15308410,\n    darkseagreen: 9419919,\n    darkslateblue: 4734347,\n    darkslategray: 3100495,\n    darkslategrey: 3100495,\n    darkturquoise: 52945,\n    darkviolet: 9699539,\n    deeppink: 16716947,\n    deepskyblue: 49151,\n    dimgray: 6908265,\n    dimgrey: 6908265,\n    dodgerblue: 2003199,\n    firebrick: 11674146,\n    floralwhite: 16775920,\n    forestgreen: 2263842,\n    fuchsia: 16711935,\n    gainsboro: 14474460,\n    ghostwhite: 16316671,\n    gold: 16766720,\n    goldenrod: 14329120,\n    gray: 8421504,\n    green: 32768,\n    greenyellow: 11403055,\n    grey: 8421504,\n    honeydew: 15794160,\n    hotpink: 16738740,\n    indianred: 13458524,\n    indigo: 4915330,\n    ivory: 16777200,\n    khaki: 15787660,\n    lavender: 15132410,\n    lavenderblush: 16773365,\n    lawngreen: 8190976,\n    lemonchiffon: 16775885,\n    lightblue: 11393254,\n    lightcoral: 15761536,\n    lightcyan: 14745599,\n    lightgoldenrodyellow: 16448210,\n    lightgray: 13882323,\n    lightgreen: 9498256,\n    lightgrey: 13882323,\n    lightpink: 16758465,\n    lightsalmon: 16752762,\n    lightseagreen: 2142890,\n    lightskyblue: 8900346,\n    lightslategray: 7833753,\n    lightslategrey: 7833753,\n    lightsteelblue: 11584734,\n    lightyellow: 16777184,\n    lime: 65280,\n    limegreen: 3329330,\n    linen: 16445670,\n    magenta: 16711935,\n    maroon: 8388608,\n    mediumaquamarine: 6737322,\n    mediumblue: 205,\n    mediumorchid: 12211667,\n    mediumpurple: 9662683,\n    mediumseagreen: 3978097,\n    mediumslateblue: 8087790,\n    mediumspringgreen: 64154,\n    mediumturquoise: 4772300,\n    mediumvioletred: 13047173,\n    midnightblue: 1644912,\n    mintcream: 16121850,\n    mistyrose: 16770273,\n    moccasin: 16770229,\n    navajowhite: 16768685,\n    navy: 128,\n    oldlace: 16643558,\n    olive: 8421376,\n    olivedrab: 7048739,\n    orange: 16753920,\n    orangered: 16729344,\n    orchid: 14315734,\n    palegoldenrod: 15657130,\n    palegreen: 10025880,\n    paleturquoise: 11529966,\n    palevioletred: 14381203,\n    papayawhip: 16773077,\n    peachpuff: 16767673,\n    peru: 13468991,\n    pink: 16761035,\n    plum: 14524637,\n    powderblue: 11591910,\n    purple: 8388736,\n    rebeccapurple: 6697881,\n    red: 16711680,\n    rosybrown: 12357519,\n    royalblue: 4286945,\n    saddlebrown: 9127187,\n    salmon: 16416882,\n    sandybrown: 16032864,\n    seagreen: 3050327,\n    seashell: 16774638,\n    sienna: 10506797,\n    silver: 12632256,\n    skyblue: 8900331,\n    slateblue: 6970061,\n    slategray: 7372944,\n    slategrey: 7372944,\n    snow: 16775930,\n    springgreen: 65407,\n    steelblue: 4620980,\n    tan: 13808780,\n    teal: 32896,\n    thistle: 14204888,\n    tomato: 16737095,\n    turquoise: 4251856,\n    violet: 15631086,\n    wheat: 16113331,\n    white: 16777215,\n    whitesmoke: 16119285,\n    yellow: 16776960,\n    yellowgreen: 10145074\n  });\n  d3_rgb_names.forEach(function(key, value) {\n    d3_rgb_names.set(key, d3_rgbNumber(value));\n  });\n  function d3_functor(v) {\n    return typeof v === \"function\" ? v : function() {\n      return v;\n    };\n  }\n  d3.functor = d3_functor;\n  d3.xhr = d3_xhrType(d3_identity);\n  function d3_xhrType(response) {\n    return function(url, mimeType, callback) {\n      if (arguments.length === 2 && typeof mimeType === \"function\") callback = mimeType, \n      mimeType = null;\n      return d3_xhr(url, mimeType, response, callback);\n    };\n  }\n  function d3_xhr(url, mimeType, response, callback) {\n    var xhr = {}, dispatch = d3.dispatch(\"beforesend\", \"progress\", \"load\", \"error\"), headers = {}, request = new XMLHttpRequest(), responseType = null;\n    if (this.XDomainRequest && !(\"withCredentials\" in request) && /^(http(s)?:)?\\/\\//.test(url)) request = new XDomainRequest();\n    \"onload\" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {\n      request.readyState > 3 && respond();\n    };\n    function respond() {\n      var status = request.status, result;\n      if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) {\n        try {\n          result = response.call(xhr, request);\n        } catch (e) {\n          dispatch.error.call(xhr, e);\n          return;\n        }\n        dispatch.load.call(xhr, result);\n      } else {\n        dispatch.error.call(xhr, request);\n      }\n    }\n    request.onprogress = function(event) {\n      var o = d3.event;\n      d3.event = event;\n      try {\n        dispatch.progress.call(xhr, request);\n      } finally {\n        d3.event = o;\n      }\n    };\n    xhr.header = function(name, value) {\n      name = (name + \"\").toLowerCase();\n      if (arguments.length < 2) return headers[name];\n      if (value == null) delete headers[name]; else headers[name] = value + \"\";\n      return xhr;\n    };\n    xhr.mimeType = function(value) {\n      if (!arguments.length) return mimeType;\n      mimeType = value == null ? null : value + \"\";\n      return xhr;\n    };\n    xhr.responseType = function(value) {\n      if (!arguments.length) return responseType;\n      responseType = value;\n      return xhr;\n    };\n    xhr.response = function(value) {\n      response = value;\n      return xhr;\n    };\n    [ \"get\", \"post\" ].forEach(function(method) {\n      xhr[method] = function() {\n        return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments)));\n      };\n    });\n    xhr.send = function(method, data, callback) {\n      if (arguments.length === 2 && typeof data === \"function\") callback = data, data = null;\n      request.open(method, url, true);\n      if (mimeType != null && !(\"accept\" in headers)) headers[\"accept\"] = mimeType + \",*/*\";\n      if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);\n      if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);\n      if (responseType != null) request.responseType = responseType;\n      if (callback != null) xhr.on(\"error\", callback).on(\"load\", function(request) {\n        callback(null, request);\n      });\n      dispatch.beforesend.call(xhr, request);\n      request.send(data == null ? null : data);\n      return xhr;\n    };\n    xhr.abort = function() {\n      request.abort();\n      return xhr;\n    };\n    d3.rebind(xhr, dispatch, \"on\");\n    return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));\n  }\n  function d3_xhr_fixCallback(callback) {\n    return callback.length === 1 ? function(error, request) {\n      callback(error == null ? request : null);\n    } : callback;\n  }\n  function d3_xhrHasResponse(request) {\n    var type = request.responseType;\n    return type && type !== \"text\" ? request.response : request.responseText;\n  }\n  d3.dsv = function(delimiter, mimeType) {\n    var reFormat = new RegExp('[\"' + delimiter + \"\\n]\"), delimiterCode = delimiter.charCodeAt(0);\n    function dsv(url, row, callback) {\n      if (arguments.length < 3) callback = row, row = null;\n      var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback);\n      xhr.row = function(_) {\n        return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row;\n      };\n      return xhr;\n    }\n    function response(request) {\n      return dsv.parse(request.responseText);\n    }\n    function typedResponse(f) {\n      return function(request) {\n        return dsv.parse(request.responseText, f);\n      };\n    }\n    dsv.parse = function(text, f) {\n      var o;\n      return dsv.parseRows(text, function(row, i) {\n        if (o) return o(row, i - 1);\n        var a = new Function(\"d\", \"return {\" + row.map(function(name, i) {\n          return JSON.stringify(name) + \": d[\" + i + \"]\";\n        }).join(\",\") + \"}\");\n        o = f ? function(row, i) {\n          return f(a(row), i);\n        } : a;\n      });\n    };\n    dsv.parseRows = function(text, f) {\n      var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol;\n      function token() {\n        if (I >= N) return EOF;\n        if (eol) return eol = false, EOL;\n        var j = I;\n        if (text.charCodeAt(j) === 34) {\n          var i = j;\n          while (i++ < N) {\n            if (text.charCodeAt(i) === 34) {\n              if (text.charCodeAt(i + 1) !== 34) break;\n              ++i;\n            }\n          }\n          I = i + 2;\n          var c = text.charCodeAt(i + 1);\n          if (c === 13) {\n            eol = true;\n            if (text.charCodeAt(i + 2) === 10) ++I;\n          } else if (c === 10) {\n            eol = true;\n          }\n          return text.slice(j + 1, i).replace(/\"\"/g, '\"');\n        }\n        while (I < N) {\n          var c = text.charCodeAt(I++), k = 1;\n          if (c === 10) eol = true; else if (c === 13) {\n            eol = true;\n            if (text.charCodeAt(I) === 10) ++I, ++k;\n          } else if (c !== delimiterCode) continue;\n          return text.slice(j, I - k);\n        }\n        return text.slice(j);\n      }\n      while ((t = token()) !== EOF) {\n        var a = [];\n        while (t !== EOL && t !== EOF) {\n          a.push(t);\n          t = token();\n        }\n        if (f && (a = f(a, n++)) == null) continue;\n        rows.push(a);\n      }\n      return rows;\n    };\n    dsv.format = function(rows) {\n      if (Array.isArray(rows[0])) return dsv.formatRows(rows);\n      var fieldSet = new d3_Set(), fields = [];\n      rows.forEach(function(row) {\n        for (var field in row) {\n          if (!fieldSet.has(field)) {\n            fields.push(fieldSet.add(field));\n          }\n        }\n      });\n      return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) {\n        return fields.map(function(field) {\n          return formatValue(row[field]);\n        }).join(delimiter);\n      })).join(\"\\n\");\n    };\n    dsv.formatRows = function(rows) {\n      return rows.map(formatRow).join(\"\\n\");\n    };\n    function formatRow(row) {\n      return row.map(formatValue).join(delimiter);\n    }\n    function formatValue(text) {\n      return reFormat.test(text) ? '\"' + text.replace(/\\\"/g, '\"\"') + '\"' : text;\n    }\n    return dsv;\n  };\n  d3.csv = d3.dsv(\",\", \"text/csv\");\n  d3.tsv = d3.dsv(\"\t\", \"text/tab-separated-values\");\n  var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_frame = this[d3_vendorSymbol(this, \"requestAnimationFrame\")] || function(callback) {\n    setTimeout(callback, 17);\n  };\n  d3.timer = function() {\n    d3_timer.apply(this, arguments);\n  };\n  function d3_timer(callback, delay, then) {\n    var n = arguments.length;\n    if (n < 2) delay = 0;\n    if (n < 3) then = Date.now();\n    var time = then + delay, timer = {\n      c: callback,\n      t: time,\n      n: null\n    };\n    if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer;\n    d3_timer_queueTail = timer;\n    if (!d3_timer_interval) {\n      d3_timer_timeout = clearTimeout(d3_timer_timeout);\n      d3_timer_interval = 1;\n      d3_timer_frame(d3_timer_step);\n    }\n    return timer;\n  }\n  function d3_timer_step() {\n    var now = d3_timer_mark(), delay = d3_timer_sweep() - now;\n    if (delay > 24) {\n      if (isFinite(delay)) {\n        clearTimeout(d3_timer_timeout);\n        d3_timer_timeout = setTimeout(d3_timer_step, delay);\n      }\n      d3_timer_interval = 0;\n    } else {\n      d3_timer_interval = 1;\n      d3_timer_frame(d3_timer_step);\n    }\n  }\n  d3.timer.flush = function() {\n    d3_timer_mark();\n    d3_timer_sweep();\n  };\n  function d3_timer_mark() {\n    var now = Date.now(), timer = d3_timer_queueHead;\n    while (timer) {\n      if (now >= timer.t && timer.c(now - timer.t)) timer.c = null;\n      timer = timer.n;\n    }\n    return now;\n  }\n  function d3_timer_sweep() {\n    var t0, t1 = d3_timer_queueHead, time = Infinity;\n    while (t1) {\n      if (t1.c) {\n        if (t1.t < time) time = t1.t;\n        t1 = (t0 = t1).n;\n      } else {\n        t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;\n      }\n    }\n    d3_timer_queueTail = t0;\n    return time;\n  }\n  function d3_format_precision(x, p) {\n    return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1);\n  }\n  d3.round = function(x, n) {\n    return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);\n  };\n  var d3_formatPrefixes = [ \"y\", \"z\", \"a\", \"f\", \"p\", \"n\", \"µ\", \"m\", \"\", \"k\", \"M\", \"G\", \"T\", \"P\", \"E\", \"Z\", \"Y\" ].map(d3_formatPrefix);\n  d3.formatPrefix = function(value, precision) {\n    var i = 0;\n    if (value = +value) {\n      if (value < 0) value *= -1;\n      if (precision) value = d3.round(value, d3_format_precision(value, precision));\n      i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);\n      i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3));\n    }\n    return d3_formatPrefixes[8 + i / 3];\n  };\n  function d3_formatPrefix(d, i) {\n    var k = Math.pow(10, abs(8 - i) * 3);\n    return {\n      scale: i > 8 ? function(d) {\n        return d / k;\n      } : function(d) {\n        return d * k;\n      },\n      symbol: d\n    };\n  }\n  function d3_locale_numberFormat(locale) {\n    var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) {\n      var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0;\n      while (i > 0 && g > 0) {\n        if (length + g + 1 > width) g = Math.max(1, width - length);\n        t.push(value.substring(i -= g, i + g));\n        if ((length += g + 1) > width) break;\n        g = locale_grouping[j = (j + 1) % locale_grouping.length];\n      }\n      return t.reverse().join(locale_thousands);\n    } : d3_identity;\n    return function(specifier) {\n      var match = d3_format_re.exec(specifier), fill = match[1] || \" \", align = match[2] || \">\", sign = match[3] || \"-\", symbol = match[4] || \"\", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = \"\", suffix = \"\", integer = false, exponent = true;\n      if (precision) precision = +precision.substring(1);\n      if (zfill || fill === \"0\" && align === \"=\") {\n        zfill = fill = \"0\";\n        align = \"=\";\n      }\n      switch (type) {\n       case \"n\":\n        comma = true;\n        type = \"g\";\n        break;\n\n       case \"%\":\n        scale = 100;\n        suffix = \"%\";\n        type = \"f\";\n        break;\n\n       case \"p\":\n        scale = 100;\n        suffix = \"%\";\n        type = \"r\";\n        break;\n\n       case \"b\":\n       case \"o\":\n       case \"x\":\n       case \"X\":\n        if (symbol === \"#\") prefix = \"0\" + type.toLowerCase();\n\n       case \"c\":\n        exponent = false;\n\n       case \"d\":\n        integer = true;\n        precision = 0;\n        break;\n\n       case \"s\":\n        scale = -1;\n        type = \"r\";\n        break;\n      }\n      if (symbol === \"$\") prefix = locale_currency[0], suffix = locale_currency[1];\n      if (type == \"r\" && !precision) type = \"g\";\n      if (precision != null) {\n        if (type == \"g\") precision = Math.max(1, Math.min(21, precision)); else if (type == \"e\" || type == \"f\") precision = Math.max(0, Math.min(20, precision));\n      }\n      type = d3_format_types.get(type) || d3_format_typeDefault;\n      var zcomma = zfill && comma;\n      return function(value) {\n        var fullSuffix = suffix;\n        if (integer && value % 1) return \"\";\n        var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, \"-\") : sign === \"-\" ? \"\" : sign;\n        if (scale < 0) {\n          var unit = d3.formatPrefix(value, precision);\n          value = unit.scale(value);\n          fullSuffix = unit.symbol + suffix;\n        } else {\n          value *= scale;\n        }\n        value = type(value, precision);\n        var i = value.lastIndexOf(\".\"), before, after;\n        if (i < 0) {\n          var j = exponent ? value.lastIndexOf(\"e\") : -1;\n          if (j < 0) before = value, after = \"\"; else before = value.substring(0, j), after = value.substring(j);\n        } else {\n          before = value.substring(0, i);\n          after = locale_decimal + value.substring(i + 1);\n        }\n        if (!zfill && comma) before = formatGroup(before, Infinity);\n        var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : \"\";\n        if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity);\n        negative += prefix;\n        value = before + after;\n        return (align === \"<\" ? negative + value + padding : align === \">\" ? padding + negative + value : align === \"^\" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix;\n      };\n    };\n  }\n  var d3_format_re = /(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?/i;\n  var d3_format_types = d3.map({\n    b: function(x) {\n      return x.toString(2);\n    },\n    c: function(x) {\n      return String.fromCharCode(x);\n    },\n    o: function(x) {\n      return x.toString(8);\n    },\n    x: function(x) {\n      return x.toString(16);\n    },\n    X: function(x) {\n      return x.toString(16).toUpperCase();\n    },\n    g: function(x, p) {\n      return x.toPrecision(p);\n    },\n    e: function(x, p) {\n      return x.toExponential(p);\n    },\n    f: function(x, p) {\n      return x.toFixed(p);\n    },\n    r: function(x, p) {\n      return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p))));\n    }\n  });\n  function d3_format_typeDefault(x) {\n    return x + \"\";\n  }\n  var d3_time = d3.time = {}, d3_date = Date;\n  function d3_date_utc() {\n    this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]);\n  }\n  d3_date_utc.prototype = {\n    getDate: function() {\n      return this._.getUTCDate();\n    },\n    getDay: function() {\n      return this._.getUTCDay();\n    },\n    getFullYear: function() {\n      return this._.getUTCFullYear();\n    },\n    getHours: function() {\n      return this._.getUTCHours();\n    },\n    getMilliseconds: function() {\n      return this._.getUTCMilliseconds();\n    },\n    getMinutes: function() {\n      return this._.getUTCMinutes();\n    },\n    getMonth: function() {\n      return this._.getUTCMonth();\n    },\n    getSeconds: function() {\n      return this._.getUTCSeconds();\n    },\n    getTime: function() {\n      return this._.getTime();\n    },\n    getTimezoneOffset: function() {\n      return 0;\n    },\n    valueOf: function() {\n      return this._.valueOf();\n    },\n    setDate: function() {\n      d3_time_prototype.setUTCDate.apply(this._, arguments);\n    },\n    setDay: function() {\n      d3_time_prototype.setUTCDay.apply(this._, arguments);\n    },\n    setFullYear: function() {\n      d3_time_prototype.setUTCFullYear.apply(this._, arguments);\n    },\n    setHours: function() {\n      d3_time_prototype.setUTCHours.apply(this._, arguments);\n    },\n    setMilliseconds: function() {\n      d3_time_prototype.setUTCMilliseconds.apply(this._, arguments);\n    },\n    setMinutes: function() {\n      d3_time_prototype.setUTCMinutes.apply(this._, arguments);\n    },\n    setMonth: function() {\n      d3_time_prototype.setUTCMonth.apply(this._, arguments);\n    },\n    setSeconds: function() {\n      d3_time_prototype.setUTCSeconds.apply(this._, arguments);\n    },\n    setTime: function() {\n      d3_time_prototype.setTime.apply(this._, arguments);\n    }\n  };\n  var d3_time_prototype = Date.prototype;\n  function d3_time_interval(local, step, number) {\n    function round(date) {\n      var d0 = local(date), d1 = offset(d0, 1);\n      return date - d0 < d1 - date ? d0 : d1;\n    }\n    function ceil(date) {\n      step(date = local(new d3_date(date - 1)), 1);\n      return date;\n    }\n    function offset(date, k) {\n      step(date = new d3_date(+date), k);\n      return date;\n    }\n    function range(t0, t1, dt) {\n      var time = ceil(t0), times = [];\n      if (dt > 1) {\n        while (time < t1) {\n          if (!(number(time) % dt)) times.push(new Date(+time));\n          step(time, 1);\n        }\n      } else {\n        while (time < t1) times.push(new Date(+time)), step(time, 1);\n      }\n      return times;\n    }\n    function range_utc(t0, t1, dt) {\n      try {\n        d3_date = d3_date_utc;\n        var utc = new d3_date_utc();\n        utc._ = t0;\n        return range(utc, t1, dt);\n      } finally {\n        d3_date = Date;\n      }\n    }\n    local.floor = local;\n    local.round = round;\n    local.ceil = ceil;\n    local.offset = offset;\n    local.range = range;\n    var utc = local.utc = d3_time_interval_utc(local);\n    utc.floor = utc;\n    utc.round = d3_time_interval_utc(round);\n    utc.ceil = d3_time_interval_utc(ceil);\n    utc.offset = d3_time_interval_utc(offset);\n    utc.range = range_utc;\n    return local;\n  }\n  function d3_time_interval_utc(method) {\n    return function(date, k) {\n      try {\n        d3_date = d3_date_utc;\n        var utc = new d3_date_utc();\n        utc._ = date;\n        return method(utc, k)._;\n      } finally {\n        d3_date = Date;\n      }\n    };\n  }\n  d3_time.year = d3_time_interval(function(date) {\n    date = d3_time.day(date);\n    date.setMonth(0, 1);\n    return date;\n  }, function(date, offset) {\n    date.setFullYear(date.getFullYear() + offset);\n  }, function(date) {\n    return date.getFullYear();\n  });\n  d3_time.years = d3_time.year.range;\n  d3_time.years.utc = d3_time.year.utc.range;\n  d3_time.day = d3_time_interval(function(date) {\n    var day = new d3_date(2e3, 0);\n    day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());\n    return day;\n  }, function(date, offset) {\n    date.setDate(date.getDate() + offset);\n  }, function(date) {\n    return date.getDate() - 1;\n  });\n  d3_time.days = d3_time.day.range;\n  d3_time.days.utc = d3_time.day.utc.range;\n  d3_time.dayOfYear = function(date) {\n    var year = d3_time.year(date);\n    return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5);\n  };\n  [ \"sunday\", \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\" ].forEach(function(day, i) {\n    i = 7 - i;\n    var interval = d3_time[day] = d3_time_interval(function(date) {\n      (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7);\n      return date;\n    }, function(date, offset) {\n      date.setDate(date.getDate() + Math.floor(offset) * 7);\n    }, function(date) {\n      var day = d3_time.year(date).getDay();\n      return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i);\n    });\n    d3_time[day + \"s\"] = interval.range;\n    d3_time[day + \"s\"].utc = interval.utc.range;\n    d3_time[day + \"OfYear\"] = function(date) {\n      var day = d3_time.year(date).getDay();\n      return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7);\n    };\n  });\n  d3_time.week = d3_time.sunday;\n  d3_time.weeks = d3_time.sunday.range;\n  d3_time.weeks.utc = d3_time.sunday.utc.range;\n  d3_time.weekOfYear = d3_time.sundayOfYear;\n  function d3_locale_timeFormat(locale) {\n    var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths;\n    function d3_time_format(template) {\n      var n = template.length;\n      function format(date) {\n        var string = [], i = -1, j = 0, c, p, f;\n        while (++i < n) {\n          if (template.charCodeAt(i) === 37) {\n            string.push(template.slice(j, i));\n            if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i);\n            if (f = d3_time_formats[c]) c = f(date, p == null ? c === \"e\" ? \" \" : \"0\" : p);\n            string.push(c);\n            j = i + 1;\n          }\n        }\n        string.push(template.slice(j, i));\n        return string.join(\"\");\n      }\n      format.parse = function(string) {\n        var d = {\n          y: 1900,\n          m: 0,\n          d: 1,\n          H: 0,\n          M: 0,\n          S: 0,\n          L: 0,\n          Z: null\n        }, i = d3_time_parse(d, template, string, 0);\n        if (i != string.length) return null;\n        if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n        var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)();\n        if (\"j\" in d) date.setFullYear(d.y, 0, d.j); else if (\"W\" in d || \"U\" in d) {\n          if (!(\"w\" in d)) d.w = \"W\" in d ? 1 : 0;\n          date.setFullYear(d.y, 0, 1);\n          date.setFullYear(d.y, 0, \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);\n        } else date.setFullYear(d.y, d.m, d.d);\n        date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L);\n        return localZ ? date._ : date;\n      };\n      format.toString = function() {\n        return template;\n      };\n      return format;\n    }\n    function d3_time_parse(date, template, string, j) {\n      var c, p, t, i = 0, n = template.length, m = string.length;\n      while (i < n) {\n        if (j >= m) return -1;\n        c = template.charCodeAt(i++);\n        if (c === 37) {\n          t = template.charAt(i++);\n          p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t];\n          if (!p || (j = p(date, string, j)) < 0) return -1;\n        } else if (c != string.charCodeAt(j++)) {\n          return -1;\n        }\n      }\n      return j;\n    }\n    d3_time_format.utc = function(template) {\n      var local = d3_time_format(template);\n      function format(date) {\n        try {\n          d3_date = d3_date_utc;\n          var utc = new d3_date();\n          utc._ = date;\n          return local(utc);\n        } finally {\n          d3_date = Date;\n        }\n      }\n      format.parse = function(string) {\n        try {\n          d3_date = d3_date_utc;\n          var date = local.parse(string);\n          return date && date._;\n        } finally {\n          d3_date = Date;\n        }\n      };\n      format.toString = local.toString;\n      return format;\n    };\n    d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti;\n    var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths);\n    locale_periods.forEach(function(p, i) {\n      d3_time_periodLookup.set(p.toLowerCase(), i);\n    });\n    var d3_time_formats = {\n      a: function(d) {\n        return locale_shortDays[d.getDay()];\n      },\n      A: function(d) {\n        return locale_days[d.getDay()];\n      },\n      b: function(d) {\n        return locale_shortMonths[d.getMonth()];\n      },\n      B: function(d) {\n        return locale_months[d.getMonth()];\n      },\n      c: d3_time_format(locale_dateTime),\n      d: function(d, p) {\n        return d3_time_formatPad(d.getDate(), p, 2);\n      },\n      e: function(d, p) {\n        return d3_time_formatPad(d.getDate(), p, 2);\n      },\n      H: function(d, p) {\n        return d3_time_formatPad(d.getHours(), p, 2);\n      },\n      I: function(d, p) {\n        return d3_time_formatPad(d.getHours() % 12 || 12, p, 2);\n      },\n      j: function(d, p) {\n        return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3);\n      },\n      L: function(d, p) {\n        return d3_time_formatPad(d.getMilliseconds(), p, 3);\n      },\n      m: function(d, p) {\n        return d3_time_formatPad(d.getMonth() + 1, p, 2);\n      },\n      M: function(d, p) {\n        return d3_time_formatPad(d.getMinutes(), p, 2);\n      },\n      p: function(d) {\n        return locale_periods[+(d.getHours() >= 12)];\n      },\n      S: function(d, p) {\n        return d3_time_formatPad(d.getSeconds(), p, 2);\n      },\n      U: function(d, p) {\n        return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2);\n      },\n      w: function(d) {\n        return d.getDay();\n      },\n      W: function(d, p) {\n        return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2);\n      },\n      x: d3_time_format(locale_date),\n      X: d3_time_format(locale_time),\n      y: function(d, p) {\n        return d3_time_formatPad(d.getFullYear() % 100, p, 2);\n      },\n      Y: function(d, p) {\n        return d3_time_formatPad(d.getFullYear() % 1e4, p, 4);\n      },\n      Z: d3_time_zone,\n      \"%\": function() {\n        return \"%\";\n      }\n    };\n    var d3_time_parsers = {\n      a: d3_time_parseWeekdayAbbrev,\n      A: d3_time_parseWeekday,\n      b: d3_time_parseMonthAbbrev,\n      B: d3_time_parseMonth,\n      c: d3_time_parseLocaleFull,\n      d: d3_time_parseDay,\n      e: d3_time_parseDay,\n      H: d3_time_parseHour24,\n      I: d3_time_parseHour24,\n      j: d3_time_parseDayOfYear,\n      L: d3_time_parseMilliseconds,\n      m: d3_time_parseMonthNumber,\n      M: d3_time_parseMinutes,\n      p: d3_time_parseAmPm,\n      S: d3_time_parseSeconds,\n      U: d3_time_parseWeekNumberSunday,\n      w: d3_time_parseWeekdayNumber,\n      W: d3_time_parseWeekNumberMonday,\n      x: d3_time_parseLocaleDate,\n      X: d3_time_parseLocaleTime,\n      y: d3_time_parseYear,\n      Y: d3_time_parseFullYear,\n      Z: d3_time_parseZone,\n      \"%\": d3_time_parseLiteralPercent\n    };\n    function d3_time_parseWeekdayAbbrev(date, string, i) {\n      d3_time_dayAbbrevRe.lastIndex = 0;\n      var n = d3_time_dayAbbrevRe.exec(string.slice(i));\n      return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n    }\n    function d3_time_parseWeekday(date, string, i) {\n      d3_time_dayRe.lastIndex = 0;\n      var n = d3_time_dayRe.exec(string.slice(i));\n      return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n    }\n    function d3_time_parseMonthAbbrev(date, string, i) {\n      d3_time_monthAbbrevRe.lastIndex = 0;\n      var n = d3_time_monthAbbrevRe.exec(string.slice(i));\n      return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n    }\n    function d3_time_parseMonth(date, string, i) {\n      d3_time_monthRe.lastIndex = 0;\n      var n = d3_time_monthRe.exec(string.slice(i));\n      return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n    }\n    function d3_time_parseLocaleFull(date, string, i) {\n      return d3_time_parse(date, d3_time_formats.c.toString(), string, i);\n    }\n    function d3_time_parseLocaleDate(date, string, i) {\n      return d3_time_parse(date, d3_time_formats.x.toString(), string, i);\n    }\n    function d3_time_parseLocaleTime(date, string, i) {\n      return d3_time_parse(date, d3_time_formats.X.toString(), string, i);\n    }\n    function d3_time_parseAmPm(date, string, i) {\n      var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase());\n      return n == null ? -1 : (date.p = n, i);\n    }\n    return d3_time_format;\n  }\n  var d3_time_formatPads = {\n    \"-\": \"\",\n    _: \" \",\n    \"0\": \"0\"\n  }, d3_time_numberRe = /^\\s*\\d+/, d3_time_percentRe = /^%/;\n  function d3_time_formatPad(value, fill, width) {\n    var sign = value < 0 ? \"-\" : \"\", string = (sign ? -value : value) + \"\", length = string.length;\n    return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n  }\n  function d3_time_formatRe(names) {\n    return new RegExp(\"^(?:\" + names.map(d3.requote).join(\"|\") + \")\", \"i\");\n  }\n  function d3_time_formatLookup(names) {\n    var map = new d3_Map(), i = -1, n = names.length;\n    while (++i < n) map.set(names[i].toLowerCase(), i);\n    return map;\n  }\n  function d3_time_parseWeekdayNumber(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 1));\n    return n ? (date.w = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseWeekNumberSunday(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i));\n    return n ? (date.U = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseWeekNumberMonday(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i));\n    return n ? (date.W = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseFullYear(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 4));\n    return n ? (date.y = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseYear(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 2));\n    return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;\n  }\n  function d3_time_parseZone(date, string, i) {\n    return /^[+-]\\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, \n    i + 5) : -1;\n  }\n  function d3_time_expandYear(d) {\n    return d + (d > 68 ? 1900 : 2e3);\n  }\n  function d3_time_parseMonthNumber(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 2));\n    return n ? (date.m = n[0] - 1, i + n[0].length) : -1;\n  }\n  function d3_time_parseDay(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 2));\n    return n ? (date.d = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseDayOfYear(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 3));\n    return n ? (date.j = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseHour24(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 2));\n    return n ? (date.H = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseMinutes(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 2));\n    return n ? (date.M = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseSeconds(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 2));\n    return n ? (date.S = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_parseMilliseconds(date, string, i) {\n    d3_time_numberRe.lastIndex = 0;\n    var n = d3_time_numberRe.exec(string.slice(i, i + 3));\n    return n ? (date.L = +n[0], i + n[0].length) : -1;\n  }\n  function d3_time_zone(d) {\n    var z = d.getTimezoneOffset(), zs = z > 0 ? \"-\" : \"+\", zh = abs(z) / 60 | 0, zm = abs(z) % 60;\n    return zs + d3_time_formatPad(zh, \"0\", 2) + d3_time_formatPad(zm, \"0\", 2);\n  }\n  function d3_time_parseLiteralPercent(date, string, i) {\n    d3_time_percentRe.lastIndex = 0;\n    var n = d3_time_percentRe.exec(string.slice(i, i + 1));\n    return n ? i + n[0].length : -1;\n  }\n  function d3_time_formatMulti(formats) {\n    var n = formats.length, i = -1;\n    while (++i < n) formats[i][0] = this(formats[i][0]);\n    return function(date) {\n      var i = 0, f = formats[i];\n      while (!f[1](date)) f = formats[++i];\n      return f[0](date);\n    };\n  }\n  d3.locale = function(locale) {\n    return {\n      numberFormat: d3_locale_numberFormat(locale),\n      timeFormat: d3_locale_timeFormat(locale)\n    };\n  };\n  var d3_locale_enUS = d3.locale({\n    decimal: \".\",\n    thousands: \",\",\n    grouping: [ 3 ],\n    currency: [ \"$\", \"\" ],\n    dateTime: \"%a %b %e %X %Y\",\n    date: \"%m/%d/%Y\",\n    time: \"%H:%M:%S\",\n    periods: [ \"AM\", \"PM\" ],\n    days: [ \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\" ],\n    shortDays: [ \"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\" ],\n    months: [ \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\" ],\n    shortMonths: [ \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\" ]\n  });\n  d3.format = d3_locale_enUS.numberFormat;\n  d3.geo = {};\n  function d3_adder() {}\n  d3_adder.prototype = {\n    s: 0,\n    t: 0,\n    add: function(y) {\n      d3_adderSum(y, this.t, d3_adderTemp);\n      d3_adderSum(d3_adderTemp.s, this.s, this);\n      if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t;\n    },\n    reset: function() {\n      this.s = this.t = 0;\n    },\n    valueOf: function() {\n      return this.s;\n    }\n  };\n  var d3_adderTemp = new d3_adder();\n  function d3_adderSum(a, b, o) {\n    var x = o.s = a + b, bv = x - a, av = x - bv;\n    o.t = a - av + (b - bv);\n  }\n  d3.geo.stream = function(object, listener) {\n    if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) {\n      d3_geo_streamObjectType[object.type](object, listener);\n    } else {\n      d3_geo_streamGeometry(object, listener);\n    }\n  };\n  function d3_geo_streamGeometry(geometry, listener) {\n    if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) {\n      d3_geo_streamGeometryType[geometry.type](geometry, listener);\n    }\n  }\n  var d3_geo_streamObjectType = {\n    Feature: function(feature, listener) {\n      d3_geo_streamGeometry(feature.geometry, listener);\n    },\n    FeatureCollection: function(object, listener) {\n      var features = object.features, i = -1, n = features.length;\n      while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener);\n    }\n  };\n  var d3_geo_streamGeometryType = {\n    Sphere: function(object, listener) {\n      listener.sphere();\n    },\n    Point: function(object, listener) {\n      object = object.coordinates;\n      listener.point(object[0], object[1], object[2]);\n    },\n    MultiPoint: function(object, listener) {\n      var coordinates = object.coordinates, i = -1, n = coordinates.length;\n      while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]);\n    },\n    LineString: function(object, listener) {\n      d3_geo_streamLine(object.coordinates, listener, 0);\n    },\n    MultiLineString: function(object, listener) {\n      var coordinates = object.coordinates, i = -1, n = coordinates.length;\n      while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0);\n    },\n    Polygon: function(object, listener) {\n      d3_geo_streamPolygon(object.coordinates, listener);\n    },\n    MultiPolygon: function(object, listener) {\n      var coordinates = object.coordinates, i = -1, n = coordinates.length;\n      while (++i < n) d3_geo_streamPolygon(coordinates[i], listener);\n    },\n    GeometryCollection: function(object, listener) {\n      var geometries = object.geometries, i = -1, n = geometries.length;\n      while (++i < n) d3_geo_streamGeometry(geometries[i], listener);\n    }\n  };\n  function d3_geo_streamLine(coordinates, listener, closed) {\n    var i = -1, n = coordinates.length - closed, coordinate;\n    listener.lineStart();\n    while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]);\n    listener.lineEnd();\n  }\n  function d3_geo_streamPolygon(coordinates, listener) {\n    var i = -1, n = coordinates.length;\n    listener.polygonStart();\n    while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);\n    listener.polygonEnd();\n  }\n  d3.geo.area = function(object) {\n    d3_geo_areaSum = 0;\n    d3.geo.stream(object, d3_geo_area);\n    return d3_geo_areaSum;\n  };\n  var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder();\n  var d3_geo_area = {\n    sphere: function() {\n      d3_geo_areaSum += 4 * π;\n    },\n    point: d3_noop,\n    lineStart: d3_noop,\n    lineEnd: d3_noop,\n    polygonStart: function() {\n      d3_geo_areaRingSum.reset();\n      d3_geo_area.lineStart = d3_geo_areaRingStart;\n    },\n    polygonEnd: function() {\n      var area = 2 * d3_geo_areaRingSum;\n      d3_geo_areaSum += area < 0 ? 4 * π + area : area;\n      d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;\n    }\n  };\n  function d3_geo_areaRingStart() {\n    var λ00, φ00, λ0, cosφ0, sinφ0;\n    d3_geo_area.point = function(λ, φ) {\n      d3_geo_area.point = nextPoint;\n      λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), \n      sinφ0 = Math.sin(φ);\n    };\n    function nextPoint(λ, φ) {\n      λ *= d3_radians;\n      φ = φ * d3_radians / 2 + π / 4;\n      var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ);\n      d3_geo_areaRingSum.add(Math.atan2(v, u));\n      λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ;\n    }\n    d3_geo_area.lineEnd = function() {\n      nextPoint(λ00, φ00);\n    };\n  }\n  function d3_geo_cartesian(spherical) {\n    var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ);\n    return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ];\n  }\n  function d3_geo_cartesianDot(a, b) {\n    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n  }\n  function d3_geo_cartesianCross(a, b) {\n    return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ];\n  }\n  function d3_geo_cartesianAdd(a, b) {\n    a[0] += b[0];\n    a[1] += b[1];\n    a[2] += b[2];\n  }\n  function d3_geo_cartesianScale(vector, k) {\n    return [ vector[0] * k, vector[1] * k, vector[2] * k ];\n  }\n  function d3_geo_cartesianNormalize(d) {\n    var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);\n    d[0] /= l;\n    d[1] /= l;\n    d[2] /= l;\n  }\n  function d3_geo_spherical(cartesian) {\n    return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ];\n  }\n  function d3_geo_sphericalEqual(a, b) {\n    return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε;\n  }\n  d3.geo.bounds = function() {\n    var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range;\n    var bound = {\n      point: point,\n      lineStart: lineStart,\n      lineEnd: lineEnd,\n      polygonStart: function() {\n        bound.point = ringPoint;\n        bound.lineStart = ringStart;\n        bound.lineEnd = ringEnd;\n        dλSum = 0;\n        d3_geo_area.polygonStart();\n      },\n      polygonEnd: function() {\n        d3_geo_area.polygonEnd();\n        bound.point = point;\n        bound.lineStart = lineStart;\n        bound.lineEnd = lineEnd;\n        if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90;\n        range[0] = λ0, range[1] = λ1;\n      }\n    };\n    function point(λ, φ) {\n      ranges.push(range = [ λ0 = λ, λ1 = λ ]);\n      if (φ < φ0) φ0 = φ;\n      if (φ > φ1) φ1 = φ;\n    }\n    function linePoint(λ, φ) {\n      var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]);\n      if (p0) {\n        var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal);\n        d3_geo_cartesianNormalize(inflection);\n        inflection = d3_geo_spherical(inflection);\n        var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180;\n        if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) {\n          var φi = inflection[1] * d3_degrees;\n          if (φi > φ1) φ1 = φi;\n        } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) {\n          var φi = -inflection[1] * d3_degrees;\n          if (φi < φ0) φ0 = φi;\n        } else {\n          if (φ < φ0) φ0 = φ;\n          if (φ > φ1) φ1 = φ;\n        }\n        if (antimeridian) {\n          if (λ < λ_) {\n            if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;\n          } else {\n            if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;\n          }\n        } else {\n          if (λ1 >= λ0) {\n            if (λ < λ0) λ0 = λ;\n            if (λ > λ1) λ1 = λ;\n          } else {\n            if (λ > λ_) {\n              if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;\n            } else {\n              if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;\n            }\n          }\n        }\n      } else {\n        point(λ, φ);\n      }\n      p0 = p, λ_ = λ;\n    }\n    function lineStart() {\n      bound.point = linePoint;\n    }\n    function lineEnd() {\n      range[0] = λ0, range[1] = λ1;\n      bound.point = point;\n      p0 = null;\n    }\n    function ringPoint(λ, φ) {\n      if (p0) {\n        var dλ = λ - λ_;\n        dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;\n      } else λ__ = λ, φ__ = φ;\n      d3_geo_area.point(λ, φ);\n      linePoint(λ, φ);\n    }\n    function ringStart() {\n      d3_geo_area.lineStart();\n    }\n    function ringEnd() {\n      ringPoint(λ__, φ__);\n      d3_geo_area.lineEnd();\n      if (abs(dλSum) > ε) λ0 = -(λ1 = 180);\n      range[0] = λ0, range[1] = λ1;\n      p0 = null;\n    }\n    function angle(λ0, λ1) {\n      return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1;\n    }\n    function compareRanges(a, b) {\n      return a[0] - b[0];\n    }\n    function withinRange(x, range) {\n      return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;\n    }\n    return function(feature) {\n      φ1 = λ1 = -(λ0 = φ0 = Infinity);\n      ranges = [];\n      d3.geo.stream(feature, bound);\n      var n = ranges.length;\n      if (n) {\n        ranges.sort(compareRanges);\n        for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) {\n          b = ranges[i];\n          if (withinRange(b[0], a) || withinRange(b[1], a)) {\n            if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];\n            if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];\n          } else {\n            merged.push(a = b);\n          }\n        }\n        var best = -Infinity, dλ;\n        for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) {\n          b = merged[i];\n          if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1];\n        }\n      }\n      ranges = range = null;\n      return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ];\n    };\n  }();\n  d3.geo.centroid = function(object) {\n    d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;\n    d3.geo.stream(object, d3_geo_centroid);\n    var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z;\n    if (m < ε2) {\n      x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1;\n      if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0;\n      m = x * x + y * y + z * z;\n      if (m < ε2) return [ NaN, NaN ];\n    }\n    return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ];\n  };\n  var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2;\n  var d3_geo_centroid = {\n    sphere: d3_noop,\n    point: d3_geo_centroidPoint,\n    lineStart: d3_geo_centroidLineStart,\n    lineEnd: d3_geo_centroidLineEnd,\n    polygonStart: function() {\n      d3_geo_centroid.lineStart = d3_geo_centroidRingStart;\n    },\n    polygonEnd: function() {\n      d3_geo_centroid.lineStart = d3_geo_centroidLineStart;\n    }\n  };\n  function d3_geo_centroidPoint(λ, φ) {\n    λ *= d3_radians;\n    var cosφ = Math.cos(φ *= d3_radians);\n    d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ));\n  }\n  function d3_geo_centroidPointXYZ(x, y, z) {\n    ++d3_geo_centroidW0;\n    d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0;\n    d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0;\n    d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0;\n  }\n  function d3_geo_centroidLineStart() {\n    var x0, y0, z0;\n    d3_geo_centroid.point = function(λ, φ) {\n      λ *= d3_radians;\n      var cosφ = Math.cos(φ *= d3_radians);\n      x0 = cosφ * Math.cos(λ);\n      y0 = cosφ * Math.sin(λ);\n      z0 = Math.sin(φ);\n      d3_geo_centroid.point = nextPoint;\n      d3_geo_centroidPointXYZ(x0, y0, z0);\n    };\n    function nextPoint(λ, φ) {\n      λ *= d3_radians;\n      var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);\n      d3_geo_centroidW1 += w;\n      d3_geo_centroidX1 += w * (x0 + (x0 = x));\n      d3_geo_centroidY1 += w * (y0 + (y0 = y));\n      d3_geo_centroidZ1 += w * (z0 + (z0 = z));\n      d3_geo_centroidPointXYZ(x0, y0, z0);\n    }\n  }\n  function d3_geo_centroidLineEnd() {\n    d3_geo_centroid.point = d3_geo_centroidPoint;\n  }\n  function d3_geo_centroidRingStart() {\n    var λ00, φ00, x0, y0, z0;\n    d3_geo_centroid.point = function(λ, φ) {\n      λ00 = λ, φ00 = φ;\n      d3_geo_centroid.point = nextPoint;\n      λ *= d3_radians;\n      var cosφ = Math.cos(φ *= d3_radians);\n      x0 = cosφ * Math.cos(λ);\n      y0 = cosφ * Math.sin(λ);\n      z0 = Math.sin(φ);\n      d3_geo_centroidPointXYZ(x0, y0, z0);\n    };\n    d3_geo_centroid.lineEnd = function() {\n      nextPoint(λ00, φ00);\n      d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd;\n      d3_geo_centroid.point = d3_geo_centroidPoint;\n    };\n    function nextPoint(λ, φ) {\n      λ *= d3_radians;\n      var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u);\n      d3_geo_centroidX2 += v * cx;\n      d3_geo_centroidY2 += v * cy;\n      d3_geo_centroidZ2 += v * cz;\n      d3_geo_centroidW1 += w;\n      d3_geo_centroidX1 += w * (x0 + (x0 = x));\n      d3_geo_centroidY1 += w * (y0 + (y0 = y));\n      d3_geo_centroidZ1 += w * (z0 + (z0 = z));\n      d3_geo_centroidPointXYZ(x0, y0, z0);\n    }\n  }\n  function d3_geo_compose(a, b) {\n    function compose(x, y) {\n      return x = a(x, y), b(x[0], x[1]);\n    }\n    if (a.invert && b.invert) compose.invert = function(x, y) {\n      return x = b.invert(x, y), x && a.invert(x[0], x[1]);\n    };\n    return compose;\n  }\n  function d3_true() {\n    return true;\n  }\n  function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) {\n    var subject = [], clip = [];\n    segments.forEach(function(segment) {\n      if ((n = segment.length - 1) <= 0) return;\n      var n, p0 = segment[0], p1 = segment[n];\n      if (d3_geo_sphericalEqual(p0, p1)) {\n        listener.lineStart();\n        for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]);\n        listener.lineEnd();\n        return;\n      }\n      var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false);\n      a.o = b;\n      subject.push(a);\n      clip.push(b);\n      a = new d3_geo_clipPolygonIntersection(p1, segment, null, false);\n      b = new d3_geo_clipPolygonIntersection(p1, null, a, true);\n      a.o = b;\n      subject.push(a);\n      clip.push(b);\n    });\n    clip.sort(compare);\n    d3_geo_clipPolygonLinkCircular(subject);\n    d3_geo_clipPolygonLinkCircular(clip);\n    if (!subject.length) return;\n    for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) {\n      clip[i].e = entry = !entry;\n    }\n    var start = subject[0], points, point;\n    while (1) {\n      var current = start, isSubject = true;\n      while (current.v) if ((current = current.n) === start) return;\n      points = current.z;\n      listener.lineStart();\n      do {\n        current.v = current.o.v = true;\n        if (current.e) {\n          if (isSubject) {\n            for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]);\n          } else {\n            interpolate(current.x, current.n.x, 1, listener);\n          }\n          current = current.n;\n        } else {\n          if (isSubject) {\n            points = current.p.z;\n            for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]);\n          } else {\n            interpolate(current.x, current.p.x, -1, listener);\n          }\n          current = current.p;\n        }\n        current = current.o;\n        points = current.z;\n        isSubject = !isSubject;\n      } while (!current.v);\n      listener.lineEnd();\n    }\n  }\n  function d3_geo_clipPolygonLinkCircular(array) {\n    if (!(n = array.length)) return;\n    var n, i = 0, a = array[0], b;\n    while (++i < n) {\n      a.n = b = array[i];\n      b.p = a;\n      a = b;\n    }\n    a.n = b = array[0];\n    b.p = a;\n  }\n  function d3_geo_clipPolygonIntersection(point, points, other, entry) {\n    this.x = point;\n    this.z = points;\n    this.o = other;\n    this.e = entry;\n    this.v = false;\n    this.n = this.p = null;\n  }\n  function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {\n    return function(rotate, listener) {\n      var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]);\n      var clip = {\n        point: point,\n        lineStart: lineStart,\n        lineEnd: lineEnd,\n        polygonStart: function() {\n          clip.point = pointRing;\n          clip.lineStart = ringStart;\n          clip.lineEnd = ringEnd;\n          segments = [];\n          polygon = [];\n        },\n        polygonEnd: function() {\n          clip.point = point;\n          clip.lineStart = lineStart;\n          clip.lineEnd = lineEnd;\n          segments = d3.merge(segments);\n          var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);\n          if (segments.length) {\n            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;\n            d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);\n          } else if (clipStartInside) {\n            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;\n            listener.lineStart();\n            interpolate(null, null, 1, listener);\n            listener.lineEnd();\n          }\n          if (polygonStarted) listener.polygonEnd(), polygonStarted = false;\n          segments = polygon = null;\n        },\n        sphere: function() {\n          listener.polygonStart();\n          listener.lineStart();\n          interpolate(null, null, 1, listener);\n          listener.lineEnd();\n          listener.polygonEnd();\n        }\n      };\n      function point(λ, φ) {\n        var point = rotate(λ, φ);\n        if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ);\n      }\n      function pointLine(λ, φ) {\n        var point = rotate(λ, φ);\n        line.point(point[0], point[1]);\n      }\n      function lineStart() {\n        clip.point = pointLine;\n        line.lineStart();\n      }\n      function lineEnd() {\n        clip.point = point;\n        line.lineEnd();\n      }\n      var segments;\n      var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring;\n      function pointRing(λ, φ) {\n        ring.push([ λ, φ ]);\n        var point = rotate(λ, φ);\n        ringListener.point(point[0], point[1]);\n      }\n      function ringStart() {\n        ringListener.lineStart();\n        ring = [];\n      }\n      function ringEnd() {\n        pointRing(ring[0][0], ring[0][1]);\n        ringListener.lineEnd();\n        var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length;\n        ring.pop();\n        polygon.push(ring);\n        ring = null;\n        if (!n) return;\n        if (clean & 1) {\n          segment = ringSegments[0];\n          var n = segment.length - 1, i = -1, point;\n          if (n > 0) {\n            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;\n            listener.lineStart();\n            while (++i < n) listener.point((point = segment[i])[0], point[1]);\n            listener.lineEnd();\n          }\n          return;\n        }\n        if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));\n        segments.push(ringSegments.filter(d3_geo_clipSegmentLength1));\n      }\n      return clip;\n    };\n  }\n  function d3_geo_clipSegmentLength1(segment) {\n    return segment.length > 1;\n  }\n  function d3_geo_clipBufferListener() {\n    var lines = [], line;\n    return {\n      lineStart: function() {\n        lines.push(line = []);\n      },\n      point: function(λ, φ) {\n        line.push([ λ, φ ]);\n      },\n      lineEnd: d3_noop,\n      buffer: function() {\n        var buffer = lines;\n        lines = [];\n        line = null;\n        return buffer;\n      },\n      rejoin: function() {\n        if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));\n      }\n    };\n  }\n  function d3_geo_clipSort(a, b) {\n    return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]);\n  }\n  var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]);\n  function d3_geo_clipAntimeridianLine(listener) {\n    var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean;\n    return {\n      lineStart: function() {\n        listener.lineStart();\n        clean = 1;\n      },\n      point: function(λ1, φ1) {\n        var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0);\n        if (abs(dλ - π) < ε) {\n          listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ);\n          listener.point(sλ0, φ0);\n          listener.lineEnd();\n          listener.lineStart();\n          listener.point(sλ1, φ0);\n          listener.point(λ1, φ0);\n          clean = 0;\n        } else if (sλ0 !== sλ1 && dλ >= π) {\n          if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;\n          if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;\n          φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1);\n          listener.point(sλ0, φ0);\n          listener.lineEnd();\n          listener.lineStart();\n          listener.point(sλ1, φ0);\n          clean = 0;\n        }\n        listener.point(λ0 = λ1, φ0 = φ1);\n        sλ0 = sλ1;\n      },\n      lineEnd: function() {\n        listener.lineEnd();\n        λ0 = φ0 = NaN;\n      },\n      clean: function() {\n        return 2 - clean;\n      }\n    };\n  }\n  function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {\n    var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1);\n    return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;\n  }\n  function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {\n    var φ;\n    if (from == null) {\n      φ = direction * halfπ;\n      listener.point(-π, φ);\n      listener.point(0, φ);\n      listener.point(π, φ);\n      listener.point(π, 0);\n      listener.point(π, -φ);\n      listener.point(0, -φ);\n      listener.point(-π, -φ);\n      listener.point(-π, 0);\n      listener.point(-π, φ);\n    } else if (abs(from[0] - to[0]) > ε) {\n      var s = from[0] < to[0] ? π : -π;\n      φ = direction * s / 2;\n      listener.point(-s, φ);\n      listener.point(0, φ);\n      listener.point(s, φ);\n    } else {\n      listener.point(to[0], to[1]);\n    }\n  }\n  function d3_geo_pointInPolygon(point, polygon) {\n    var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0;\n    d3_geo_areaRingSum.reset();\n    for (var i = 0, n = polygon.length; i < n; ++i) {\n      var ring = polygon[i], m = ring.length;\n      if (!m) continue;\n      var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1;\n      while (true) {\n        if (j === m) j = 0;\n        point = ring[j];\n        var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ;\n        d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ)));\n        polarAngle += antimeridian ? dλ + sdλ * τ : dλ;\n        if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) {\n          var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point));\n          d3_geo_cartesianNormalize(arc);\n          var intersection = d3_geo_cartesianCross(meridianNormal, arc);\n          d3_geo_cartesianNormalize(intersection);\n          var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]);\n          if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) {\n            winding += antimeridian ^ dλ >= 0 ? 1 : -1;\n          }\n        }\n        if (!j++) break;\n        λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point;\n      }\n    }\n    return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1;\n  }\n  function d3_geo_clipCircle(radius) {\n    var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians);\n    return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]);\n    function visible(λ, φ) {\n      return Math.cos(λ) * Math.cos(φ) > cr;\n    }\n    function clipLine(listener) {\n      var point0, c0, v0, v00, clean;\n      return {\n        lineStart: function() {\n          v00 = v0 = false;\n          clean = 1;\n        },\n        point: function(λ, φ) {\n          var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0;\n          if (!point0 && (v00 = v0 = v)) listener.lineStart();\n          if (v !== v0) {\n            point2 = intersect(point0, point1);\n            if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) {\n              point1[0] += ε;\n              point1[1] += ε;\n              v = visible(point1[0], point1[1]);\n            }\n          }\n          if (v !== v0) {\n            clean = 0;\n            if (v) {\n              listener.lineStart();\n              point2 = intersect(point1, point0);\n              listener.point(point2[0], point2[1]);\n            } else {\n              point2 = intersect(point0, point1);\n              listener.point(point2[0], point2[1]);\n              listener.lineEnd();\n            }\n            point0 = point2;\n          } else if (notHemisphere && point0 && smallRadius ^ v) {\n            var t;\n            if (!(c & c0) && (t = intersect(point1, point0, true))) {\n              clean = 0;\n              if (smallRadius) {\n                listener.lineStart();\n                listener.point(t[0][0], t[0][1]);\n                listener.point(t[1][0], t[1][1]);\n                listener.lineEnd();\n              } else {\n                listener.point(t[1][0], t[1][1]);\n                listener.lineEnd();\n                listener.lineStart();\n                listener.point(t[0][0], t[0][1]);\n              }\n            }\n          }\n          if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) {\n            listener.point(point1[0], point1[1]);\n          }\n          point0 = point1, v0 = v, c0 = c;\n        },\n        lineEnd: function() {\n          if (v0) listener.lineEnd();\n          point0 = null;\n        },\n        clean: function() {\n          return clean | (v00 && v0) << 1;\n        }\n      };\n    }\n    function intersect(a, b, two) {\n      var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b);\n      var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;\n      if (!determinant) return !two && a;\n      var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2);\n      d3_geo_cartesianAdd(A, B);\n      var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1);\n      if (t2 < 0) return;\n      var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu);\n      d3_geo_cartesianAdd(q, A);\n      q = d3_geo_spherical(q);\n      if (!two) return q;\n      var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z;\n      if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z;\n      var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε;\n      if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z;\n      if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) {\n        var q1 = d3_geo_cartesianScale(u, (-w + t) / uu);\n        d3_geo_cartesianAdd(q1, A);\n        return [ q, d3_geo_spherical(q1) ];\n      }\n    }\n    function code(λ, φ) {\n      var r = smallRadius ? radius : π - radius, code = 0;\n      if (λ < -r) code |= 1; else if (λ > r) code |= 2;\n      if (φ < -r) code |= 4; else if (φ > r) code |= 8;\n      return code;\n    }\n  }\n  function d3_geom_clipLine(x0, y0, x1, y1) {\n    return function(line) {\n      var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r;\n      r = x0 - ax;\n      if (!dx && r > 0) return;\n      r /= dx;\n      if (dx < 0) {\n        if (r < t0) return;\n        if (r < t1) t1 = r;\n      } else if (dx > 0) {\n        if (r > t1) return;\n        if (r > t0) t0 = r;\n      }\n      r = x1 - ax;\n      if (!dx && r < 0) return;\n      r /= dx;\n      if (dx < 0) {\n        if (r > t1) return;\n        if (r > t0) t0 = r;\n      } else if (dx > 0) {\n        if (r < t0) return;\n        if (r < t1) t1 = r;\n      }\n      r = y0 - ay;\n      if (!dy && r > 0) return;\n      r /= dy;\n      if (dy < 0) {\n        if (r < t0) return;\n        if (r < t1) t1 = r;\n      } else if (dy > 0) {\n        if (r > t1) return;\n        if (r > t0) t0 = r;\n      }\n      r = y1 - ay;\n      if (!dy && r < 0) return;\n      r /= dy;\n      if (dy < 0) {\n        if (r > t1) return;\n        if (r > t0) t0 = r;\n      } else if (dy > 0) {\n        if (r < t0) return;\n        if (r < t1) t1 = r;\n      }\n      if (t0 > 0) line.a = {\n        x: ax + t0 * dx,\n        y: ay + t0 * dy\n      };\n      if (t1 < 1) line.b = {\n        x: ax + t1 * dx,\n        y: ay + t1 * dy\n      };\n      return line;\n    };\n  }\n  var d3_geo_clipExtentMAX = 1e9;\n  d3.geo.clipExtent = function() {\n    var x0, y0, x1, y1, stream, clip, clipExtent = {\n      stream: function(output) {\n        if (stream) stream.valid = false;\n        stream = clip(output);\n        stream.valid = true;\n        return stream;\n      },\n      extent: function(_) {\n        if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];\n        clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]);\n        if (stream) stream.valid = false, stream = null;\n        return clipExtent;\n      }\n    };\n    return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]);\n  };\n  function d3_geo_clipExtent(x0, y0, x1, y1) {\n    return function(listener) {\n      var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring;\n      var clip = {\n        point: point,\n        lineStart: lineStart,\n        lineEnd: lineEnd,\n        polygonStart: function() {\n          listener = bufferListener;\n          segments = [];\n          polygon = [];\n          clean = true;\n        },\n        polygonEnd: function() {\n          listener = listener_;\n          segments = d3.merge(segments);\n          var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length;\n          if (inside || visible) {\n            listener.polygonStart();\n            if (inside) {\n              listener.lineStart();\n              interpolate(null, null, 1, listener);\n              listener.lineEnd();\n            }\n            if (visible) {\n              d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener);\n            }\n            listener.polygonEnd();\n          }\n          segments = polygon = ring = null;\n        }\n      };\n      function insidePolygon(p) {\n        var wn = 0, n = polygon.length, y = p[1];\n        for (var i = 0; i < n; ++i) {\n          for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) {\n            b = v[j];\n            if (a[1] <= y) {\n              if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn;\n            } else {\n              if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn;\n            }\n            a = b;\n          }\n        }\n        return wn !== 0;\n      }\n      function interpolate(from, to, direction, listener) {\n        var a = 0, a1 = 0;\n        if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) {\n          do {\n            listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);\n          } while ((a = (a + direction + 4) % 4) !== a1);\n        } else {\n          listener.point(to[0], to[1]);\n        }\n      }\n      function pointVisible(x, y) {\n        return x0 <= x && x <= x1 && y0 <= y && y <= y1;\n      }\n      function point(x, y) {\n        if (pointVisible(x, y)) listener.point(x, y);\n      }\n      var x__, y__, v__, x_, y_, v_, first, clean;\n      function lineStart() {\n        clip.point = linePoint;\n        if (polygon) polygon.push(ring = []);\n        first = true;\n        v_ = false;\n        x_ = y_ = NaN;\n      }\n      function lineEnd() {\n        if (segments) {\n          linePoint(x__, y__);\n          if (v__ && v_) bufferListener.rejoin();\n          segments.push(bufferListener.buffer());\n        }\n        clip.point = point;\n        if (v_) listener.lineEnd();\n      }\n      function linePoint(x, y) {\n        x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));\n        y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));\n        var v = pointVisible(x, y);\n        if (polygon) ring.push([ x, y ]);\n        if (first) {\n          x__ = x, y__ = y, v__ = v;\n          first = false;\n          if (v) {\n            listener.lineStart();\n            listener.point(x, y);\n          }\n        } else {\n          if (v && v_) listener.point(x, y); else {\n            var l = {\n              a: {\n                x: x_,\n                y: y_\n              },\n              b: {\n                x: x,\n                y: y\n              }\n            };\n            if (clipLine(l)) {\n              if (!v_) {\n                listener.lineStart();\n                listener.point(l.a.x, l.a.y);\n              }\n              listener.point(l.b.x, l.b.y);\n              if (!v) listener.lineEnd();\n              clean = false;\n            } else if (v) {\n              listener.lineStart();\n              listener.point(x, y);\n              clean = false;\n            }\n          }\n        }\n        x_ = x, y_ = y, v_ = v;\n      }\n      return clip;\n    };\n    function corner(p, direction) {\n      return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2;\n    }\n    function compare(a, b) {\n      return comparePoints(a.x, b.x);\n    }\n    function comparePoints(a, b) {\n      var ca = corner(a, 1), cb = corner(b, 1);\n      return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0];\n    }\n  }\n  function d3_geo_conic(projectAt) {\n    var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1);\n    p.parallels = function(_) {\n      if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ];\n      return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180);\n    };\n    return p;\n  }\n  function d3_geo_conicEqualArea(φ0, φ1) {\n    var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n;\n    function forward(λ, φ) {\n      var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n;\n      return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ];\n    }\n    forward.invert = function(x, y) {\n      var ρ0_y = ρ0 - y;\n      return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ];\n    };\n    return forward;\n  }\n  (d3.geo.conicEqualArea = function() {\n    return d3_geo_conic(d3_geo_conicEqualArea);\n  }).raw = d3_geo_conicEqualArea;\n  d3.geo.albers = function() {\n    return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070);\n  };\n  d3.geo.albersUsa = function() {\n    var lower48 = d3.geo.albers();\n    var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]);\n    var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]);\n    var point, pointStream = {\n      point: function(x, y) {\n        point = [ x, y ];\n      }\n    }, lower48Point, alaskaPoint, hawaiiPoint;\n    function albersUsa(coordinates) {\n      var x = coordinates[0], y = coordinates[1];\n      point = null;\n      (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y);\n      return point;\n    }\n    albersUsa.invert = function(coordinates) {\n      var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k;\n      return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates);\n    };\n    albersUsa.stream = function(stream) {\n      var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream);\n      return {\n        point: function(x, y) {\n          lower48Stream.point(x, y);\n          alaskaStream.point(x, y);\n          hawaiiStream.point(x, y);\n        },\n        sphere: function() {\n          lower48Stream.sphere();\n          alaskaStream.sphere();\n          hawaiiStream.sphere();\n        },\n        lineStart: function() {\n          lower48Stream.lineStart();\n          alaskaStream.lineStart();\n          hawaiiStream.lineStart();\n        },\n        lineEnd: function() {\n          lower48Stream.lineEnd();\n          alaskaStream.lineEnd();\n          hawaiiStream.lineEnd();\n        },\n        polygonStart: function() {\n          lower48Stream.polygonStart();\n          alaskaStream.polygonStart();\n          hawaiiStream.polygonStart();\n        },\n        polygonEnd: function() {\n          lower48Stream.polygonEnd();\n          alaskaStream.polygonEnd();\n          hawaiiStream.polygonEnd();\n        }\n      };\n    };\n    albersUsa.precision = function(_) {\n      if (!arguments.length) return lower48.precision();\n      lower48.precision(_);\n      alaska.precision(_);\n      hawaii.precision(_);\n      return albersUsa;\n    };\n    albersUsa.scale = function(_) {\n      if (!arguments.length) return lower48.scale();\n      lower48.scale(_);\n      alaska.scale(_ * .35);\n      hawaii.scale(_);\n      return albersUsa.translate(lower48.translate());\n    };\n    albersUsa.translate = function(_) {\n      if (!arguments.length) return lower48.translate();\n      var k = lower48.scale(), x = +_[0], y = +_[1];\n      lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point;\n      alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;\n      hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;\n      return albersUsa;\n    };\n    return albersUsa.scale(1070);\n  };\n  var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = {\n    point: d3_noop,\n    lineStart: d3_noop,\n    lineEnd: d3_noop,\n    polygonStart: function() {\n      d3_geo_pathAreaPolygon = 0;\n      d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;\n    },\n    polygonEnd: function() {\n      d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;\n      d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2);\n    }\n  };\n  function d3_geo_pathAreaRingStart() {\n    var x00, y00, x0, y0;\n    d3_geo_pathArea.point = function(x, y) {\n      d3_geo_pathArea.point = nextPoint;\n      x00 = x0 = x, y00 = y0 = y;\n    };\n    function nextPoint(x, y) {\n      d3_geo_pathAreaPolygon += y0 * x - x0 * y;\n      x0 = x, y0 = y;\n    }\n    d3_geo_pathArea.lineEnd = function() {\n      nextPoint(x00, y00);\n    };\n  }\n  var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1;\n  var d3_geo_pathBounds = {\n    point: d3_geo_pathBoundsPoint,\n    lineStart: d3_noop,\n    lineEnd: d3_noop,\n    polygonStart: d3_noop,\n    polygonEnd: d3_noop\n  };\n  function d3_geo_pathBoundsPoint(x, y) {\n    if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x;\n    if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x;\n    if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y;\n    if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y;\n  }\n  function d3_geo_pathBuffer() {\n    var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = [];\n    var stream = {\n      point: point,\n      lineStart: function() {\n        stream.point = pointLineStart;\n      },\n      lineEnd: lineEnd,\n      polygonStart: function() {\n        stream.lineEnd = lineEndPolygon;\n      },\n      polygonEnd: function() {\n        stream.lineEnd = lineEnd;\n        stream.point = point;\n      },\n      pointRadius: function(_) {\n        pointCircle = d3_geo_pathBufferCircle(_);\n        return stream;\n      },\n      result: function() {\n        if (buffer.length) {\n          var result = buffer.join(\"\");\n          buffer = [];\n          return result;\n        }\n      }\n    };\n    function point(x, y) {\n      buffer.push(\"M\", x, \",\", y, pointCircle);\n    }\n    function pointLineStart(x, y) {\n      buffer.push(\"M\", x, \",\", y);\n      stream.point = pointLine;\n    }\n    function pointLine(x, y) {\n      buffer.push(\"L\", x, \",\", y);\n    }\n    function lineEnd() {\n      stream.point = point;\n    }\n    function lineEndPolygon() {\n      buffer.push(\"Z\");\n    }\n    return stream;\n  }\n  function d3_geo_pathBufferCircle(radius) {\n    return \"m0,\" + radius + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + -2 * radius + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + 2 * radius + \"z\";\n  }\n  var d3_geo_pathCentroid = {\n    point: d3_geo_pathCentroidPoint,\n    lineStart: d3_geo_pathCentroidLineStart,\n    lineEnd: d3_geo_pathCentroidLineEnd,\n    polygonStart: function() {\n      d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;\n    },\n    polygonEnd: function() {\n      d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;\n      d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;\n      d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;\n    }\n  };\n  function d3_geo_pathCentroidPoint(x, y) {\n    d3_geo_centroidX0 += x;\n    d3_geo_centroidY0 += y;\n    ++d3_geo_centroidZ0;\n  }\n  function d3_geo_pathCentroidLineStart() {\n    var x0, y0;\n    d3_geo_pathCentroid.point = function(x, y) {\n      d3_geo_pathCentroid.point = nextPoint;\n      d3_geo_pathCentroidPoint(x0 = x, y0 = y);\n    };\n    function nextPoint(x, y) {\n      var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);\n      d3_geo_centroidX1 += z * (x0 + x) / 2;\n      d3_geo_centroidY1 += z * (y0 + y) / 2;\n      d3_geo_centroidZ1 += z;\n      d3_geo_pathCentroidPoint(x0 = x, y0 = y);\n    }\n  }\n  function d3_geo_pathCentroidLineEnd() {\n    d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;\n  }\n  function d3_geo_pathCentroidRingStart() {\n    var x00, y00, x0, y0;\n    d3_geo_pathCentroid.point = function(x, y) {\n      d3_geo_pathCentroid.point = nextPoint;\n      d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y);\n    };\n    function nextPoint(x, y) {\n      var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);\n      d3_geo_centroidX1 += z * (x0 + x) / 2;\n      d3_geo_centroidY1 += z * (y0 + y) / 2;\n      d3_geo_centroidZ1 += z;\n      z = y0 * x - x0 * y;\n      d3_geo_centroidX2 += z * (x0 + x);\n      d3_geo_centroidY2 += z * (y0 + y);\n      d3_geo_centroidZ2 += z * 3;\n      d3_geo_pathCentroidPoint(x0 = x, y0 = y);\n    }\n    d3_geo_pathCentroid.lineEnd = function() {\n      nextPoint(x00, y00);\n    };\n  }\n  function d3_geo_pathContext(context) {\n    var pointRadius = 4.5;\n    var stream = {\n      point: point,\n      lineStart: function() {\n        stream.point = pointLineStart;\n      },\n      lineEnd: lineEnd,\n      polygonStart: function() {\n        stream.lineEnd = lineEndPolygon;\n      },\n      polygonEnd: function() {\n        stream.lineEnd = lineEnd;\n        stream.point = point;\n      },\n      pointRadius: function(_) {\n        pointRadius = _;\n        return stream;\n      },\n      result: d3_noop\n    };\n    function point(x, y) {\n      context.moveTo(x + pointRadius, y);\n      context.arc(x, y, pointRadius, 0, τ);\n    }\n    function pointLineStart(x, y) {\n      context.moveTo(x, y);\n      stream.point = pointLine;\n    }\n    function pointLine(x, y) {\n      context.lineTo(x, y);\n    }\n    function lineEnd() {\n      stream.point = point;\n    }\n    function lineEndPolygon() {\n      context.closePath();\n    }\n    return stream;\n  }\n  function d3_geo_resample(project) {\n    var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16;\n    function resample(stream) {\n      return (maxDepth ? resampleRecursive : resampleNone)(stream);\n    }\n    function resampleNone(stream) {\n      return d3_geo_transformPoint(stream, function(x, y) {\n        x = project(x, y);\n        stream.point(x[0], x[1]);\n      });\n    }\n    function resampleRecursive(stream) {\n      var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0;\n      var resample = {\n        point: point,\n        lineStart: lineStart,\n        lineEnd: lineEnd,\n        polygonStart: function() {\n          stream.polygonStart();\n          resample.lineStart = ringStart;\n        },\n        polygonEnd: function() {\n          stream.polygonEnd();\n          resample.lineStart = lineStart;\n        }\n      };\n      function point(x, y) {\n        x = project(x, y);\n        stream.point(x[0], x[1]);\n      }\n      function lineStart() {\n        x0 = NaN;\n        resample.point = linePoint;\n        stream.lineStart();\n      }\n      function linePoint(λ, φ) {\n        var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);\n        resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);\n        stream.point(x0, y0);\n      }\n      function lineEnd() {\n        resample.point = point;\n        stream.lineEnd();\n      }\n      function ringStart() {\n        lineStart();\n        resample.point = ringPoint;\n        resample.lineEnd = ringEnd;\n      }\n      function ringPoint(λ, φ) {\n        linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;\n        resample.point = linePoint;\n      }\n      function ringEnd() {\n        resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);\n        resample.lineEnd = lineEnd;\n        lineEnd();\n      }\n      return resample;\n    }\n    function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {\n      var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy;\n      if (d2 > 4 * δ2 && depth--) {\n        var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;\n        if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) {\n          resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);\n          stream.point(x2, y2);\n          resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);\n        }\n      }\n    }\n    resample.precision = function(_) {\n      if (!arguments.length) return Math.sqrt(δ2);\n      maxDepth = (δ2 = _ * _) > 0 && 16;\n      return resample;\n    };\n    return resample;\n  }\n  d3.geo.path = function() {\n    var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream;\n    function path(object) {\n      if (object) {\n        if (typeof pointRadius === \"function\") contextStream.pointRadius(+pointRadius.apply(this, arguments));\n        if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream);\n        d3.geo.stream(object, cacheStream);\n      }\n      return contextStream.result();\n    }\n    path.area = function(object) {\n      d3_geo_pathAreaSum = 0;\n      d3.geo.stream(object, projectStream(d3_geo_pathArea));\n      return d3_geo_pathAreaSum;\n    };\n    path.centroid = function(object) {\n      d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;\n      d3.geo.stream(object, projectStream(d3_geo_pathCentroid));\n      return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ];\n    };\n    path.bounds = function(object) {\n      d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity);\n      d3.geo.stream(object, projectStream(d3_geo_pathBounds));\n      return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ];\n    };\n    path.projection = function(_) {\n      if (!arguments.length) return projection;\n      projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity;\n      return reset();\n    };\n    path.context = function(_) {\n      if (!arguments.length) return context;\n      contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_);\n      if (typeof pointRadius !== \"function\") contextStream.pointRadius(pointRadius);\n      return reset();\n    };\n    path.pointRadius = function(_) {\n      if (!arguments.length) return pointRadius;\n      pointRadius = typeof _ === \"function\" ? _ : (contextStream.pointRadius(+_), +_);\n      return path;\n    };\n    function reset() {\n      cacheStream = null;\n      return path;\n    }\n    return path.projection(d3.geo.albersUsa()).context(null);\n  };\n  function d3_geo_pathProjectStream(project) {\n    var resample = d3_geo_resample(function(x, y) {\n      return project([ x * d3_degrees, y * d3_degrees ]);\n    });\n    return function(stream) {\n      return d3_geo_projectionRadians(resample(stream));\n    };\n  }\n  d3.geo.transform = function(methods) {\n    return {\n      stream: function(stream) {\n        var transform = new d3_geo_transform(stream);\n        for (var k in methods) transform[k] = methods[k];\n        return transform;\n      }\n    };\n  };\n  function d3_geo_transform(stream) {\n    this.stream = stream;\n  }\n  d3_geo_transform.prototype = {\n    point: function(x, y) {\n      this.stream.point(x, y);\n    },\n    sphere: function() {\n      this.stream.sphere();\n    },\n    lineStart: function() {\n      this.stream.lineStart();\n    },\n    lineEnd: function() {\n      this.stream.lineEnd();\n    },\n    polygonStart: function() {\n      this.stream.polygonStart();\n    },\n    polygonEnd: function() {\n      this.stream.polygonEnd();\n    }\n  };\n  function d3_geo_transformPoint(stream, point) {\n    return {\n      point: point,\n      sphere: function() {\n        stream.sphere();\n      },\n      lineStart: function() {\n        stream.lineStart();\n      },\n      lineEnd: function() {\n        stream.lineEnd();\n      },\n      polygonStart: function() {\n        stream.polygonStart();\n      },\n      polygonEnd: function() {\n        stream.polygonEnd();\n      }\n    };\n  }\n  d3.geo.projection = d3_geo_projection;\n  d3.geo.projectionMutator = d3_geo_projectionMutator;\n  function d3_geo_projection(project) {\n    return d3_geo_projectionMutator(function() {\n      return project;\n    })();\n  }\n  function d3_geo_projectionMutator(projectAt) {\n    var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) {\n      x = project(x, y);\n      return [ x[0] * k + δx, δy - x[1] * k ];\n    }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream;\n    function projection(point) {\n      point = projectRotate(point[0] * d3_radians, point[1] * d3_radians);\n      return [ point[0] * k + δx, δy - point[1] * k ];\n    }\n    function invert(point) {\n      point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k);\n      return point && [ point[0] * d3_degrees, point[1] * d3_degrees ];\n    }\n    projection.stream = function(output) {\n      if (stream) stream.valid = false;\n      stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output))));\n      stream.valid = true;\n      return stream;\n    };\n    projection.clipAngle = function(_) {\n      if (!arguments.length) return clipAngle;\n      preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians);\n      return invalidate();\n    };\n    projection.clipExtent = function(_) {\n      if (!arguments.length) return clipExtent;\n      clipExtent = _;\n      postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity;\n      return invalidate();\n    };\n    projection.scale = function(_) {\n      if (!arguments.length) return k;\n      k = +_;\n      return reset();\n    };\n    projection.translate = function(_) {\n      if (!arguments.length) return [ x, y ];\n      x = +_[0];\n      y = +_[1];\n      return reset();\n    };\n    projection.center = function(_) {\n      if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ];\n      λ = _[0] % 360 * d3_radians;\n      φ = _[1] % 360 * d3_radians;\n      return reset();\n    };\n    projection.rotate = function(_) {\n      if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ];\n      δλ = _[0] % 360 * d3_radians;\n      δφ = _[1] % 360 * d3_radians;\n      δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0;\n      return reset();\n    };\n    d3.rebind(projection, projectResample, \"precision\");\n    function reset() {\n      projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project);\n      var center = project(λ, φ);\n      δx = x - center[0] * k;\n      δy = y + center[1] * k;\n      return invalidate();\n    }\n    function invalidate() {\n      if (stream) stream.valid = false, stream = null;\n      return projection;\n    }\n    return function() {\n      project = projectAt.apply(this, arguments);\n      projection.invert = project.invert && invert;\n      return reset();\n    };\n  }\n  function d3_geo_projectionRadians(stream) {\n    return d3_geo_transformPoint(stream, function(x, y) {\n      stream.point(x * d3_radians, y * d3_radians);\n    });\n  }\n  function d3_geo_equirectangular(λ, φ) {\n    return [ λ, φ ];\n  }\n  (d3.geo.equirectangular = function() {\n    return d3_geo_projection(d3_geo_equirectangular);\n  }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular;\n  d3.geo.rotation = function(rotate) {\n    rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0);\n    function forward(coordinates) {\n      coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians);\n      return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;\n    }\n    forward.invert = function(coordinates) {\n      coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians);\n      return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;\n    };\n    return forward;\n  };\n  function d3_geo_identityRotation(λ, φ) {\n    return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];\n  }\n  d3_geo_identityRotation.invert = d3_geo_equirectangular;\n  function d3_geo_rotation(δλ, δφ, δγ) {\n    return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation;\n  }\n  function d3_geo_forwardRotationλ(δλ) {\n    return function(λ, φ) {\n      return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];\n    };\n  }\n  function d3_geo_rotationλ(δλ) {\n    var rotation = d3_geo_forwardRotationλ(δλ);\n    rotation.invert = d3_geo_forwardRotationλ(-δλ);\n    return rotation;\n  }\n  function d3_geo_rotationφγ(δφ, δγ) {\n    var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ);\n    function rotation(λ, φ) {\n      var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ;\n      return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ];\n    }\n    rotation.invert = function(λ, φ) {\n      var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ;\n      return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ];\n    };\n    return rotation;\n  }\n  d3.geo.circle = function() {\n    var origin = [ 0, 0 ], angle, precision = 6, interpolate;\n    function circle() {\n      var center = typeof origin === \"function\" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = [];\n      interpolate(null, null, 1, {\n        point: function(x, y) {\n          ring.push(x = rotate(x, y));\n          x[0] *= d3_degrees, x[1] *= d3_degrees;\n        }\n      });\n      return {\n        type: \"Polygon\",\n        coordinates: [ ring ]\n      };\n    }\n    circle.origin = function(x) {\n      if (!arguments.length) return origin;\n      origin = x;\n      return circle;\n    };\n    circle.angle = function(x) {\n      if (!arguments.length) return angle;\n      interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians);\n      return circle;\n    };\n    circle.precision = function(_) {\n      if (!arguments.length) return precision;\n      interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians);\n      return circle;\n    };\n    return circle.angle(90);\n  };\n  function d3_geo_circleInterpolate(radius, precision) {\n    var cr = Math.cos(radius), sr = Math.sin(radius);\n    return function(from, to, direction, listener) {\n      var step = direction * precision;\n      if (from != null) {\n        from = d3_geo_circleAngle(cr, from);\n        to = d3_geo_circleAngle(cr, to);\n        if (direction > 0 ? from < to : from > to) from += direction * τ;\n      } else {\n        from = radius + direction * τ;\n        to = radius - .5 * step;\n      }\n      for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) {\n        listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]);\n      }\n    };\n  }\n  function d3_geo_circleAngle(cr, point) {\n    var a = d3_geo_cartesian(point);\n    a[0] -= cr;\n    d3_geo_cartesianNormalize(a);\n    var angle = d3_acos(-a[1]);\n    return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI);\n  }\n  d3.geo.distance = function(a, b) {\n    var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t;\n    return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ);\n  };\n  d3.geo.graticule = function() {\n    var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5;\n    function graticule() {\n      return {\n        type: \"MultiLineString\",\n        coordinates: lines()\n      };\n    }\n    function lines() {\n      return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) {\n        return abs(x % DX) > ε;\n      }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) {\n        return abs(y % DY) > ε;\n      }).map(y));\n    }\n    graticule.lines = function() {\n      return lines().map(function(coordinates) {\n        return {\n          type: \"LineString\",\n          coordinates: coordinates\n        };\n      });\n    };\n    graticule.outline = function() {\n      return {\n        type: \"Polygon\",\n        coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ]\n      };\n    };\n    graticule.extent = function(_) {\n      if (!arguments.length) return graticule.minorExtent();\n      return graticule.majorExtent(_).minorExtent(_);\n    };\n    graticule.majorExtent = function(_) {\n      if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ];\n      X0 = +_[0][0], X1 = +_[1][0];\n      Y0 = +_[0][1], Y1 = +_[1][1];\n      if (X0 > X1) _ = X0, X0 = X1, X1 = _;\n      if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;\n      return graticule.precision(precision);\n    };\n    graticule.minorExtent = function(_) {\n      if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];\n      x0 = +_[0][0], x1 = +_[1][0];\n      y0 = +_[0][1], y1 = +_[1][1];\n      if (x0 > x1) _ = x0, x0 = x1, x1 = _;\n      if (y0 > y1) _ = y0, y0 = y1, y1 = _;\n      return graticule.precision(precision);\n    };\n    graticule.step = function(_) {\n      if (!arguments.length) return graticule.minorStep();\n      return graticule.majorStep(_).minorStep(_);\n    };\n    graticule.majorStep = function(_) {\n      if (!arguments.length) return [ DX, DY ];\n      DX = +_[0], DY = +_[1];\n      return graticule;\n    };\n    graticule.minorStep = function(_) {\n      if (!arguments.length) return [ dx, dy ];\n      dx = +_[0], dy = +_[1];\n      return graticule;\n    };\n    graticule.precision = function(_) {\n      if (!arguments.length) return precision;\n      precision = +_;\n      x = d3_geo_graticuleX(y0, y1, 90);\n      y = d3_geo_graticuleY(x0, x1, precision);\n      X = d3_geo_graticuleX(Y0, Y1, 90);\n      Y = d3_geo_graticuleY(X0, X1, precision);\n      return graticule;\n    };\n    return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]);\n  };\n  function d3_geo_graticuleX(y0, y1, dy) {\n    var y = d3.range(y0, y1 - ε, dy).concat(y1);\n    return function(x) {\n      return y.map(function(y) {\n        return [ x, y ];\n      });\n    };\n  }\n  function d3_geo_graticuleY(x0, x1, dx) {\n    var x = d3.range(x0, x1 - ε, dx).concat(x1);\n    return function(y) {\n      return x.map(function(x) {\n        return [ x, y ];\n      });\n    };\n  }\n  function d3_source(d) {\n    return d.source;\n  }\n  function d3_target(d) {\n    return d.target;\n  }\n  d3.geo.greatArc = function() {\n    var source = d3_source, source_, target = d3_target, target_;\n    function greatArc() {\n      return {\n        type: \"LineString\",\n        coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ]\n      };\n    }\n    greatArc.distance = function() {\n      return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments));\n    };\n    greatArc.source = function(_) {\n      if (!arguments.length) return source;\n      source = _, source_ = typeof _ === \"function\" ? null : _;\n      return greatArc;\n    };\n    greatArc.target = function(_) {\n      if (!arguments.length) return target;\n      target = _, target_ = typeof _ === \"function\" ? null : _;\n      return greatArc;\n    };\n    greatArc.precision = function() {\n      return arguments.length ? greatArc : 0;\n    };\n    return greatArc;\n  };\n  d3.geo.interpolate = function(source, target) {\n    return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians);\n  };\n  function d3_geo_interpolate(x0, y0, x1, y1) {\n    var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d);\n    var interpolate = d ? function(t) {\n      var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;\n      return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ];\n    } : function() {\n      return [ x0 * d3_degrees, y0 * d3_degrees ];\n    };\n    interpolate.distance = d;\n    return interpolate;\n  }\n  d3.geo.length = function(object) {\n    d3_geo_lengthSum = 0;\n    d3.geo.stream(object, d3_geo_length);\n    return d3_geo_lengthSum;\n  };\n  var d3_geo_lengthSum;\n  var d3_geo_length = {\n    sphere: d3_noop,\n    point: d3_noop,\n    lineStart: d3_geo_lengthLineStart,\n    lineEnd: d3_noop,\n    polygonStart: d3_noop,\n    polygonEnd: d3_noop\n  };\n  function d3_geo_lengthLineStart() {\n    var λ0, sinφ0, cosφ0;\n    d3_geo_length.point = function(λ, φ) {\n      λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ);\n      d3_geo_length.point = nextPoint;\n    };\n    d3_geo_length.lineEnd = function() {\n      d3_geo_length.point = d3_geo_length.lineEnd = d3_noop;\n    };\n    function nextPoint(λ, φ) {\n      var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t);\n      d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ);\n      λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;\n    }\n  }\n  function d3_geo_azimuthal(scale, angle) {\n    function azimuthal(λ, φ) {\n      var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ);\n      return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ];\n    }\n    azimuthal.invert = function(x, y) {\n      var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c);\n      return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ];\n    };\n    return azimuthal;\n  }\n  var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) {\n    return Math.sqrt(2 / (1 + cosλcosφ));\n  }, function(ρ) {\n    return 2 * Math.asin(ρ / 2);\n  });\n  (d3.geo.azimuthalEqualArea = function() {\n    return d3_geo_projection(d3_geo_azimuthalEqualArea);\n  }).raw = d3_geo_azimuthalEqualArea;\n  var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) {\n    var c = Math.acos(cosλcosφ);\n    return c && c / Math.sin(c);\n  }, d3_identity);\n  (d3.geo.azimuthalEquidistant = function() {\n    return d3_geo_projection(d3_geo_azimuthalEquidistant);\n  }).raw = d3_geo_azimuthalEquidistant;\n  function d3_geo_conicConformal(φ0, φ1) {\n    var cosφ0 = Math.cos(φ0), t = function(φ) {\n      return Math.tan(π / 4 + φ / 2);\n    }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n;\n    if (!n) return d3_geo_mercator;\n    function forward(λ, φ) {\n      if (F > 0) {\n        if (φ < -halfπ + ε) φ = -halfπ + ε;\n      } else {\n        if (φ > halfπ - ε) φ = halfπ - ε;\n      }\n      var ρ = F / Math.pow(t(φ), n);\n      return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ];\n    }\n    forward.invert = function(x, y) {\n      var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y);\n      return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ];\n    };\n    return forward;\n  }\n  (d3.geo.conicConformal = function() {\n    return d3_geo_conic(d3_geo_conicConformal);\n  }).raw = d3_geo_conicConformal;\n  function d3_geo_conicEquidistant(φ0, φ1) {\n    var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0;\n    if (abs(n) < ε) return d3_geo_equirectangular;\n    function forward(λ, φ) {\n      var ρ = G - φ;\n      return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ];\n    }\n    forward.invert = function(x, y) {\n      var ρ0_y = G - y;\n      return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ];\n    };\n    return forward;\n  }\n  (d3.geo.conicEquidistant = function() {\n    return d3_geo_conic(d3_geo_conicEquidistant);\n  }).raw = d3_geo_conicEquidistant;\n  var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) {\n    return 1 / cosλcosφ;\n  }, Math.atan);\n  (d3.geo.gnomonic = function() {\n    return d3_geo_projection(d3_geo_gnomonic);\n  }).raw = d3_geo_gnomonic;\n  function d3_geo_mercator(λ, φ) {\n    return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ];\n  }\n  d3_geo_mercator.invert = function(x, y) {\n    return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ];\n  };\n  function d3_geo_mercatorProjection(project) {\n    var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto;\n    m.scale = function() {\n      var v = scale.apply(m, arguments);\n      return v === m ? clipAuto ? m.clipExtent(null) : m : v;\n    };\n    m.translate = function() {\n      var v = translate.apply(m, arguments);\n      return v === m ? clipAuto ? m.clipExtent(null) : m : v;\n    };\n    m.clipExtent = function(_) {\n      var v = clipExtent.apply(m, arguments);\n      if (v === m) {\n        if (clipAuto = _ == null) {\n          var k = π * scale(), t = translate();\n          clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]);\n        }\n      } else if (clipAuto) {\n        v = null;\n      }\n      return v;\n    };\n    return m.clipExtent(null);\n  }\n  (d3.geo.mercator = function() {\n    return d3_geo_mercatorProjection(d3_geo_mercator);\n  }).raw = d3_geo_mercator;\n  var d3_geo_orthographic = d3_geo_azimuthal(function() {\n    return 1;\n  }, Math.asin);\n  (d3.geo.orthographic = function() {\n    return d3_geo_projection(d3_geo_orthographic);\n  }).raw = d3_geo_orthographic;\n  var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) {\n    return 1 / (1 + cosλcosφ);\n  }, function(ρ) {\n    return 2 * Math.atan(ρ);\n  });\n  (d3.geo.stereographic = function() {\n    return d3_geo_projection(d3_geo_stereographic);\n  }).raw = d3_geo_stereographic;\n  function d3_geo_transverseMercator(λ, φ) {\n    return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ];\n  }\n  d3_geo_transverseMercator.invert = function(x, y) {\n    return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ];\n  };\n  (d3.geo.transverseMercator = function() {\n    var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate;\n    projection.center = function(_) {\n      return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]);\n    };\n    projection.rotate = function(_) {\n      return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), \n      [ _[0], _[1], _[2] - 90 ]);\n    };\n    return rotate([ 0, 0, 90 ]);\n  }).raw = d3_geo_transverseMercator;\n  d3.geom = {};\n  function d3_geom_pointX(d) {\n    return d[0];\n  }\n  function d3_geom_pointY(d) {\n    return d[1];\n  }\n  d3.geom.hull = function(vertices) {\n    var x = d3_geom_pointX, y = d3_geom_pointY;\n    if (arguments.length) return hull(vertices);\n    function hull(data) {\n      if (data.length < 3) return [];\n      var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = [];\n      for (i = 0; i < n; i++) {\n        points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]);\n      }\n      points.sort(d3_geom_hullOrder);\n      for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]);\n      var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints);\n      var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = [];\n      for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]);\n      for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]);\n      return polygon;\n    }\n    hull.x = function(_) {\n      return arguments.length ? (x = _, hull) : x;\n    };\n    hull.y = function(_) {\n      return arguments.length ? (y = _, hull) : y;\n    };\n    return hull;\n  };\n  function d3_geom_hullUpper(points) {\n    var n = points.length, hull = [ 0, 1 ], hs = 2;\n    for (var i = 2; i < n; i++) {\n      while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs;\n      hull[hs++] = i;\n    }\n    return hull.slice(0, hs);\n  }\n  function d3_geom_hullOrder(a, b) {\n    return a[0] - b[0] || a[1] - b[1];\n  }\n  d3.geom.polygon = function(coordinates) {\n    d3_subclass(coordinates, d3_geom_polygonPrototype);\n    return coordinates;\n  };\n  var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];\n  d3_geom_polygonPrototype.area = function() {\n    var i = -1, n = this.length, a, b = this[n - 1], area = 0;\n    while (++i < n) {\n      a = b;\n      b = this[i];\n      area += a[1] * b[0] - a[0] * b[1];\n    }\n    return area * .5;\n  };\n  d3_geom_polygonPrototype.centroid = function(k) {\n    var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c;\n    if (!arguments.length) k = -1 / (6 * this.area());\n    while (++i < n) {\n      a = b;\n      b = this[i];\n      c = a[0] * b[1] - b[0] * a[1];\n      x += (a[0] + b[0]) * c;\n      y += (a[1] + b[1]) * c;\n    }\n    return [ x * k, y * k ];\n  };\n  d3_geom_polygonPrototype.clip = function(subject) {\n    var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d;\n    while (++i < n) {\n      input = subject.slice();\n      subject.length = 0;\n      b = this[i];\n      c = input[(m = input.length - closed) - 1];\n      j = -1;\n      while (++j < m) {\n        d = input[j];\n        if (d3_geom_polygonInside(d, a, b)) {\n          if (!d3_geom_polygonInside(c, a, b)) {\n            subject.push(d3_geom_polygonIntersect(c, d, a, b));\n          }\n          subject.push(d);\n        } else if (d3_geom_polygonInside(c, a, b)) {\n          subject.push(d3_geom_polygonIntersect(c, d, a, b));\n        }\n        c = d;\n      }\n      if (closed) subject.push(subject[0]);\n      a = b;\n    }\n    return subject;\n  };\n  function d3_geom_polygonInside(p, a, b) {\n    return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);\n  }\n  function d3_geom_polygonIntersect(c, d, a, b) {\n    var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);\n    return [ x1 + ua * x21, y1 + ua * y21 ];\n  }\n  function d3_geom_polygonClosed(coordinates) {\n    var a = coordinates[0], b = coordinates[coordinates.length - 1];\n    return !(a[0] - b[0] || a[1] - b[1]);\n  }\n  var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = [];\n  function d3_geom_voronoiBeach() {\n    d3_geom_voronoiRedBlackNode(this);\n    this.edge = this.site = this.circle = null;\n  }\n  function d3_geom_voronoiCreateBeach(site) {\n    var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach();\n    beach.site = site;\n    return beach;\n  }\n  function d3_geom_voronoiDetachBeach(beach) {\n    d3_geom_voronoiDetachCircle(beach);\n    d3_geom_voronoiBeaches.remove(beach);\n    d3_geom_voronoiBeachPool.push(beach);\n    d3_geom_voronoiRedBlackNode(beach);\n  }\n  function d3_geom_voronoiRemoveBeach(beach) {\n    var circle = beach.circle, x = circle.x, y = circle.cy, vertex = {\n      x: x,\n      y: y\n    }, previous = beach.P, next = beach.N, disappearing = [ beach ];\n    d3_geom_voronoiDetachBeach(beach);\n    var lArc = previous;\n    while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) {\n      previous = lArc.P;\n      disappearing.unshift(lArc);\n      d3_geom_voronoiDetachBeach(lArc);\n      lArc = previous;\n    }\n    disappearing.unshift(lArc);\n    d3_geom_voronoiDetachCircle(lArc);\n    var rArc = next;\n    while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) {\n      next = rArc.N;\n      disappearing.push(rArc);\n      d3_geom_voronoiDetachBeach(rArc);\n      rArc = next;\n    }\n    disappearing.push(rArc);\n    d3_geom_voronoiDetachCircle(rArc);\n    var nArcs = disappearing.length, iArc;\n    for (iArc = 1; iArc < nArcs; ++iArc) {\n      rArc = disappearing[iArc];\n      lArc = disappearing[iArc - 1];\n      d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);\n    }\n    lArc = disappearing[0];\n    rArc = disappearing[nArcs - 1];\n    rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex);\n    d3_geom_voronoiAttachCircle(lArc);\n    d3_geom_voronoiAttachCircle(rArc);\n  }\n  function d3_geom_voronoiAddBeach(site) {\n    var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._;\n    while (node) {\n      dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x;\n      if (dxl > ε) node = node.L; else {\n        dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix);\n        if (dxr > ε) {\n          if (!node.R) {\n            lArc = node;\n            break;\n          }\n          node = node.R;\n        } else {\n          if (dxl > -ε) {\n            lArc = node.P;\n            rArc = node;\n          } else if (dxr > -ε) {\n            lArc = node;\n            rArc = node.N;\n          } else {\n            lArc = rArc = node;\n          }\n          break;\n        }\n      }\n    }\n    var newArc = d3_geom_voronoiCreateBeach(site);\n    d3_geom_voronoiBeaches.insert(lArc, newArc);\n    if (!lArc && !rArc) return;\n    if (lArc === rArc) {\n      d3_geom_voronoiDetachCircle(lArc);\n      rArc = d3_geom_voronoiCreateBeach(lArc.site);\n      d3_geom_voronoiBeaches.insert(newArc, rArc);\n      newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);\n      d3_geom_voronoiAttachCircle(lArc);\n      d3_geom_voronoiAttachCircle(rArc);\n      return;\n    }\n    if (!rArc) {\n      newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);\n      return;\n    }\n    d3_geom_voronoiDetachCircle(lArc);\n    d3_geom_voronoiDetachCircle(rArc);\n    var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = {\n      x: (cy * hb - by * hc) / d + ax,\n      y: (bx * hc - cx * hb) / d + ay\n    };\n    d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex);\n    newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex);\n    rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex);\n    d3_geom_voronoiAttachCircle(lArc);\n    d3_geom_voronoiAttachCircle(rArc);\n  }\n  function d3_geom_voronoiLeftBreakPoint(arc, directrix) {\n    var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix;\n    if (!pby2) return rfocx;\n    var lArc = arc.P;\n    if (!lArc) return -Infinity;\n    site = lArc.site;\n    var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix;\n    if (!plby2) return lfocx;\n    var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2;\n    if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;\n    return (rfocx + lfocx) / 2;\n  }\n  function d3_geom_voronoiRightBreakPoint(arc, directrix) {\n    var rArc = arc.N;\n    if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix);\n    var site = arc.site;\n    return site.y === directrix ? site.x : Infinity;\n  }\n  function d3_geom_voronoiCell(site) {\n    this.site = site;\n    this.edges = [];\n  }\n  d3_geom_voronoiCell.prototype.prepare = function() {\n    var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge;\n    while (iHalfEdge--) {\n      edge = halfEdges[iHalfEdge].edge;\n      if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1);\n    }\n    halfEdges.sort(d3_geom_voronoiHalfEdgeOrder);\n    return halfEdges.length;\n  };\n  function d3_geom_voronoiCloseCells(extent) {\n    var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end;\n    while (iCell--) {\n      cell = cells[iCell];\n      if (!cell || !cell.prepare()) continue;\n      halfEdges = cell.edges;\n      nHalfEdges = halfEdges.length;\n      iHalfEdge = 0;\n      while (iHalfEdge < nHalfEdges) {\n        end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y;\n        start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y;\n        if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) {\n          halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? {\n            x: x0,\n            y: abs(x2 - x0) < ε ? y2 : y1\n          } : abs(y3 - y1) < ε && x1 - x3 > ε ? {\n            x: abs(y2 - y1) < ε ? x2 : x1,\n            y: y1\n          } : abs(x3 - x1) < ε && y3 - y0 > ε ? {\n            x: x1,\n            y: abs(x2 - x1) < ε ? y2 : y0\n          } : abs(y3 - y0) < ε && x3 - x0 > ε ? {\n            x: abs(y2 - y0) < ε ? x2 : x0,\n            y: y0\n          } : null), cell.site, null));\n          ++nHalfEdges;\n        }\n      }\n    }\n  }\n  function d3_geom_voronoiHalfEdgeOrder(a, b) {\n    return b.angle - a.angle;\n  }\n  function d3_geom_voronoiCircle() {\n    d3_geom_voronoiRedBlackNode(this);\n    this.x = this.y = this.arc = this.site = this.cy = null;\n  }\n  function d3_geom_voronoiAttachCircle(arc) {\n    var lArc = arc.P, rArc = arc.N;\n    if (!lArc || !rArc) return;\n    var lSite = lArc.site, cSite = arc.site, rSite = rArc.site;\n    if (lSite === rSite) return;\n    var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by;\n    var d = 2 * (ax * cy - ay * cx);\n    if (d >= -ε2) return;\n    var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by;\n    var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle();\n    circle.arc = arc;\n    circle.site = cSite;\n    circle.x = x + bx;\n    circle.y = cy + Math.sqrt(x * x + y * y);\n    circle.cy = cy;\n    arc.circle = circle;\n    var before = null, node = d3_geom_voronoiCircles._;\n    while (node) {\n      if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) {\n        if (node.L) node = node.L; else {\n          before = node.P;\n          break;\n        }\n      } else {\n        if (node.R) node = node.R; else {\n          before = node;\n          break;\n        }\n      }\n    }\n    d3_geom_voronoiCircles.insert(before, circle);\n    if (!before) d3_geom_voronoiFirstCircle = circle;\n  }\n  function d3_geom_voronoiDetachCircle(arc) {\n    var circle = arc.circle;\n    if (circle) {\n      if (!circle.P) d3_geom_voronoiFirstCircle = circle.N;\n      d3_geom_voronoiCircles.remove(circle);\n      d3_geom_voronoiCirclePool.push(circle);\n      d3_geom_voronoiRedBlackNode(circle);\n      arc.circle = null;\n    }\n  }\n  function d3_geom_voronoiClipEdges(extent) {\n    var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e;\n    while (i--) {\n      e = edges[i];\n      if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) {\n        e.a = e.b = null;\n        edges.splice(i, 1);\n      }\n    }\n  }\n  function d3_geom_voronoiConnectEdge(edge, extent) {\n    var vb = edge.b;\n    if (vb) return true;\n    var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb;\n    if (ry === ly) {\n      if (fx < x0 || fx >= x1) return;\n      if (lx > rx) {\n        if (!va) va = {\n          x: fx,\n          y: y0\n        }; else if (va.y >= y1) return;\n        vb = {\n          x: fx,\n          y: y1\n        };\n      } else {\n        if (!va) va = {\n          x: fx,\n          y: y1\n        }; else if (va.y < y0) return;\n        vb = {\n          x: fx,\n          y: y0\n        };\n      }\n    } else {\n      fm = (lx - rx) / (ry - ly);\n      fb = fy - fm * fx;\n      if (fm < -1 || fm > 1) {\n        if (lx > rx) {\n          if (!va) va = {\n            x: (y0 - fb) / fm,\n            y: y0\n          }; else if (va.y >= y1) return;\n          vb = {\n            x: (y1 - fb) / fm,\n            y: y1\n          };\n        } else {\n          if (!va) va = {\n            x: (y1 - fb) / fm,\n            y: y1\n          }; else if (va.y < y0) return;\n          vb = {\n            x: (y0 - fb) / fm,\n            y: y0\n          };\n        }\n      } else {\n        if (ly < ry) {\n          if (!va) va = {\n            x: x0,\n            y: fm * x0 + fb\n          }; else if (va.x >= x1) return;\n          vb = {\n            x: x1,\n            y: fm * x1 + fb\n          };\n        } else {\n          if (!va) va = {\n            x: x1,\n            y: fm * x1 + fb\n          }; else if (va.x < x0) return;\n          vb = {\n            x: x0,\n            y: fm * x0 + fb\n          };\n        }\n      }\n    }\n    edge.a = va;\n    edge.b = vb;\n    return true;\n  }\n  function d3_geom_voronoiEdge(lSite, rSite) {\n    this.l = lSite;\n    this.r = rSite;\n    this.a = this.b = null;\n  }\n  function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) {\n    var edge = new d3_geom_voronoiEdge(lSite, rSite);\n    d3_geom_voronoiEdges.push(edge);\n    if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va);\n    if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb);\n    d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite));\n    d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite));\n    return edge;\n  }\n  function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) {\n    var edge = new d3_geom_voronoiEdge(lSite, null);\n    edge.a = va;\n    edge.b = vb;\n    d3_geom_voronoiEdges.push(edge);\n    return edge;\n  }\n  function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) {\n    if (!edge.a && !edge.b) {\n      edge.a = vertex;\n      edge.l = lSite;\n      edge.r = rSite;\n    } else if (edge.l === rSite) {\n      edge.b = vertex;\n    } else {\n      edge.a = vertex;\n    }\n  }\n  function d3_geom_voronoiHalfEdge(edge, lSite, rSite) {\n    var va = edge.a, vb = edge.b;\n    this.edge = edge;\n    this.site = lSite;\n    this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y);\n  }\n  d3_geom_voronoiHalfEdge.prototype = {\n    start: function() {\n      return this.edge.l === this.site ? this.edge.a : this.edge.b;\n    },\n    end: function() {\n      return this.edge.l === this.site ? this.edge.b : this.edge.a;\n    }\n  };\n  function d3_geom_voronoiRedBlackTree() {\n    this._ = null;\n  }\n  function d3_geom_voronoiRedBlackNode(node) {\n    node.U = node.C = node.L = node.R = node.P = node.N = null;\n  }\n  d3_geom_voronoiRedBlackTree.prototype = {\n    insert: function(after, node) {\n      var parent, grandpa, uncle;\n      if (after) {\n        node.P = after;\n        node.N = after.N;\n        if (after.N) after.N.P = node;\n        after.N = node;\n        if (after.R) {\n          after = after.R;\n          while (after.L) after = after.L;\n          after.L = node;\n        } else {\n          after.R = node;\n        }\n        parent = after;\n      } else if (this._) {\n        after = d3_geom_voronoiRedBlackFirst(this._);\n        node.P = null;\n        node.N = after;\n        after.P = after.L = node;\n        parent = after;\n      } else {\n        node.P = node.N = null;\n        this._ = node;\n        parent = null;\n      }\n      node.L = node.R = null;\n      node.U = parent;\n      node.C = true;\n      after = node;\n      while (parent && parent.C) {\n        grandpa = parent.U;\n        if (parent === grandpa.L) {\n          uncle = grandpa.R;\n          if (uncle && uncle.C) {\n            parent.C = uncle.C = false;\n            grandpa.C = true;\n            after = grandpa;\n          } else {\n            if (after === parent.R) {\n              d3_geom_voronoiRedBlackRotateLeft(this, parent);\n              after = parent;\n              parent = after.U;\n            }\n            parent.C = false;\n            grandpa.C = true;\n            d3_geom_voronoiRedBlackRotateRight(this, grandpa);\n          }\n        } else {\n          uncle = grandpa.L;\n          if (uncle && uncle.C) {\n            parent.C = uncle.C = false;\n            grandpa.C = true;\n            after = grandpa;\n          } else {\n            if (after === parent.L) {\n              d3_geom_voronoiRedBlackRotateRight(this, parent);\n              after = parent;\n              parent = after.U;\n            }\n            parent.C = false;\n            grandpa.C = true;\n            d3_geom_voronoiRedBlackRotateLeft(this, grandpa);\n          }\n        }\n        parent = after.U;\n      }\n      this._.C = false;\n    },\n    remove: function(node) {\n      if (node.N) node.N.P = node.P;\n      if (node.P) node.P.N = node.N;\n      node.N = node.P = null;\n      var parent = node.U, sibling, left = node.L, right = node.R, next, red;\n      if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right);\n      if (parent) {\n        if (parent.L === node) parent.L = next; else parent.R = next;\n      } else {\n        this._ = next;\n      }\n      if (left && right) {\n        red = next.C;\n        next.C = node.C;\n        next.L = left;\n        left.U = next;\n        if (next !== right) {\n          parent = next.U;\n          next.U = node.U;\n          node = next.R;\n          parent.L = node;\n          next.R = right;\n          right.U = next;\n        } else {\n          next.U = parent;\n          parent = next;\n          node = next.R;\n        }\n      } else {\n        red = node.C;\n        node = next;\n      }\n      if (node) node.U = parent;\n      if (red) return;\n      if (node && node.C) {\n        node.C = false;\n        return;\n      }\n      do {\n        if (node === this._) break;\n        if (node === parent.L) {\n          sibling = parent.R;\n          if (sibling.C) {\n            sibling.C = false;\n            parent.C = true;\n            d3_geom_voronoiRedBlackRotateLeft(this, parent);\n            sibling = parent.R;\n          }\n          if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {\n            if (!sibling.R || !sibling.R.C) {\n              sibling.L.C = false;\n              sibling.C = true;\n              d3_geom_voronoiRedBlackRotateRight(this, sibling);\n              sibling = parent.R;\n            }\n            sibling.C = parent.C;\n            parent.C = sibling.R.C = false;\n            d3_geom_voronoiRedBlackRotateLeft(this, parent);\n            node = this._;\n            break;\n          }\n        } else {\n          sibling = parent.L;\n          if (sibling.C) {\n            sibling.C = false;\n            parent.C = true;\n            d3_geom_voronoiRedBlackRotateRight(this, parent);\n            sibling = parent.L;\n          }\n          if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {\n            if (!sibling.L || !sibling.L.C) {\n              sibling.R.C = false;\n              sibling.C = true;\n              d3_geom_voronoiRedBlackRotateLeft(this, sibling);\n              sibling = parent.L;\n            }\n            sibling.C = parent.C;\n            parent.C = sibling.L.C = false;\n            d3_geom_voronoiRedBlackRotateRight(this, parent);\n            node = this._;\n            break;\n          }\n        }\n        sibling.C = true;\n        node = parent;\n        parent = parent.U;\n      } while (!node.C);\n      if (node) node.C = false;\n    }\n  };\n  function d3_geom_voronoiRedBlackRotateLeft(tree, node) {\n    var p = node, q = node.R, parent = p.U;\n    if (parent) {\n      if (parent.L === p) parent.L = q; else parent.R = q;\n    } else {\n      tree._ = q;\n    }\n    q.U = parent;\n    p.U = q;\n    p.R = q.L;\n    if (p.R) p.R.U = p;\n    q.L = p;\n  }\n  function d3_geom_voronoiRedBlackRotateRight(tree, node) {\n    var p = node, q = node.L, parent = p.U;\n    if (parent) {\n      if (parent.L === p) parent.L = q; else parent.R = q;\n    } else {\n      tree._ = q;\n    }\n    q.U = parent;\n    p.U = q;\n    p.L = q.R;\n    if (p.L) p.L.U = p;\n    q.R = p;\n  }\n  function d3_geom_voronoiRedBlackFirst(node) {\n    while (node.L) node = node.L;\n    return node;\n  }\n  function d3_geom_voronoi(sites, bbox) {\n    var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle;\n    d3_geom_voronoiEdges = [];\n    d3_geom_voronoiCells = new Array(sites.length);\n    d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree();\n    d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree();\n    while (true) {\n      circle = d3_geom_voronoiFirstCircle;\n      if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) {\n        if (site.x !== x0 || site.y !== y0) {\n          d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site);\n          d3_geom_voronoiAddBeach(site);\n          x0 = site.x, y0 = site.y;\n        }\n        site = sites.pop();\n      } else if (circle) {\n        d3_geom_voronoiRemoveBeach(circle.arc);\n      } else {\n        break;\n      }\n    }\n    if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox);\n    var diagram = {\n      cells: d3_geom_voronoiCells,\n      edges: d3_geom_voronoiEdges\n    };\n    d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null;\n    return diagram;\n  }\n  function d3_geom_voronoiVertexOrder(a, b) {\n    return b.y - a.y || b.x - a.x;\n  }\n  d3.geom.voronoi = function(points) {\n    var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent;\n    if (points) return voronoi(points);\n    function voronoi(data) {\n      var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1];\n      d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) {\n        var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) {\n          var s = e.start();\n          return [ s.x, s.y ];\n        }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : [];\n        polygon.point = data[i];\n      });\n      return polygons;\n    }\n    function sites(data) {\n      return data.map(function(d, i) {\n        return {\n          x: Math.round(fx(d, i) / ε) * ε,\n          y: Math.round(fy(d, i) / ε) * ε,\n          i: i\n        };\n      });\n    }\n    voronoi.links = function(data) {\n      return d3_geom_voronoi(sites(data)).edges.filter(function(edge) {\n        return edge.l && edge.r;\n      }).map(function(edge) {\n        return {\n          source: data[edge.l.i],\n          target: data[edge.r.i]\n        };\n      });\n    };\n    voronoi.triangles = function(data) {\n      var triangles = [];\n      d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) {\n        var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l;\n        while (++j < m) {\n          e0 = e1;\n          s0 = s1;\n          e1 = edges[j].edge;\n          s1 = e1.l === site ? e1.r : e1.l;\n          if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) {\n            triangles.push([ data[i], data[s0.i], data[s1.i] ]);\n          }\n        }\n      });\n      return triangles;\n    };\n    voronoi.x = function(_) {\n      return arguments.length ? (fx = d3_functor(x = _), voronoi) : x;\n    };\n    voronoi.y = function(_) {\n      return arguments.length ? (fy = d3_functor(y = _), voronoi) : y;\n    };\n    voronoi.clipExtent = function(_) {\n      if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent;\n      clipExtent = _ == null ? d3_geom_voronoiClipExtent : _;\n      return voronoi;\n    };\n    voronoi.size = function(_) {\n      if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1];\n      return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]);\n    };\n    return voronoi;\n  };\n  var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ];\n  function d3_geom_voronoiTriangleArea(a, b, c) {\n    return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y);\n  }\n  d3.geom.delaunay = function(vertices) {\n    return d3.geom.voronoi().triangles(vertices);\n  };\n  d3.geom.quadtree = function(points, x1, y1, x2, y2) {\n    var x = d3_geom_pointX, y = d3_geom_pointY, compat;\n    if (compat = arguments.length) {\n      x = d3_geom_quadtreeCompatX;\n      y = d3_geom_quadtreeCompatY;\n      if (compat === 3) {\n        y2 = y1;\n        x2 = x1;\n        y1 = x1 = 0;\n      }\n      return quadtree(points);\n    }\n    function quadtree(data) {\n      var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_;\n      if (x1 != null) {\n        x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2;\n      } else {\n        x2_ = y2_ = -(x1_ = y1_ = Infinity);\n        xs = [], ys = [];\n        n = data.length;\n        if (compat) for (i = 0; i < n; ++i) {\n          d = data[i];\n          if (d.x < x1_) x1_ = d.x;\n          if (d.y < y1_) y1_ = d.y;\n          if (d.x > x2_) x2_ = d.x;\n          if (d.y > y2_) y2_ = d.y;\n          xs.push(d.x);\n          ys.push(d.y);\n        } else for (i = 0; i < n; ++i) {\n          var x_ = +fx(d = data[i], i), y_ = +fy(d, i);\n          if (x_ < x1_) x1_ = x_;\n          if (y_ < y1_) y1_ = y_;\n          if (x_ > x2_) x2_ = x_;\n          if (y_ > y2_) y2_ = y_;\n          xs.push(x_);\n          ys.push(y_);\n        }\n      }\n      var dx = x2_ - x1_, dy = y2_ - y1_;\n      if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy;\n      function insert(n, d, x, y, x1, y1, x2, y2) {\n        if (isNaN(x) || isNaN(y)) return;\n        if (n.leaf) {\n          var nx = n.x, ny = n.y;\n          if (nx != null) {\n            if (abs(nx - x) + abs(ny - y) < .01) {\n              insertChild(n, d, x, y, x1, y1, x2, y2);\n            } else {\n              var nPoint = n.point;\n              n.x = n.y = n.point = null;\n              insertChild(n, nPoint, nx, ny, x1, y1, x2, y2);\n              insertChild(n, d, x, y, x1, y1, x2, y2);\n            }\n          } else {\n            n.x = x, n.y = y, n.point = d;\n          }\n        } else {\n          insertChild(n, d, x, y, x1, y1, x2, y2);\n        }\n      }\n      function insertChild(n, d, x, y, x1, y1, x2, y2) {\n        var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right;\n        n.leaf = false;\n        n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());\n        if (right) x1 = xm; else x2 = xm;\n        if (below) y1 = ym; else y2 = ym;\n        insert(n, d, x, y, x1, y1, x2, y2);\n      }\n      var root = d3_geom_quadtreeNode();\n      root.add = function(d) {\n        insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_);\n      };\n      root.visit = function(f) {\n        d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_);\n      };\n      root.find = function(point) {\n        return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_);\n      };\n      i = -1;\n      if (x1 == null) {\n        while (++i < n) {\n          insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_);\n        }\n        --i;\n      } else data.forEach(root.add);\n      xs = ys = data = d = null;\n      return root;\n    }\n    quadtree.x = function(_) {\n      return arguments.length ? (x = _, quadtree) : x;\n    };\n    quadtree.y = function(_) {\n      return arguments.length ? (y = _, quadtree) : y;\n    };\n    quadtree.extent = function(_) {\n      if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ];\n      if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], \n      y2 = +_[1][1];\n      return quadtree;\n    };\n    quadtree.size = function(_) {\n      if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ];\n      if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1];\n      return quadtree;\n    };\n    return quadtree;\n  };\n  function d3_geom_quadtreeCompatX(d) {\n    return d.x;\n  }\n  function d3_geom_quadtreeCompatY(d) {\n    return d.y;\n  }\n  function d3_geom_quadtreeNode() {\n    return {\n      leaf: true,\n      nodes: [],\n      point: null,\n      x: null,\n      y: null\n    };\n  }\n  function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {\n    if (!f(node, x1, y1, x2, y2)) {\n      var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes;\n      if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);\n      if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);\n      if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);\n      if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);\n    }\n  }\n  function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) {\n    var minDistance2 = Infinity, closestPoint;\n    (function find(node, x1, y1, x2, y2) {\n      if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return;\n      if (point = node.point) {\n        var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy;\n        if (distance2 < minDistance2) {\n          var distance = Math.sqrt(minDistance2 = distance2);\n          x0 = x - distance, y0 = y - distance;\n          x3 = x + distance, y3 = y + distance;\n          closestPoint = point;\n        }\n      }\n      var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym;\n      for (var i = below << 1 | right, j = i + 4; i < j; ++i) {\n        if (node = children[i & 3]) switch (i & 3) {\n         case 0:\n          find(node, x1, y1, xm, ym);\n          break;\n\n         case 1:\n          find(node, xm, y1, x2, ym);\n          break;\n\n         case 2:\n          find(node, x1, ym, xm, y2);\n          break;\n\n         case 3:\n          find(node, xm, ym, x2, y2);\n          break;\n        }\n      }\n    })(root, x0, y0, x3, y3);\n    return closestPoint;\n  }\n  d3.interpolateRgb = d3_interpolateRgb;\n  function d3_interpolateRgb(a, b) {\n    a = d3.rgb(a);\n    b = d3.rgb(b);\n    var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab;\n    return function(t) {\n      return \"#\" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t));\n    };\n  }\n  d3.interpolateObject = d3_interpolateObject;\n  function d3_interpolateObject(a, b) {\n    var i = {}, c = {}, k;\n    for (k in a) {\n      if (k in b) {\n        i[k] = d3_interpolate(a[k], b[k]);\n      } else {\n        c[k] = a[k];\n      }\n    }\n    for (k in b) {\n      if (!(k in a)) {\n        c[k] = b[k];\n      }\n    }\n    return function(t) {\n      for (k in i) c[k] = i[k](t);\n      return c;\n    };\n  }\n  d3.interpolateNumber = d3_interpolateNumber;\n  function d3_interpolateNumber(a, b) {\n    a = +a, b = +b;\n    return function(t) {\n      return a * (1 - t) + b * t;\n    };\n  }\n  d3.interpolateString = d3_interpolateString;\n  function d3_interpolateString(a, b) {\n    var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = [];\n    a = a + \"\", b = b + \"\";\n    while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) {\n      if ((bs = bm.index) > bi) {\n        bs = b.slice(bi, bs);\n        if (s[i]) s[i] += bs; else s[++i] = bs;\n      }\n      if ((am = am[0]) === (bm = bm[0])) {\n        if (s[i]) s[i] += bm; else s[++i] = bm;\n      } else {\n        s[++i] = null;\n        q.push({\n          i: i,\n          x: d3_interpolateNumber(am, bm)\n        });\n      }\n      bi = d3_interpolate_numberB.lastIndex;\n    }\n    if (bi < b.length) {\n      bs = b.slice(bi);\n      if (s[i]) s[i] += bs; else s[++i] = bs;\n    }\n    return s.length < 2 ? q[0] ? (b = q[0].x, function(t) {\n      return b(t) + \"\";\n    }) : function() {\n      return b;\n    } : (b = q.length, function(t) {\n      for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n      return s.join(\"\");\n    });\n  }\n  var d3_interpolate_numberA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, \"g\");\n  d3.interpolate = d3_interpolate;\n  function d3_interpolate(a, b) {\n    var i = d3.interpolators.length, f;\n    while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ;\n    return f;\n  }\n  d3.interpolators = [ function(a, b) {\n    var t = typeof b;\n    return (t === \"string\" ? d3_rgb_names.has(b.toLowerCase()) || /^(#|rgb\\(|hsl\\()/i.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === \"object\" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b);\n  } ];\n  d3.interpolateArray = d3_interpolateArray;\n  function d3_interpolateArray(a, b) {\n    var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i;\n    for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i]));\n    for (;i < na; ++i) c[i] = a[i];\n    for (;i < nb; ++i) c[i] = b[i];\n    return function(t) {\n      for (i = 0; i < n0; ++i) c[i] = x[i](t);\n      return c;\n    };\n  }\n  var d3_ease_default = function() {\n    return d3_identity;\n  };\n  var d3_ease = d3.map({\n    linear: d3_ease_default,\n    poly: d3_ease_poly,\n    quad: function() {\n      return d3_ease_quad;\n    },\n    cubic: function() {\n      return d3_ease_cubic;\n    },\n    sin: function() {\n      return d3_ease_sin;\n    },\n    exp: function() {\n      return d3_ease_exp;\n    },\n    circle: function() {\n      return d3_ease_circle;\n    },\n    elastic: d3_ease_elastic,\n    back: d3_ease_back,\n    bounce: function() {\n      return d3_ease_bounce;\n    }\n  });\n  var d3_ease_mode = d3.map({\n    \"in\": d3_identity,\n    out: d3_ease_reverse,\n    \"in-out\": d3_ease_reflect,\n    \"out-in\": function(f) {\n      return d3_ease_reflect(d3_ease_reverse(f));\n    }\n  });\n  d3.ease = function(name) {\n    var i = name.indexOf(\"-\"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : \"in\";\n    t = d3_ease.get(t) || d3_ease_default;\n    m = d3_ease_mode.get(m) || d3_identity;\n    return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1))));\n  };\n  function d3_ease_clamp(f) {\n    return function(t) {\n      return t <= 0 ? 0 : t >= 1 ? 1 : f(t);\n    };\n  }\n  function d3_ease_reverse(f) {\n    return function(t) {\n      return 1 - f(1 - t);\n    };\n  }\n  function d3_ease_reflect(f) {\n    return function(t) {\n      return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));\n    };\n  }\n  function d3_ease_quad(t) {\n    return t * t;\n  }\n  function d3_ease_cubic(t) {\n    return t * t * t;\n  }\n  function d3_ease_cubicInOut(t) {\n    if (t <= 0) return 0;\n    if (t >= 1) return 1;\n    var t2 = t * t, t3 = t2 * t;\n    return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75);\n  }\n  function d3_ease_poly(e) {\n    return function(t) {\n      return Math.pow(t, e);\n    };\n  }\n  function d3_ease_sin(t) {\n    return 1 - Math.cos(t * halfπ);\n  }\n  function d3_ease_exp(t) {\n    return Math.pow(2, 10 * (t - 1));\n  }\n  function d3_ease_circle(t) {\n    return 1 - Math.sqrt(1 - t * t);\n  }\n  function d3_ease_elastic(a, p) {\n    var s;\n    if (arguments.length < 2) p = .45;\n    if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4;\n    return function(t) {\n      return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p);\n    };\n  }\n  function d3_ease_back(s) {\n    if (!s) s = 1.70158;\n    return function(t) {\n      return t * t * ((s + 1) * t - s);\n    };\n  }\n  function d3_ease_bounce(t) {\n    return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;\n  }\n  d3.interpolateHcl = d3_interpolateHcl;\n  function d3_interpolateHcl(a, b) {\n    a = d3.hcl(a);\n    b = d3.hcl(b);\n    var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al;\n    if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac;\n    if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;\n    return function(t) {\n      return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + \"\";\n    };\n  }\n  d3.interpolateHsl = d3_interpolateHsl;\n  function d3_interpolateHsl(a, b) {\n    a = d3.hsl(a);\n    b = d3.hsl(b);\n    var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al;\n    if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as;\n    if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;\n    return function(t) {\n      return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + \"\";\n    };\n  }\n  d3.interpolateLab = d3_interpolateLab;\n  function d3_interpolateLab(a, b) {\n    a = d3.lab(a);\n    b = d3.lab(b);\n    var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab;\n    return function(t) {\n      return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + \"\";\n    };\n  }\n  d3.interpolateRound = d3_interpolateRound;\n  function d3_interpolateRound(a, b) {\n    b -= a;\n    return function(t) {\n      return Math.round(a + b * t);\n    };\n  }\n  d3.transform = function(string) {\n    var g = d3_document.createElementNS(d3.ns.prefix.svg, \"g\");\n    return (d3.transform = function(string) {\n      if (string != null) {\n        g.setAttribute(\"transform\", string);\n        var t = g.transform.baseVal.consolidate();\n      }\n      return new d3_transform(t ? t.matrix : d3_transformIdentity);\n    })(string);\n  };\n  function d3_transform(m) {\n    var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;\n    if (r0[0] * r1[1] < r1[0] * r0[1]) {\n      r0[0] *= -1;\n      r0[1] *= -1;\n      kx *= -1;\n      kz *= -1;\n    }\n    this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees;\n    this.translate = [ m.e, m.f ];\n    this.scale = [ kx, ky ];\n    this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0;\n  }\n  d3_transform.prototype.toString = function() {\n    return \"translate(\" + this.translate + \")rotate(\" + this.rotate + \")skewX(\" + this.skew + \")scale(\" + this.scale + \")\";\n  };\n  function d3_transformDot(a, b) {\n    return a[0] * b[0] + a[1] * b[1];\n  }\n  function d3_transformNormalize(a) {\n    var k = Math.sqrt(d3_transformDot(a, a));\n    if (k) {\n      a[0] /= k;\n      a[1] /= k;\n    }\n    return k;\n  }\n  function d3_transformCombine(a, b, k) {\n    a[0] += k * b[0];\n    a[1] += k * b[1];\n    return a;\n  }\n  var d3_transformIdentity = {\n    a: 1,\n    b: 0,\n    c: 0,\n    d: 1,\n    e: 0,\n    f: 0\n  };\n  d3.interpolateTransform = d3_interpolateTransform;\n  function d3_interpolateTransformPop(s) {\n    return s.length ? s.pop() + \",\" : \"\";\n  }\n  function d3_interpolateTranslate(ta, tb, s, q) {\n    if (ta[0] !== tb[0] || ta[1] !== tb[1]) {\n      var i = s.push(\"translate(\", null, \",\", null, \")\");\n      q.push({\n        i: i - 4,\n        x: d3_interpolateNumber(ta[0], tb[0])\n      }, {\n        i: i - 2,\n        x: d3_interpolateNumber(ta[1], tb[1])\n      });\n    } else if (tb[0] || tb[1]) {\n      s.push(\"translate(\" + tb + \")\");\n    }\n  }\n  function d3_interpolateRotate(ra, rb, s, q) {\n    if (ra !== rb) {\n      if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;\n      q.push({\n        i: s.push(d3_interpolateTransformPop(s) + \"rotate(\", null, \")\") - 2,\n        x: d3_interpolateNumber(ra, rb)\n      });\n    } else if (rb) {\n      s.push(d3_interpolateTransformPop(s) + \"rotate(\" + rb + \")\");\n    }\n  }\n  function d3_interpolateSkew(wa, wb, s, q) {\n    if (wa !== wb) {\n      q.push({\n        i: s.push(d3_interpolateTransformPop(s) + \"skewX(\", null, \")\") - 2,\n        x: d3_interpolateNumber(wa, wb)\n      });\n    } else if (wb) {\n      s.push(d3_interpolateTransformPop(s) + \"skewX(\" + wb + \")\");\n    }\n  }\n  function d3_interpolateScale(ka, kb, s, q) {\n    if (ka[0] !== kb[0] || ka[1] !== kb[1]) {\n      var i = s.push(d3_interpolateTransformPop(s) + \"scale(\", null, \",\", null, \")\");\n      q.push({\n        i: i - 4,\n        x: d3_interpolateNumber(ka[0], kb[0])\n      }, {\n        i: i - 2,\n        x: d3_interpolateNumber(ka[1], kb[1])\n      });\n    } else if (kb[0] !== 1 || kb[1] !== 1) {\n      s.push(d3_interpolateTransformPop(s) + \"scale(\" + kb + \")\");\n    }\n  }\n  function d3_interpolateTransform(a, b) {\n    var s = [], q = [];\n    a = d3.transform(a), b = d3.transform(b);\n    d3_interpolateTranslate(a.translate, b.translate, s, q);\n    d3_interpolateRotate(a.rotate, b.rotate, s, q);\n    d3_interpolateSkew(a.skew, b.skew, s, q);\n    d3_interpolateScale(a.scale, b.scale, s, q);\n    a = b = null;\n    return function(t) {\n      var i = -1, n = q.length, o;\n      while (++i < n) s[(o = q[i]).i] = o.x(t);\n      return s.join(\"\");\n    };\n  }\n  function d3_uninterpolateNumber(a, b) {\n    b = (b -= a = +a) || 1 / b;\n    return function(x) {\n      return (x - a) / b;\n    };\n  }\n  function d3_uninterpolateClamp(a, b) {\n    b = (b -= a = +a) || 1 / b;\n    return function(x) {\n      return Math.max(0, Math.min(1, (x - a) / b));\n    };\n  }\n  d3.layout = {};\n  d3.layout.bundle = function() {\n    return function(links) {\n      var paths = [], i = -1, n = links.length;\n      while (++i < n) paths.push(d3_layout_bundlePath(links[i]));\n      return paths;\n    };\n  };\n  function d3_layout_bundlePath(link) {\n    var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ];\n    while (start !== lca) {\n      start = start.parent;\n      points.push(start);\n    }\n    var k = points.length;\n    while (end !== lca) {\n      points.splice(k, 0, end);\n      end = end.parent;\n    }\n    return points;\n  }\n  function d3_layout_bundleAncestors(node) {\n    var ancestors = [], parent = node.parent;\n    while (parent != null) {\n      ancestors.push(node);\n      node = parent;\n      parent = parent.parent;\n    }\n    ancestors.push(node);\n    return ancestors;\n  }\n  function d3_layout_bundleLeastCommonAncestor(a, b) {\n    if (a === b) return a;\n    var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null;\n    while (aNode === bNode) {\n      sharedNode = aNode;\n      aNode = aNodes.pop();\n      bNode = bNodes.pop();\n    }\n    return sharedNode;\n  }\n  d3.layout.chord = function() {\n    var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords;\n    function relayout() {\n      var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j;\n      chords = [];\n      groups = [];\n      k = 0, i = -1;\n      while (++i < n) {\n        x = 0, j = -1;\n        while (++j < n) {\n          x += matrix[i][j];\n        }\n        groupSums.push(x);\n        subgroupIndex.push(d3.range(n));\n        k += x;\n      }\n      if (sortGroups) {\n        groupIndex.sort(function(a, b) {\n          return sortGroups(groupSums[a], groupSums[b]);\n        });\n      }\n      if (sortSubgroups) {\n        subgroupIndex.forEach(function(d, i) {\n          d.sort(function(a, b) {\n            return sortSubgroups(matrix[i][a], matrix[i][b]);\n          });\n        });\n      }\n      k = (τ - padding * n) / k;\n      x = 0, i = -1;\n      while (++i < n) {\n        x0 = x, j = -1;\n        while (++j < n) {\n          var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k;\n          subgroups[di + \"-\" + dj] = {\n            index: di,\n            subindex: dj,\n            startAngle: a0,\n            endAngle: a1,\n            value: v\n          };\n        }\n        groups[di] = {\n          index: di,\n          startAngle: x0,\n          endAngle: x,\n          value: (x - x0) / k\n        };\n        x += padding;\n      }\n      i = -1;\n      while (++i < n) {\n        j = i - 1;\n        while (++j < n) {\n          var source = subgroups[i + \"-\" + j], target = subgroups[j + \"-\" + i];\n          if (source.value || target.value) {\n            chords.push(source.value < target.value ? {\n              source: target,\n              target: source\n            } : {\n              source: source,\n              target: target\n            });\n          }\n        }\n      }\n      if (sortChords) resort();\n    }\n    function resort() {\n      chords.sort(function(a, b) {\n        return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2);\n      });\n    }\n    chord.matrix = function(x) {\n      if (!arguments.length) return matrix;\n      n = (matrix = x) && matrix.length;\n      chords = groups = null;\n      return chord;\n    };\n    chord.padding = function(x) {\n      if (!arguments.length) return padding;\n      padding = x;\n      chords = groups = null;\n      return chord;\n    };\n    chord.sortGroups = function(x) {\n      if (!arguments.length) return sortGroups;\n      sortGroups = x;\n      chords = groups = null;\n      return chord;\n    };\n    chord.sortSubgroups = function(x) {\n      if (!arguments.length) return sortSubgroups;\n      sortSubgroups = x;\n      chords = null;\n      return chord;\n    };\n    chord.sortChords = function(x) {\n      if (!arguments.length) return sortChords;\n      sortChords = x;\n      if (chords) resort();\n      return chord;\n    };\n    chord.chords = function() {\n      if (!chords) relayout();\n      return chords;\n    };\n    chord.groups = function() {\n      if (!groups) relayout();\n      return groups;\n    };\n    return chord;\n  };\n  d3.layout.force = function() {\n    var force = {}, event = d3.dispatch(\"start\", \"tick\", \"end\"), timer, size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges;\n    function repulse(node) {\n      return function(quad, x1, _, x2) {\n        if (quad.point !== node) {\n          var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy;\n          if (dw * dw / theta2 < dn) {\n            if (dn < chargeDistance2) {\n              var k = quad.charge / dn;\n              node.px -= dx * k;\n              node.py -= dy * k;\n            }\n            return true;\n          }\n          if (quad.point && dn && dn < chargeDistance2) {\n            var k = quad.pointCharge / dn;\n            node.px -= dx * k;\n            node.py -= dy * k;\n          }\n        }\n        return !quad.charge;\n      };\n    }\n    force.tick = function() {\n      if ((alpha *= .99) < .005) {\n        timer = null;\n        event.end({\n          type: \"end\",\n          alpha: alpha = 0\n        });\n        return true;\n      }\n      var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y;\n      for (i = 0; i < m; ++i) {\n        o = links[i];\n        s = o.source;\n        t = o.target;\n        x = t.x - s.x;\n        y = t.y - s.y;\n        if (l = x * x + y * y) {\n          l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;\n          x *= l;\n          y *= l;\n          t.x -= x * (k = s.weight + t.weight ? s.weight / (s.weight + t.weight) : .5);\n          t.y -= y * k;\n          s.x += x * (k = 1 - k);\n          s.y += y * k;\n        }\n      }\n      if (k = alpha * gravity) {\n        x = size[0] / 2;\n        y = size[1] / 2;\n        i = -1;\n        if (k) while (++i < n) {\n          o = nodes[i];\n          o.x += (x - o.x) * k;\n          o.y += (y - o.y) * k;\n        }\n      }\n      if (charge) {\n        d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges);\n        i = -1;\n        while (++i < n) {\n          if (!(o = nodes[i]).fixed) {\n            q.visit(repulse(o));\n          }\n        }\n      }\n      i = -1;\n      while (++i < n) {\n        o = nodes[i];\n        if (o.fixed) {\n          o.x = o.px;\n          o.y = o.py;\n        } else {\n          o.x -= (o.px - (o.px = o.x)) * friction;\n          o.y -= (o.py - (o.py = o.y)) * friction;\n        }\n      }\n      event.tick({\n        type: \"tick\",\n        alpha: alpha\n      });\n    };\n    force.nodes = function(x) {\n      if (!arguments.length) return nodes;\n      nodes = x;\n      return force;\n    };\n    force.links = function(x) {\n      if (!arguments.length) return links;\n      links = x;\n      return force;\n    };\n    force.size = function(x) {\n      if (!arguments.length) return size;\n      size = x;\n      return force;\n    };\n    force.linkDistance = function(x) {\n      if (!arguments.length) return linkDistance;\n      linkDistance = typeof x === \"function\" ? x : +x;\n      return force;\n    };\n    force.distance = force.linkDistance;\n    force.linkStrength = function(x) {\n      if (!arguments.length) return linkStrength;\n      linkStrength = typeof x === \"function\" ? x : +x;\n      return force;\n    };\n    force.friction = function(x) {\n      if (!arguments.length) return friction;\n      friction = +x;\n      return force;\n    };\n    force.charge = function(x) {\n      if (!arguments.length) return charge;\n      charge = typeof x === \"function\" ? x : +x;\n      return force;\n    };\n    force.chargeDistance = function(x) {\n      if (!arguments.length) return Math.sqrt(chargeDistance2);\n      chargeDistance2 = x * x;\n      return force;\n    };\n    force.gravity = function(x) {\n      if (!arguments.length) return gravity;\n      gravity = +x;\n      return force;\n    };\n    force.theta = function(x) {\n      if (!arguments.length) return Math.sqrt(theta2);\n      theta2 = x * x;\n      return force;\n    };\n    force.alpha = function(x) {\n      if (!arguments.length) return alpha;\n      x = +x;\n      if (alpha) {\n        if (x > 0) {\n          alpha = x;\n        } else {\n          timer.c = null, timer.t = NaN, timer = null;\n          event.end({\n            type: \"end\",\n            alpha: alpha = 0\n          });\n        }\n      } else if (x > 0) {\n        event.start({\n          type: \"start\",\n          alpha: alpha = x\n        });\n        timer = d3_timer(force.tick);\n      }\n      return force;\n    };\n    force.start = function() {\n      var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o;\n      for (i = 0; i < n; ++i) {\n        (o = nodes[i]).index = i;\n        o.weight = 0;\n      }\n      for (i = 0; i < m; ++i) {\n        o = links[i];\n        if (typeof o.source == \"number\") o.source = nodes[o.source];\n        if (typeof o.target == \"number\") o.target = nodes[o.target];\n        ++o.source.weight;\n        ++o.target.weight;\n      }\n      for (i = 0; i < n; ++i) {\n        o = nodes[i];\n        if (isNaN(o.x)) o.x = position(\"x\", w);\n        if (isNaN(o.y)) o.y = position(\"y\", h);\n        if (isNaN(o.px)) o.px = o.x;\n        if (isNaN(o.py)) o.py = o.y;\n      }\n      distances = [];\n      if (typeof linkDistance === \"function\") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance;\n      strengths = [];\n      if (typeof linkStrength === \"function\") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength;\n      charges = [];\n      if (typeof charge === \"function\") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge;\n      function position(dimension, size) {\n        if (!neighbors) {\n          neighbors = new Array(n);\n          for (j = 0; j < n; ++j) {\n            neighbors[j] = [];\n          }\n          for (j = 0; j < m; ++j) {\n            var o = links[j];\n            neighbors[o.source.index].push(o.target);\n            neighbors[o.target.index].push(o.source);\n          }\n        }\n        var candidates = neighbors[i], j = -1, l = candidates.length, x;\n        while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x;\n        return Math.random() * size;\n      }\n      return force.resume();\n    };\n    force.resume = function() {\n      return force.alpha(.1);\n    };\n    force.stop = function() {\n      return force.alpha(0);\n    };\n    force.drag = function() {\n      if (!drag) drag = d3.behavior.drag().origin(d3_identity).on(\"dragstart.force\", d3_layout_forceDragstart).on(\"drag.force\", dragmove).on(\"dragend.force\", d3_layout_forceDragend);\n      if (!arguments.length) return drag;\n      this.on(\"mouseover.force\", d3_layout_forceMouseover).on(\"mouseout.force\", d3_layout_forceMouseout).call(drag);\n    };\n    function dragmove(d) {\n      d.px = d3.event.x, d.py = d3.event.y;\n      force.resume();\n    }\n    return d3.rebind(force, event, \"on\");\n  };\n  function d3_layout_forceDragstart(d) {\n    d.fixed |= 2;\n  }\n  function d3_layout_forceDragend(d) {\n    d.fixed &= ~6;\n  }\n  function d3_layout_forceMouseover(d) {\n    d.fixed |= 4;\n    d.px = d.x, d.py = d.y;\n  }\n  function d3_layout_forceMouseout(d) {\n    d.fixed &= ~4;\n  }\n  function d3_layout_forceAccumulate(quad, alpha, charges) {\n    var cx = 0, cy = 0;\n    quad.charge = 0;\n    if (!quad.leaf) {\n      var nodes = quad.nodes, n = nodes.length, i = -1, c;\n      while (++i < n) {\n        c = nodes[i];\n        if (c == null) continue;\n        d3_layout_forceAccumulate(c, alpha, charges);\n        quad.charge += c.charge;\n        cx += c.charge * c.cx;\n        cy += c.charge * c.cy;\n      }\n    }\n    if (quad.point) {\n      if (!quad.leaf) {\n        quad.point.x += Math.random() - .5;\n        quad.point.y += Math.random() - .5;\n      }\n      var k = alpha * charges[quad.point.index];\n      quad.charge += quad.pointCharge = k;\n      cx += k * quad.point.x;\n      cy += k * quad.point.y;\n    }\n    quad.cx = cx / quad.charge;\n    quad.cy = cy / quad.charge;\n  }\n  var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity;\n  d3.layout.hierarchy = function() {\n    var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue;\n    function hierarchy(root) {\n      var stack = [ root ], nodes = [], node;\n      root.depth = 0;\n      while ((node = stack.pop()) != null) {\n        nodes.push(node);\n        if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) {\n          var n, childs, child;\n          while (--n >= 0) {\n            stack.push(child = childs[n]);\n            child.parent = node;\n            child.depth = node.depth + 1;\n          }\n          if (value) node.value = 0;\n          node.children = childs;\n        } else {\n          if (value) node.value = +value.call(hierarchy, node, node.depth) || 0;\n          delete node.children;\n        }\n      }\n      d3_layout_hierarchyVisitAfter(root, function(node) {\n        var childs, parent;\n        if (sort && (childs = node.children)) childs.sort(sort);\n        if (value && (parent = node.parent)) parent.value += node.value;\n      });\n      return nodes;\n    }\n    hierarchy.sort = function(x) {\n      if (!arguments.length) return sort;\n      sort = x;\n      return hierarchy;\n    };\n    hierarchy.children = function(x) {\n      if (!arguments.length) return children;\n      children = x;\n      return hierarchy;\n    };\n    hierarchy.value = function(x) {\n      if (!arguments.length) return value;\n      value = x;\n      return hierarchy;\n    };\n    hierarchy.revalue = function(root) {\n      if (value) {\n        d3_layout_hierarchyVisitBefore(root, function(node) {\n          if (node.children) node.value = 0;\n        });\n        d3_layout_hierarchyVisitAfter(root, function(node) {\n          var parent;\n          if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0;\n          if (parent = node.parent) parent.value += node.value;\n        });\n      }\n      return root;\n    };\n    return hierarchy;\n  };\n  function d3_layout_hierarchyRebind(object, hierarchy) {\n    d3.rebind(object, hierarchy, \"sort\", \"children\", \"value\");\n    object.nodes = object;\n    object.links = d3_layout_hierarchyLinks;\n    return object;\n  }\n  function d3_layout_hierarchyVisitBefore(node, callback) {\n    var nodes = [ node ];\n    while ((node = nodes.pop()) != null) {\n      callback(node);\n      if ((children = node.children) && (n = children.length)) {\n        var n, children;\n        while (--n >= 0) nodes.push(children[n]);\n      }\n    }\n  }\n  function d3_layout_hierarchyVisitAfter(node, callback) {\n    var nodes = [ node ], nodes2 = [];\n    while ((node = nodes.pop()) != null) {\n      nodes2.push(node);\n      if ((children = node.children) && (n = children.length)) {\n        var i = -1, n, children;\n        while (++i < n) nodes.push(children[i]);\n      }\n    }\n    while ((node = nodes2.pop()) != null) {\n      callback(node);\n    }\n  }\n  function d3_layout_hierarchyChildren(d) {\n    return d.children;\n  }\n  function d3_layout_hierarchyValue(d) {\n    return d.value;\n  }\n  function d3_layout_hierarchySort(a, b) {\n    return b.value - a.value;\n  }\n  function d3_layout_hierarchyLinks(nodes) {\n    return d3.merge(nodes.map(function(parent) {\n      return (parent.children || []).map(function(child) {\n        return {\n          source: parent,\n          target: child\n        };\n      });\n    }));\n  }\n  d3.layout.partition = function() {\n    var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ];\n    function position(node, x, dx, dy) {\n      var children = node.children;\n      node.x = x;\n      node.y = node.depth * dy;\n      node.dx = dx;\n      node.dy = dy;\n      if (children && (n = children.length)) {\n        var i = -1, n, c, d;\n        dx = node.value ? dx / node.value : 0;\n        while (++i < n) {\n          position(c = children[i], x, d = c.value * dx, dy);\n          x += d;\n        }\n      }\n    }\n    function depth(node) {\n      var children = node.children, d = 0;\n      if (children && (n = children.length)) {\n        var i = -1, n;\n        while (++i < n) d = Math.max(d, depth(children[i]));\n      }\n      return 1 + d;\n    }\n    function partition(d, i) {\n      var nodes = hierarchy.call(this, d, i);\n      position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));\n      return nodes;\n    }\n    partition.size = function(x) {\n      if (!arguments.length) return size;\n      size = x;\n      return partition;\n    };\n    return d3_layout_hierarchyRebind(partition, hierarchy);\n  };\n  d3.layout.pie = function() {\n    var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0;\n    function pie(data) {\n      var n = data.length, values = data.map(function(d, i) {\n        return +value.call(pie, d, i);\n      }), a = +(typeof startAngle === \"function\" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === \"function\" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === \"function\" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), sum = d3.sum(values), k = sum ? (da - n * pa) / sum : 0, index = d3.range(n), arcs = [], v;\n      if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) {\n        return values[j] - values[i];\n      } : function(i, j) {\n        return sort(data[i], data[j]);\n      });\n      index.forEach(function(i) {\n        arcs[i] = {\n          data: data[i],\n          value: v = values[i],\n          startAngle: a,\n          endAngle: a += v * k + pa,\n          padAngle: p\n        };\n      });\n      return arcs;\n    }\n    pie.value = function(_) {\n      if (!arguments.length) return value;\n      value = _;\n      return pie;\n    };\n    pie.sort = function(_) {\n      if (!arguments.length) return sort;\n      sort = _;\n      return pie;\n    };\n    pie.startAngle = function(_) {\n      if (!arguments.length) return startAngle;\n      startAngle = _;\n      return pie;\n    };\n    pie.endAngle = function(_) {\n      if (!arguments.length) return endAngle;\n      endAngle = _;\n      return pie;\n    };\n    pie.padAngle = function(_) {\n      if (!arguments.length) return padAngle;\n      padAngle = _;\n      return pie;\n    };\n    return pie;\n  };\n  var d3_layout_pieSortByValue = {};\n  d3.layout.stack = function() {\n    var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY;\n    function stack(data, index) {\n      if (!(n = data.length)) return data;\n      var series = data.map(function(d, i) {\n        return values.call(stack, d, i);\n      });\n      var points = series.map(function(d) {\n        return d.map(function(v, i) {\n          return [ x.call(stack, v, i), y.call(stack, v, i) ];\n        });\n      });\n      var orders = order.call(stack, points, index);\n      series = d3.permute(series, orders);\n      points = d3.permute(points, orders);\n      var offsets = offset.call(stack, points, index);\n      var m = series[0].length, n, i, j, o;\n      for (j = 0; j < m; ++j) {\n        out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);\n        for (i = 1; i < n; ++i) {\n          out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);\n        }\n      }\n      return data;\n    }\n    stack.values = function(x) {\n      if (!arguments.length) return values;\n      values = x;\n      return stack;\n    };\n    stack.order = function(x) {\n      if (!arguments.length) return order;\n      order = typeof x === \"function\" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault;\n      return stack;\n    };\n    stack.offset = function(x) {\n      if (!arguments.length) return offset;\n      offset = typeof x === \"function\" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero;\n      return stack;\n    };\n    stack.x = function(z) {\n      if (!arguments.length) return x;\n      x = z;\n      return stack;\n    };\n    stack.y = function(z) {\n      if (!arguments.length) return y;\n      y = z;\n      return stack;\n    };\n    stack.out = function(z) {\n      if (!arguments.length) return out;\n      out = z;\n      return stack;\n    };\n    return stack;\n  };\n  function d3_layout_stackX(d) {\n    return d.x;\n  }\n  function d3_layout_stackY(d) {\n    return d.y;\n  }\n  function d3_layout_stackOut(d, y0, y) {\n    d.y0 = y0;\n    d.y = y;\n  }\n  var d3_layout_stackOrders = d3.map({\n    \"inside-out\": function(data) {\n      var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) {\n        return max[a] - max[b];\n      }), top = 0, bottom = 0, tops = [], bottoms = [];\n      for (i = 0; i < n; ++i) {\n        j = index[i];\n        if (top < bottom) {\n          top += sums[j];\n          tops.push(j);\n        } else {\n          bottom += sums[j];\n          bottoms.push(j);\n        }\n      }\n      return bottoms.reverse().concat(tops);\n    },\n    reverse: function(data) {\n      return d3.range(data.length).reverse();\n    },\n    \"default\": d3_layout_stackOrderDefault\n  });\n  var d3_layout_stackOffsets = d3.map({\n    silhouette: function(data) {\n      var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = [];\n      for (j = 0; j < m; ++j) {\n        for (i = 0, o = 0; i < n; i++) o += data[i][j][1];\n        if (o > max) max = o;\n        sums.push(o);\n      }\n      for (j = 0; j < m; ++j) {\n        y0[j] = (max - sums[j]) / 2;\n      }\n      return y0;\n    },\n    wiggle: function(data) {\n      var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = [];\n      y0[0] = o = o0 = 0;\n      for (j = 1; j < m; ++j) {\n        for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];\n        for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {\n          for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {\n            s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;\n          }\n          s2 += s3 * data[i][j][1];\n        }\n        y0[j] = o -= s1 ? s2 / s1 * dx : 0;\n        if (o < o0) o0 = o;\n      }\n      for (j = 0; j < m; ++j) y0[j] -= o0;\n      return y0;\n    },\n    expand: function(data) {\n      var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = [];\n      for (j = 0; j < m; ++j) {\n        for (i = 0, o = 0; i < n; i++) o += data[i][j][1];\n        if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k;\n      }\n      for (j = 0; j < m; ++j) y0[j] = 0;\n      return y0;\n    },\n    zero: d3_layout_stackOffsetZero\n  });\n  function d3_layout_stackOrderDefault(data) {\n    return d3.range(data.length);\n  }\n  function d3_layout_stackOffsetZero(data) {\n    var j = -1, m = data[0].length, y0 = [];\n    while (++j < m) y0[j] = 0;\n    return y0;\n  }\n  function d3_layout_stackMaxIndex(array) {\n    var i = 1, j = 0, v = array[0][1], k, n = array.length;\n    for (;i < n; ++i) {\n      if ((k = array[i][1]) > v) {\n        j = i;\n        v = k;\n      }\n    }\n    return j;\n  }\n  function d3_layout_stackReduceSum(d) {\n    return d.reduce(d3_layout_stackSum, 0);\n  }\n  function d3_layout_stackSum(p, d) {\n    return p + d[1];\n  }\n  d3.layout.histogram = function() {\n    var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges;\n    function histogram(data, i) {\n      var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x;\n      while (++i < m) {\n        bin = bins[i] = [];\n        bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);\n        bin.y = 0;\n      }\n      if (m > 0) {\n        i = -1;\n        while (++i < n) {\n          x = values[i];\n          if (x >= range[0] && x <= range[1]) {\n            bin = bins[d3.bisect(thresholds, x, 1, m) - 1];\n            bin.y += k;\n            bin.push(data[i]);\n          }\n        }\n      }\n      return bins;\n    }\n    histogram.value = function(x) {\n      if (!arguments.length) return valuer;\n      valuer = x;\n      return histogram;\n    };\n    histogram.range = function(x) {\n      if (!arguments.length) return ranger;\n      ranger = d3_functor(x);\n      return histogram;\n    };\n    histogram.bins = function(x) {\n      if (!arguments.length) return binner;\n      binner = typeof x === \"number\" ? function(range) {\n        return d3_layout_histogramBinFixed(range, x);\n      } : d3_functor(x);\n      return histogram;\n    };\n    histogram.frequency = function(x) {\n      if (!arguments.length) return frequency;\n      frequency = !!x;\n      return histogram;\n    };\n    return histogram;\n  };\n  function d3_layout_histogramBinSturges(range, values) {\n    return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));\n  }\n  function d3_layout_histogramBinFixed(range, n) {\n    var x = -1, b = +range[0], m = (range[1] - b) / n, f = [];\n    while (++x <= n) f[x] = m * x + b;\n    return f;\n  }\n  function d3_layout_histogramRange(values) {\n    return [ d3.min(values), d3.max(values) ];\n  }\n  d3.layout.pack = function() {\n    var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius;\n    function pack(d, i) {\n      var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === \"function\" ? radius : function() {\n        return radius;\n      };\n      root.x = root.y = 0;\n      d3_layout_hierarchyVisitAfter(root, function(d) {\n        d.r = +r(d.value);\n      });\n      d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);\n      if (padding) {\n        var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2;\n        d3_layout_hierarchyVisitAfter(root, function(d) {\n          d.r += dr;\n        });\n        d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);\n        d3_layout_hierarchyVisitAfter(root, function(d) {\n          d.r -= dr;\n        });\n      }\n      d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h));\n      return nodes;\n    }\n    pack.size = function(_) {\n      if (!arguments.length) return size;\n      size = _;\n      return pack;\n    };\n    pack.radius = function(_) {\n      if (!arguments.length) return radius;\n      radius = _ == null || typeof _ === \"function\" ? _ : +_;\n      return pack;\n    };\n    pack.padding = function(_) {\n      if (!arguments.length) return padding;\n      padding = +_;\n      return pack;\n    };\n    return d3_layout_hierarchyRebind(pack, hierarchy);\n  };\n  function d3_layout_packSort(a, b) {\n    return a.value - b.value;\n  }\n  function d3_layout_packInsert(a, b) {\n    var c = a._pack_next;\n    a._pack_next = b;\n    b._pack_prev = a;\n    b._pack_next = c;\n    c._pack_prev = b;\n  }\n  function d3_layout_packSplice(a, b) {\n    a._pack_next = b;\n    b._pack_prev = a;\n  }\n  function d3_layout_packIntersects(a, b) {\n    var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;\n    return .999 * dr * dr > dx * dx + dy * dy;\n  }\n  function d3_layout_packSiblings(node) {\n    if (!(nodes = node.children) || !(n = nodes.length)) return;\n    var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;\n    function bound(node) {\n      xMin = Math.min(node.x - node.r, xMin);\n      xMax = Math.max(node.x + node.r, xMax);\n      yMin = Math.min(node.y - node.r, yMin);\n      yMax = Math.max(node.y + node.r, yMax);\n    }\n    nodes.forEach(d3_layout_packLink);\n    a = nodes[0];\n    a.x = -a.r;\n    a.y = 0;\n    bound(a);\n    if (n > 1) {\n      b = nodes[1];\n      b.x = b.r;\n      b.y = 0;\n      bound(b);\n      if (n > 2) {\n        c = nodes[2];\n        d3_layout_packPlace(a, b, c);\n        bound(c);\n        d3_layout_packInsert(a, c);\n        a._pack_prev = c;\n        d3_layout_packInsert(c, b);\n        b = a._pack_next;\n        for (i = 3; i < n; i++) {\n          d3_layout_packPlace(a, b, c = nodes[i]);\n          var isect = 0, s1 = 1, s2 = 1;\n          for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {\n            if (d3_layout_packIntersects(j, c)) {\n              isect = 1;\n              break;\n            }\n          }\n          if (isect == 1) {\n            for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {\n              if (d3_layout_packIntersects(k, c)) {\n                break;\n              }\n            }\n          }\n          if (isect) {\n            if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b);\n            i--;\n          } else {\n            d3_layout_packInsert(a, c);\n            b = c;\n            bound(c);\n          }\n        }\n      }\n    }\n    var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;\n    for (i = 0; i < n; i++) {\n      c = nodes[i];\n      c.x -= cx;\n      c.y -= cy;\n      cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));\n    }\n    node.r = cr;\n    nodes.forEach(d3_layout_packUnlink);\n  }\n  function d3_layout_packLink(node) {\n    node._pack_next = node._pack_prev = node;\n  }\n  function d3_layout_packUnlink(node) {\n    delete node._pack_next;\n    delete node._pack_prev;\n  }\n  function d3_layout_packTransform(node, x, y, k) {\n    var children = node.children;\n    node.x = x += k * node.x;\n    node.y = y += k * node.y;\n    node.r *= k;\n    if (children) {\n      var i = -1, n = children.length;\n      while (++i < n) d3_layout_packTransform(children[i], x, y, k);\n    }\n  }\n  function d3_layout_packPlace(a, b, c) {\n    var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y;\n    if (db && (dx || dy)) {\n      var da = b.r + c.r, dc = dx * dx + dy * dy;\n      da *= da;\n      db *= db;\n      var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);\n      c.x = a.x + x * dx + y * dy;\n      c.y = a.y + x * dy - y * dx;\n    } else {\n      c.x = a.x + db;\n      c.y = a.y;\n    }\n  }\n  d3.layout.tree = function() {\n    var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null;\n    function tree(d, i) {\n      var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0);\n      d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z;\n      d3_layout_hierarchyVisitBefore(root1, secondWalk);\n      if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else {\n        var left = root0, right = root0, bottom = root0;\n        d3_layout_hierarchyVisitBefore(root0, function(node) {\n          if (node.x < left.x) left = node;\n          if (node.x > right.x) right = node;\n          if (node.depth > bottom.depth) bottom = node;\n        });\n        var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1);\n        d3_layout_hierarchyVisitBefore(root0, function(node) {\n          node.x = (node.x + tx) * kx;\n          node.y = node.depth * ky;\n        });\n      }\n      return nodes;\n    }\n    function wrapTree(root0) {\n      var root1 = {\n        A: null,\n        children: [ root0 ]\n      }, queue = [ root1 ], node1;\n      while ((node1 = queue.pop()) != null) {\n        for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) {\n          queue.push((children[i] = child = {\n            _: children[i],\n            parent: node1,\n            children: (child = children[i].children) && child.slice() || [],\n            A: null,\n            a: null,\n            z: 0,\n            m: 0,\n            c: 0,\n            s: 0,\n            t: null,\n            i: i\n          }).a = child);\n        }\n      }\n      return root1.children[0];\n    }\n    function firstWalk(v) {\n      var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null;\n      if (children.length) {\n        d3_layout_treeShift(v);\n        var midpoint = (children[0].z + children[children.length - 1].z) / 2;\n        if (w) {\n          v.z = w.z + separation(v._, w._);\n          v.m = v.z - midpoint;\n        } else {\n          v.z = midpoint;\n        }\n      } else if (w) {\n        v.z = w.z + separation(v._, w._);\n      }\n      v.parent.A = apportion(v, w, v.parent.A || siblings[0]);\n    }\n    function secondWalk(v) {\n      v._.x = v.z + v.parent.m;\n      v.m += v.parent.m;\n    }\n    function apportion(v, w, ancestor) {\n      if (w) {\n        var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift;\n        while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {\n          vom = d3_layout_treeLeft(vom);\n          vop = d3_layout_treeRight(vop);\n          vop.a = v;\n          shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);\n          if (shift > 0) {\n            d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift);\n            sip += shift;\n            sop += shift;\n          }\n          sim += vim.m;\n          sip += vip.m;\n          som += vom.m;\n          sop += vop.m;\n        }\n        if (vim && !d3_layout_treeRight(vop)) {\n          vop.t = vim;\n          vop.m += sim - sop;\n        }\n        if (vip && !d3_layout_treeLeft(vom)) {\n          vom.t = vip;\n          vom.m += sip - som;\n          ancestor = v;\n        }\n      }\n      return ancestor;\n    }\n    function sizeNode(node) {\n      node.x *= size[0];\n      node.y = node.depth * size[1];\n    }\n    tree.separation = function(x) {\n      if (!arguments.length) return separation;\n      separation = x;\n      return tree;\n    };\n    tree.size = function(x) {\n      if (!arguments.length) return nodeSize ? null : size;\n      nodeSize = (size = x) == null ? sizeNode : null;\n      return tree;\n    };\n    tree.nodeSize = function(x) {\n      if (!arguments.length) return nodeSize ? size : null;\n      nodeSize = (size = x) == null ? null : sizeNode;\n      return tree;\n    };\n    return d3_layout_hierarchyRebind(tree, hierarchy);\n  };\n  function d3_layout_treeSeparation(a, b) {\n    return a.parent == b.parent ? 1 : 2;\n  }\n  function d3_layout_treeLeft(v) {\n    var children = v.children;\n    return children.length ? children[0] : v.t;\n  }\n  function d3_layout_treeRight(v) {\n    var children = v.children, n;\n    return (n = children.length) ? children[n - 1] : v.t;\n  }\n  function d3_layout_treeMove(wm, wp, shift) {\n    var change = shift / (wp.i - wm.i);\n    wp.c -= change;\n    wp.s += shift;\n    wm.c += change;\n    wp.z += shift;\n    wp.m += shift;\n  }\n  function d3_layout_treeShift(v) {\n    var shift = 0, change = 0, children = v.children, i = children.length, w;\n    while (--i >= 0) {\n      w = children[i];\n      w.z += shift;\n      w.m += shift;\n      shift += w.s + (change += w.c);\n    }\n  }\n  function d3_layout_treeAncestor(vim, v, ancestor) {\n    return vim.a.parent === v.parent ? vim.a : ancestor;\n  }\n  d3.layout.cluster = function() {\n    var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false;\n    function cluster(d, i) {\n      var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0;\n      d3_layout_hierarchyVisitAfter(root, function(node) {\n        var children = node.children;\n        if (children && children.length) {\n          node.x = d3_layout_clusterX(children);\n          node.y = d3_layout_clusterY(children);\n        } else {\n          node.x = previousNode ? x += separation(node, previousNode) : 0;\n          node.y = 0;\n          previousNode = node;\n        }\n      });\n      var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2;\n      d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) {\n        node.x = (node.x - root.x) * size[0];\n        node.y = (root.y - node.y) * size[1];\n      } : function(node) {\n        node.x = (node.x - x0) / (x1 - x0) * size[0];\n        node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];\n      });\n      return nodes;\n    }\n    cluster.separation = function(x) {\n      if (!arguments.length) return separation;\n      separation = x;\n      return cluster;\n    };\n    cluster.size = function(x) {\n      if (!arguments.length) return nodeSize ? null : size;\n      nodeSize = (size = x) == null;\n      return cluster;\n    };\n    cluster.nodeSize = function(x) {\n      if (!arguments.length) return nodeSize ? size : null;\n      nodeSize = (size = x) != null;\n      return cluster;\n    };\n    return d3_layout_hierarchyRebind(cluster, hierarchy);\n  };\n  function d3_layout_clusterY(children) {\n    return 1 + d3.max(children, function(child) {\n      return child.y;\n    });\n  }\n  function d3_layout_clusterX(children) {\n    return children.reduce(function(x, child) {\n      return x + child.x;\n    }, 0) / children.length;\n  }\n  function d3_layout_clusterLeft(node) {\n    var children = node.children;\n    return children && children.length ? d3_layout_clusterLeft(children[0]) : node;\n  }\n  function d3_layout_clusterRight(node) {\n    var children = node.children, n;\n    return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;\n  }\n  d3.layout.treemap = function() {\n    var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = \"squarify\", ratio = .5 * (1 + Math.sqrt(5));\n    function scale(children, k) {\n      var i = -1, n = children.length, child, area;\n      while (++i < n) {\n        area = (child = children[i]).value * (k < 0 ? 0 : k);\n        child.area = isNaN(area) || area <= 0 ? 0 : area;\n      }\n    }\n    function squarify(node) {\n      var children = node.children;\n      if (children && children.length) {\n        var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === \"slice\" ? rect.dx : mode === \"dice\" ? rect.dy : mode === \"slice-dice\" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n;\n        scale(remaining, rect.dx * rect.dy / node.value);\n        row.area = 0;\n        while ((n = remaining.length) > 0) {\n          row.push(child = remaining[n - 1]);\n          row.area += child.area;\n          if (mode !== \"squarify\" || (score = worst(row, u)) <= best) {\n            remaining.pop();\n            best = score;\n          } else {\n            row.area -= row.pop().area;\n            position(row, u, rect, false);\n            u = Math.min(rect.dx, rect.dy);\n            row.length = row.area = 0;\n            best = Infinity;\n          }\n        }\n        if (row.length) {\n          position(row, u, rect, true);\n          row.length = row.area = 0;\n        }\n        children.forEach(squarify);\n      }\n    }\n    function stickify(node) {\n      var children = node.children;\n      if (children && children.length) {\n        var rect = pad(node), remaining = children.slice(), child, row = [];\n        scale(remaining, rect.dx * rect.dy / node.value);\n        row.area = 0;\n        while (child = remaining.pop()) {\n          row.push(child);\n          row.area += child.area;\n          if (child.z != null) {\n            position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);\n            row.length = row.area = 0;\n          }\n        }\n        children.forEach(stickify);\n      }\n    }\n    function worst(row, u) {\n      var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length;\n      while (++i < n) {\n        if (!(r = row[i].area)) continue;\n        if (r < rmin) rmin = r;\n        if (r > rmax) rmax = r;\n      }\n      s *= s;\n      u *= u;\n      return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity;\n    }\n    function position(row, u, rect, flush) {\n      var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o;\n      if (u == rect.dx) {\n        if (flush || v > rect.dy) v = rect.dy;\n        while (++i < n) {\n          o = row[i];\n          o.x = x;\n          o.y = y;\n          o.dy = v;\n          x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);\n        }\n        o.z = true;\n        o.dx += rect.x + rect.dx - x;\n        rect.y += v;\n        rect.dy -= v;\n      } else {\n        if (flush || v > rect.dx) v = rect.dx;\n        while (++i < n) {\n          o = row[i];\n          o.x = x;\n          o.y = y;\n          o.dx = v;\n          y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);\n        }\n        o.z = false;\n        o.dy += rect.y + rect.dy - y;\n        rect.x += v;\n        rect.dx -= v;\n      }\n    }\n    function treemap(d) {\n      var nodes = stickies || hierarchy(d), root = nodes[0];\n      root.x = root.y = 0;\n      if (root.value) root.dx = size[0], root.dy = size[1]; else root.dx = root.dy = 0;\n      if (stickies) hierarchy.revalue(root);\n      scale([ root ], root.dx * root.dy / root.value);\n      (stickies ? stickify : squarify)(root);\n      if (sticky) stickies = nodes;\n      return nodes;\n    }\n    treemap.size = function(x) {\n      if (!arguments.length) return size;\n      size = x;\n      return treemap;\n    };\n    treemap.padding = function(x) {\n      if (!arguments.length) return padding;\n      function padFunction(node) {\n        var p = x.call(treemap, node, node.depth);\n        return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === \"number\" ? [ p, p, p, p ] : p);\n      }\n      function padConstant(node) {\n        return d3_layout_treemapPad(node, x);\n      }\n      var type;\n      pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === \"function\" ? padFunction : type === \"number\" ? (x = [ x, x, x, x ], \n      padConstant) : padConstant;\n      return treemap;\n    };\n    treemap.round = function(x) {\n      if (!arguments.length) return round != Number;\n      round = x ? Math.round : Number;\n      return treemap;\n    };\n    treemap.sticky = function(x) {\n      if (!arguments.length) return sticky;\n      sticky = x;\n      stickies = null;\n      return treemap;\n    };\n    treemap.ratio = function(x) {\n      if (!arguments.length) return ratio;\n      ratio = x;\n      return treemap;\n    };\n    treemap.mode = function(x) {\n      if (!arguments.length) return mode;\n      mode = x + \"\";\n      return treemap;\n    };\n    return d3_layout_hierarchyRebind(treemap, hierarchy);\n  };\n  function d3_layout_treemapPadNull(node) {\n    return {\n      x: node.x,\n      y: node.y,\n      dx: node.dx,\n      dy: node.dy\n    };\n  }\n  function d3_layout_treemapPad(node, padding) {\n    var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2];\n    if (dx < 0) {\n      x += dx / 2;\n      dx = 0;\n    }\n    if (dy < 0) {\n      y += dy / 2;\n      dy = 0;\n    }\n    return {\n      x: x,\n      y: y,\n      dx: dx,\n      dy: dy\n    };\n  }\n  d3.random = {\n    normal: function(µ, σ) {\n      var n = arguments.length;\n      if (n < 2) σ = 1;\n      if (n < 1) µ = 0;\n      return function() {\n        var x, y, r;\n        do {\n          x = Math.random() * 2 - 1;\n          y = Math.random() * 2 - 1;\n          r = x * x + y * y;\n        } while (!r || r > 1);\n        return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r);\n      };\n    },\n    logNormal: function() {\n      var random = d3.random.normal.apply(d3, arguments);\n      return function() {\n        return Math.exp(random());\n      };\n    },\n    bates: function(m) {\n      var random = d3.random.irwinHall(m);\n      return function() {\n        return random() / m;\n      };\n    },\n    irwinHall: function(m) {\n      return function() {\n        for (var s = 0, j = 0; j < m; j++) s += Math.random();\n        return s;\n      };\n    }\n  };\n  d3.scale = {};\n  function d3_scaleExtent(domain) {\n    var start = domain[0], stop = domain[domain.length - 1];\n    return start < stop ? [ start, stop ] : [ stop, start ];\n  }\n  function d3_scaleRange(scale) {\n    return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());\n  }\n  function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {\n    var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);\n    return function(x) {\n      return i(u(x));\n    };\n  }\n  function d3_scale_nice(domain, nice) {\n    var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;\n    if (x1 < x0) {\n      dx = i0, i0 = i1, i1 = dx;\n      dx = x0, x0 = x1, x1 = dx;\n    }\n    domain[i0] = nice.floor(x0);\n    domain[i1] = nice.ceil(x1);\n    return domain;\n  }\n  function d3_scale_niceStep(step) {\n    return step ? {\n      floor: function(x) {\n        return Math.floor(x / step) * step;\n      },\n      ceil: function(x) {\n        return Math.ceil(x / step) * step;\n      }\n    } : d3_scale_niceIdentity;\n  }\n  var d3_scale_niceIdentity = {\n    floor: d3_identity,\n    ceil: d3_identity\n  };\n  function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {\n    var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;\n    if (domain[k] < domain[0]) {\n      domain = domain.slice().reverse();\n      range = range.slice().reverse();\n    }\n    while (++j <= k) {\n      u.push(uninterpolate(domain[j - 1], domain[j]));\n      i.push(interpolate(range[j - 1], range[j]));\n    }\n    return function(x) {\n      var j = d3.bisect(domain, x, 1, k) - 1;\n      return i[j](u[j](x));\n    };\n  }\n  d3.scale.linear = function() {\n    return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false);\n  };\n  function d3_scale_linear(domain, range, interpolate, clamp) {\n    var output, input;\n    function rescale() {\n      var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;\n      output = linear(domain, range, uninterpolate, interpolate);\n      input = linear(range, domain, uninterpolate, d3_interpolate);\n      return scale;\n    }\n    function scale(x) {\n      return output(x);\n    }\n    scale.invert = function(y) {\n      return input(y);\n    };\n    scale.domain = function(x) {\n      if (!arguments.length) return domain;\n      domain = x.map(Number);\n      return rescale();\n    };\n    scale.range = function(x) {\n      if (!arguments.length) return range;\n      range = x;\n      return rescale();\n    };\n    scale.rangeRound = function(x) {\n      return scale.range(x).interpolate(d3_interpolateRound);\n    };\n    scale.clamp = function(x) {\n      if (!arguments.length) return clamp;\n      clamp = x;\n      return rescale();\n    };\n    scale.interpolate = function(x) {\n      if (!arguments.length) return interpolate;\n      interpolate = x;\n      return rescale();\n    };\n    scale.ticks = function(m) {\n      return d3_scale_linearTicks(domain, m);\n    };\n    scale.tickFormat = function(m, format) {\n      return d3_scale_linearTickFormat(domain, m, format);\n    };\n    scale.nice = function(m) {\n      d3_scale_linearNice(domain, m);\n      return rescale();\n    };\n    scale.copy = function() {\n      return d3_scale_linear(domain, range, interpolate, clamp);\n    };\n    return rescale();\n  }\n  function d3_scale_linearRebind(scale, linear) {\n    return d3.rebind(scale, linear, \"range\", \"rangeRound\", \"interpolate\", \"clamp\");\n  }\n  function d3_scale_linearNice(domain, m) {\n    return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));\n  }\n  function d3_scale_linearTickRange(domain, m) {\n    if (m == null) m = 10;\n    var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;\n    if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;\n    extent[0] = Math.ceil(extent[0] / step) * step;\n    extent[1] = Math.floor(extent[1] / step) * step + step * .5;\n    extent[2] = step;\n    return extent;\n  }\n  function d3_scale_linearTicks(domain, m) {\n    return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));\n  }\n  function d3_scale_linearTickFormat(domain, m, format) {\n    var range = d3_scale_linearTickRange(domain, m);\n    if (format) {\n      var match = d3_format_re.exec(format);\n      match.shift();\n      if (match[8] === \"s\") {\n        var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1])));\n        if (!match[7]) match[7] = \".\" + d3_scale_linearPrecision(prefix.scale(range[2]));\n        match[8] = \"f\";\n        format = d3.format(match.join(\"\"));\n        return function(d) {\n          return format(prefix.scale(d)) + prefix.symbol;\n        };\n      }\n      if (!match[7]) match[7] = \".\" + d3_scale_linearFormatPrecision(match[8], range);\n      format = match.join(\"\");\n    } else {\n      format = \",.\" + d3_scale_linearPrecision(range[2]) + \"f\";\n    }\n    return d3.format(format);\n  }\n  var d3_scale_linearFormatSignificant = {\n    s: 1,\n    g: 1,\n    p: 1,\n    r: 1,\n    e: 1\n  };\n  function d3_scale_linearPrecision(value) {\n    return -Math.floor(Math.log(value) / Math.LN10 + .01);\n  }\n  function d3_scale_linearFormatPrecision(type, range) {\n    var p = d3_scale_linearPrecision(range[2]);\n    return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== \"e\") : p - (type === \"%\") * 2;\n  }\n  d3.scale.log = function() {\n    return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]);\n  };\n  function d3_scale_log(linear, base, positive, domain) {\n    function log(x) {\n      return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base);\n    }\n    function pow(x) {\n      return positive ? Math.pow(base, x) : -Math.pow(base, -x);\n    }\n    function scale(x) {\n      return linear(log(x));\n    }\n    scale.invert = function(x) {\n      return pow(linear.invert(x));\n    };\n    scale.domain = function(x) {\n      if (!arguments.length) return domain;\n      positive = x[0] >= 0;\n      linear.domain((domain = x.map(Number)).map(log));\n      return scale;\n    };\n    scale.base = function(_) {\n      if (!arguments.length) return base;\n      base = +_;\n      linear.domain(domain.map(log));\n      return scale;\n    };\n    scale.nice = function() {\n      var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative);\n      linear.domain(niced);\n      domain = niced.map(pow);\n      return scale;\n    };\n    scale.ticks = function() {\n      var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base;\n      if (isFinite(j - i)) {\n        if (positive) {\n          for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k);\n          ticks.push(pow(i));\n        } else {\n          ticks.push(pow(i));\n          for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k);\n        }\n        for (i = 0; ticks[i] < u; i++) {}\n        for (j = ticks.length; ticks[j - 1] > v; j--) {}\n        ticks = ticks.slice(i, j);\n      }\n      return ticks;\n    };\n    scale.tickFormat = function(n, format) {\n      if (!arguments.length) return d3_scale_logFormat;\n      if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== \"function\") format = d3.format(format);\n      var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, \n      Math.floor), e;\n      return function(d) {\n        return d / pow(f(log(d) + e)) <= k ? format(d) : \"\";\n      };\n    };\n    scale.copy = function() {\n      return d3_scale_log(linear.copy(), base, positive, domain);\n    };\n    return d3_scale_linearRebind(scale, linear);\n  }\n  var d3_scale_logFormat = d3.format(\".0e\"), d3_scale_logNiceNegative = {\n    floor: function(x) {\n      return -Math.ceil(-x);\n    },\n    ceil: function(x) {\n      return -Math.floor(-x);\n    }\n  };\n  d3.scale.pow = function() {\n    return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]);\n  };\n  function d3_scale_pow(linear, exponent, domain) {\n    var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);\n    function scale(x) {\n      return linear(powp(x));\n    }\n    scale.invert = function(x) {\n      return powb(linear.invert(x));\n    };\n    scale.domain = function(x) {\n      if (!arguments.length) return domain;\n      linear.domain((domain = x.map(Number)).map(powp));\n      return scale;\n    };\n    scale.ticks = function(m) {\n      return d3_scale_linearTicks(domain, m);\n    };\n    scale.tickFormat = function(m, format) {\n      return d3_scale_linearTickFormat(domain, m, format);\n    };\n    scale.nice = function(m) {\n      return scale.domain(d3_scale_linearNice(domain, m));\n    };\n    scale.exponent = function(x) {\n      if (!arguments.length) return exponent;\n      powp = d3_scale_powPow(exponent = x);\n      powb = d3_scale_powPow(1 / exponent);\n      linear.domain(domain.map(powp));\n      return scale;\n    };\n    scale.copy = function() {\n      return d3_scale_pow(linear.copy(), exponent, domain);\n    };\n    return d3_scale_linearRebind(scale, linear);\n  }\n  function d3_scale_powPow(e) {\n    return function(x) {\n      return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);\n    };\n  }\n  d3.scale.sqrt = function() {\n    return d3.scale.pow().exponent(.5);\n  };\n  d3.scale.ordinal = function() {\n    return d3_scale_ordinal([], {\n      t: \"range\",\n      a: [ [] ]\n    });\n  };\n  function d3_scale_ordinal(domain, ranger) {\n    var index, range, rangeBand;\n    function scale(x) {\n      return range[((index.get(x) || (ranger.t === \"range\" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length];\n    }\n    function steps(start, step) {\n      return d3.range(domain.length).map(function(i) {\n        return start + step * i;\n      });\n    }\n    scale.domain = function(x) {\n      if (!arguments.length) return domain;\n      domain = [];\n      index = new d3_Map();\n      var i = -1, n = x.length, xi;\n      while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));\n      return scale[ranger.t].apply(scale, ranger.a);\n    };\n    scale.range = function(x) {\n      if (!arguments.length) return range;\n      range = x;\n      rangeBand = 0;\n      ranger = {\n        t: \"range\",\n        a: arguments\n      };\n      return scale;\n    };\n    scale.rangePoints = function(x, padding) {\n      if (arguments.length < 2) padding = 0;\n      var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, \n      0) : (stop - start) / (domain.length - 1 + padding);\n      range = steps(start + step * padding / 2, step);\n      rangeBand = 0;\n      ranger = {\n        t: \"rangePoints\",\n        a: arguments\n      };\n      return scale;\n    };\n    scale.rangeRoundPoints = function(x, padding) {\n      if (arguments.length < 2) padding = 0;\n      var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), \n      0) : (stop - start) / (domain.length - 1 + padding) | 0;\n      range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step);\n      rangeBand = 0;\n      ranger = {\n        t: \"rangeRoundPoints\",\n        a: arguments\n      };\n      return scale;\n    };\n    scale.rangeBands = function(x, padding, outerPadding) {\n      if (arguments.length < 2) padding = 0;\n      if (arguments.length < 3) outerPadding = padding;\n      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);\n      range = steps(start + step * outerPadding, step);\n      if (reverse) range.reverse();\n      rangeBand = step * (1 - padding);\n      ranger = {\n        t: \"rangeBands\",\n        a: arguments\n      };\n      return scale;\n    };\n    scale.rangeRoundBands = function(x, padding, outerPadding) {\n      if (arguments.length < 2) padding = 0;\n      if (arguments.length < 3) outerPadding = padding;\n      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding));\n      range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step);\n      if (reverse) range.reverse();\n      rangeBand = Math.round(step * (1 - padding));\n      ranger = {\n        t: \"rangeRoundBands\",\n        a: arguments\n      };\n      return scale;\n    };\n    scale.rangeBand = function() {\n      return rangeBand;\n    };\n    scale.rangeExtent = function() {\n      return d3_scaleExtent(ranger.a[0]);\n    };\n    scale.copy = function() {\n      return d3_scale_ordinal(domain, ranger);\n    };\n    return scale.domain(domain);\n  }\n  d3.scale.category10 = function() {\n    return d3.scale.ordinal().range(d3_category10);\n  };\n  d3.scale.category20 = function() {\n    return d3.scale.ordinal().range(d3_category20);\n  };\n  d3.scale.category20b = function() {\n    return d3.scale.ordinal().range(d3_category20b);\n  };\n  d3.scale.category20c = function() {\n    return d3.scale.ordinal().range(d3_category20c);\n  };\n  var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString);\n  var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString);\n  var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString);\n  var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString);\n  d3.scale.quantile = function() {\n    return d3_scale_quantile([], []);\n  };\n  function d3_scale_quantile(domain, range) {\n    var thresholds;\n    function rescale() {\n      var k = 0, q = range.length;\n      thresholds = [];\n      while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);\n      return scale;\n    }\n    function scale(x) {\n      if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)];\n    }\n    scale.domain = function(x) {\n      if (!arguments.length) return domain;\n      domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending);\n      return rescale();\n    };\n    scale.range = function(x) {\n      if (!arguments.length) return range;\n      range = x;\n      return rescale();\n    };\n    scale.quantiles = function() {\n      return thresholds;\n    };\n    scale.invertExtent = function(y) {\n      y = range.indexOf(y);\n      return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ];\n    };\n    scale.copy = function() {\n      return d3_scale_quantile(domain, range);\n    };\n    return rescale();\n  }\n  d3.scale.quantize = function() {\n    return d3_scale_quantize(0, 1, [ 0, 1 ]);\n  };\n  function d3_scale_quantize(x0, x1, range) {\n    var kx, i;\n    function scale(x) {\n      return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];\n    }\n    function rescale() {\n      kx = range.length / (x1 - x0);\n      i = range.length - 1;\n      return scale;\n    }\n    scale.domain = function(x) {\n      if (!arguments.length) return [ x0, x1 ];\n      x0 = +x[0];\n      x1 = +x[x.length - 1];\n      return rescale();\n    };\n    scale.range = function(x) {\n      if (!arguments.length) return range;\n      range = x;\n      return rescale();\n    };\n    scale.invertExtent = function(y) {\n      y = range.indexOf(y);\n      y = y < 0 ? NaN : y / kx + x0;\n      return [ y, y + 1 / kx ];\n    };\n    scale.copy = function() {\n      return d3_scale_quantize(x0, x1, range);\n    };\n    return rescale();\n  }\n  d3.scale.threshold = function() {\n    return d3_scale_threshold([ .5 ], [ 0, 1 ]);\n  };\n  function d3_scale_threshold(domain, range) {\n    function scale(x) {\n      if (x <= x) return range[d3.bisect(domain, x)];\n    }\n    scale.domain = function(_) {\n      if (!arguments.length) return domain;\n      domain = _;\n      return scale;\n    };\n    scale.range = function(_) {\n      if (!arguments.length) return range;\n      range = _;\n      return scale;\n    };\n    scale.invertExtent = function(y) {\n      y = range.indexOf(y);\n      return [ domain[y - 1], domain[y] ];\n    };\n    scale.copy = function() {\n      return d3_scale_threshold(domain, range);\n    };\n    return scale;\n  }\n  d3.scale.identity = function() {\n    return d3_scale_identity([ 0, 1 ]);\n  };\n  function d3_scale_identity(domain) {\n    function identity(x) {\n      return +x;\n    }\n    identity.invert = identity;\n    identity.domain = identity.range = function(x) {\n      if (!arguments.length) return domain;\n      domain = x.map(identity);\n      return identity;\n    };\n    identity.ticks = function(m) {\n      return d3_scale_linearTicks(domain, m);\n    };\n    identity.tickFormat = function(m, format) {\n      return d3_scale_linearTickFormat(domain, m, format);\n    };\n    identity.copy = function() {\n      return d3_scale_identity(domain);\n    };\n    return identity;\n  }\n  d3.svg = {};\n  function d3_zero() {\n    return 0;\n  }\n  d3.svg.arc = function() {\n    var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle;\n    function arc() {\n      var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1;\n      if (r1 < r0) rc = r1, r1 = r0, r0 = rc;\n      if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : \"\") + \"Z\";\n      var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = [];\n      if (ap = (+padAngle.apply(this, arguments) || 0) / 2) {\n        rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments);\n        if (!cw) p1 *= -1;\n        if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap));\n        if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap));\n      }\n      if (r1) {\n        x0 = r1 * Math.cos(a0 + p1);\n        y0 = r1 * Math.sin(a0 + p1);\n        x1 = r1 * Math.cos(a1 - p1);\n        y1 = r1 * Math.sin(a1 - p1);\n        var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1;\n        if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) {\n          var h1 = (a0 + a1) / 2;\n          x0 = r1 * Math.cos(h1);\n          y0 = r1 * Math.sin(h1);\n          x1 = y1 = null;\n        }\n      } else {\n        x0 = y0 = 0;\n      }\n      if (r0) {\n        x2 = r0 * Math.cos(a1 - p0);\n        y2 = r0 * Math.sin(a1 - p0);\n        x3 = r0 * Math.cos(a0 + p0);\n        y3 = r0 * Math.sin(a0 + p0);\n        var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1;\n        if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) {\n          var h0 = (a0 + a1) / 2;\n          x2 = r0 * Math.cos(h0);\n          y2 = r0 * Math.sin(h0);\n          x3 = y3 = null;\n        }\n      } else {\n        x2 = y2 = 0;\n      }\n      if (da > ε && (rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) {\n        cr = r0 < r1 ^ cw ? 0 : 1;\n        var rc1 = rc, rc0 = rc;\n        if (da < π) {\n          var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n          rc0 = Math.min(rc, (r0 - lc) / (kc - 1));\n          rc1 = Math.min(rc, (r1 - lc) / (kc + 1));\n        }\n        if (x1 != null) {\n          var t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw);\n          if (rc === rc1) {\n            path.push(\"M\", t30[0], \"A\", rc1, \",\", rc1, \" 0 0,\", cr, \" \", t30[1], \"A\", r1, \",\", r1, \" 0 \", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), \",\", cw, \" \", t12[1], \"A\", rc1, \",\", rc1, \" 0 0,\", cr, \" \", t12[0]);\n          } else {\n            path.push(\"M\", t30[0], \"A\", rc1, \",\", rc1, \" 0 1,\", cr, \" \", t12[0]);\n          }\n        } else {\n          path.push(\"M\", x0, \",\", y0);\n        }\n        if (x3 != null) {\n          var t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw);\n          if (rc === rc0) {\n            path.push(\"L\", t21[0], \"A\", rc0, \",\", rc0, \" 0 0,\", cr, \" \", t21[1], \"A\", r0, \",\", r0, \" 0 \", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), \",\", 1 - cw, \" \", t03[1], \"A\", rc0, \",\", rc0, \" 0 0,\", cr, \" \", t03[0]);\n          } else {\n            path.push(\"L\", t21[0], \"A\", rc0, \",\", rc0, \" 0 0,\", cr, \" \", t03[0]);\n          }\n        } else {\n          path.push(\"L\", x2, \",\", y2);\n        }\n      } else {\n        path.push(\"M\", x0, \",\", y0);\n        if (x1 != null) path.push(\"A\", r1, \",\", r1, \" 0 \", l1, \",\", cw, \" \", x1, \",\", y1);\n        path.push(\"L\", x2, \",\", y2);\n        if (x3 != null) path.push(\"A\", r0, \",\", r0, \" 0 \", l0, \",\", 1 - cw, \" \", x3, \",\", y3);\n      }\n      path.push(\"Z\");\n      return path.join(\"\");\n    }\n    function circleSegment(r1, cw) {\n      return \"M0,\" + r1 + \"A\" + r1 + \",\" + r1 + \" 0 1,\" + cw + \" 0,\" + -r1 + \"A\" + r1 + \",\" + r1 + \" 0 1,\" + cw + \" 0,\" + r1;\n    }\n    arc.innerRadius = function(v) {\n      if (!arguments.length) return innerRadius;\n      innerRadius = d3_functor(v);\n      return arc;\n    };\n    arc.outerRadius = function(v) {\n      if (!arguments.length) return outerRadius;\n      outerRadius = d3_functor(v);\n      return arc;\n    };\n    arc.cornerRadius = function(v) {\n      if (!arguments.length) return cornerRadius;\n      cornerRadius = d3_functor(v);\n      return arc;\n    };\n    arc.padRadius = function(v) {\n      if (!arguments.length) return padRadius;\n      padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v);\n      return arc;\n    };\n    arc.startAngle = function(v) {\n      if (!arguments.length) return startAngle;\n      startAngle = d3_functor(v);\n      return arc;\n    };\n    arc.endAngle = function(v) {\n      if (!arguments.length) return endAngle;\n      endAngle = d3_functor(v);\n      return arc;\n    };\n    arc.padAngle = function(v) {\n      if (!arguments.length) return padAngle;\n      padAngle = d3_functor(v);\n      return arc;\n    };\n    arc.centroid = function() {\n      var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ;\n      return [ Math.cos(a) * r, Math.sin(a) * r ];\n    };\n    return arc;\n  };\n  var d3_svg_arcAuto = \"auto\";\n  function d3_svg_arcInnerRadius(d) {\n    return d.innerRadius;\n  }\n  function d3_svg_arcOuterRadius(d) {\n    return d.outerRadius;\n  }\n  function d3_svg_arcStartAngle(d) {\n    return d.startAngle;\n  }\n  function d3_svg_arcEndAngle(d) {\n    return d.endAngle;\n  }\n  function d3_svg_arcPadAngle(d) {\n    return d && d.padAngle;\n  }\n  function d3_svg_arcSweep(x0, y0, x1, y1) {\n    return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1;\n  }\n  function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) {\n    var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3;\n    if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n    return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ];\n  }\n  function d3_svg_line(projection) {\n    var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;\n    function line(data) {\n      var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);\n      function segment() {\n        segments.push(\"M\", interpolate(projection(points), tension));\n      }\n      while (++i < n) {\n        if (defined.call(this, d = data[i], i)) {\n          points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);\n        } else if (points.length) {\n          segment();\n          points = [];\n        }\n      }\n      if (points.length) segment();\n      return segments.length ? segments.join(\"\") : null;\n    }\n    line.x = function(_) {\n      if (!arguments.length) return x;\n      x = _;\n      return line;\n    };\n    line.y = function(_) {\n      if (!arguments.length) return y;\n      y = _;\n      return line;\n    };\n    line.defined = function(_) {\n      if (!arguments.length) return defined;\n      defined = _;\n      return line;\n    };\n    line.interpolate = function(_) {\n      if (!arguments.length) return interpolateKey;\n      if (typeof _ === \"function\") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;\n      return line;\n    };\n    line.tension = function(_) {\n      if (!arguments.length) return tension;\n      tension = _;\n      return line;\n    };\n    return line;\n  }\n  d3.svg.line = function() {\n    return d3_svg_line(d3_identity);\n  };\n  var d3_svg_lineInterpolators = d3.map({\n    linear: d3_svg_lineLinear,\n    \"linear-closed\": d3_svg_lineLinearClosed,\n    step: d3_svg_lineStep,\n    \"step-before\": d3_svg_lineStepBefore,\n    \"step-after\": d3_svg_lineStepAfter,\n    basis: d3_svg_lineBasis,\n    \"basis-open\": d3_svg_lineBasisOpen,\n    \"basis-closed\": d3_svg_lineBasisClosed,\n    bundle: d3_svg_lineBundle,\n    cardinal: d3_svg_lineCardinal,\n    \"cardinal-open\": d3_svg_lineCardinalOpen,\n    \"cardinal-closed\": d3_svg_lineCardinalClosed,\n    monotone: d3_svg_lineMonotone\n  });\n  d3_svg_lineInterpolators.forEach(function(key, value) {\n    value.key = key;\n    value.closed = /-closed$/.test(key);\n  });\n  function d3_svg_lineLinear(points) {\n    return points.length > 1 ? points.join(\"L\") : points + \"Z\";\n  }\n  function d3_svg_lineLinearClosed(points) {\n    return points.join(\"L\") + \"Z\";\n  }\n  function d3_svg_lineStep(points) {\n    var i = 0, n = points.length, p = points[0], path = [ p[0], \",\", p[1] ];\n    while (++i < n) path.push(\"H\", (p[0] + (p = points[i])[0]) / 2, \"V\", p[1]);\n    if (n > 1) path.push(\"H\", p[0]);\n    return path.join(\"\");\n  }\n  function d3_svg_lineStepBefore(points) {\n    var i = 0, n = points.length, p = points[0], path = [ p[0], \",\", p[1] ];\n    while (++i < n) path.push(\"V\", (p = points[i])[1], \"H\", p[0]);\n    return path.join(\"\");\n  }\n  function d3_svg_lineStepAfter(points) {\n    var i = 0, n = points.length, p = points[0], path = [ p[0], \",\", p[1] ];\n    while (++i < n) path.push(\"H\", (p = points[i])[0], \"V\", p[1]);\n    return path.join(\"\");\n  }\n  function d3_svg_lineCardinalOpen(points, tension) {\n    return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension));\n  }\n  function d3_svg_lineCardinalClosed(points, tension) {\n    return points.length < 3 ? d3_svg_lineLinearClosed(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), \n    points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));\n  }\n  function d3_svg_lineCardinal(points, tension) {\n    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));\n  }\n  function d3_svg_lineHermite(points, tangents) {\n    if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {\n      return d3_svg_lineLinear(points);\n    }\n    var quad = points.length != tangents.length, path = \"\", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;\n    if (quad) {\n      path += \"Q\" + (p[0] - t0[0] * 2 / 3) + \",\" + (p[1] - t0[1] * 2 / 3) + \",\" + p[0] + \",\" + p[1];\n      p0 = points[1];\n      pi = 2;\n    }\n    if (tangents.length > 1) {\n      t = tangents[1];\n      p = points[pi];\n      pi++;\n      path += \"C\" + (p0[0] + t0[0]) + \",\" + (p0[1] + t0[1]) + \",\" + (p[0] - t[0]) + \",\" + (p[1] - t[1]) + \",\" + p[0] + \",\" + p[1];\n      for (var i = 2; i < tangents.length; i++, pi++) {\n        p = points[pi];\n        t = tangents[i];\n        path += \"S\" + (p[0] - t[0]) + \",\" + (p[1] - t[1]) + \",\" + p[0] + \",\" + p[1];\n      }\n    }\n    if (quad) {\n      var lp = points[pi];\n      path += \"Q\" + (p[0] + t[0] * 2 / 3) + \",\" + (p[1] + t[1] * 2 / 3) + \",\" + lp[0] + \",\" + lp[1];\n    }\n    return path;\n  }\n  function d3_svg_lineCardinalTangents(points, tension) {\n    var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;\n    while (++i < n) {\n      p0 = p1;\n      p1 = p2;\n      p2 = points[i];\n      tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);\n    }\n    return tangents;\n  }\n  function d3_svg_lineBasis(points) {\n    if (points.length < 3) return d3_svg_lineLinear(points);\n    var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, \",\", y0, \"L\", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];\n    points.push(points[n - 1]);\n    while (++i <= n) {\n      pi = points[i];\n      px.shift();\n      px.push(pi[0]);\n      py.shift();\n      py.push(pi[1]);\n      d3_svg_lineBasisBezier(path, px, py);\n    }\n    points.pop();\n    path.push(\"L\", pi);\n    return path.join(\"\");\n  }\n  function d3_svg_lineBasisOpen(points) {\n    if (points.length < 4) return d3_svg_lineLinear(points);\n    var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ];\n    while (++i < 3) {\n      pi = points[i];\n      px.push(pi[0]);\n      py.push(pi[1]);\n    }\n    path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + \",\" + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));\n    --i;\n    while (++i < n) {\n      pi = points[i];\n      px.shift();\n      px.push(pi[0]);\n      py.shift();\n      py.push(pi[1]);\n      d3_svg_lineBasisBezier(path, px, py);\n    }\n    return path.join(\"\");\n  }\n  function d3_svg_lineBasisClosed(points) {\n    var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = [];\n    while (++i < 4) {\n      pi = points[i % n];\n      px.push(pi[0]);\n      py.push(pi[1]);\n    }\n    path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];\n    --i;\n    while (++i < m) {\n      pi = points[i % n];\n      px.shift();\n      px.push(pi[0]);\n      py.shift();\n      py.push(pi[1]);\n      d3_svg_lineBasisBezier(path, px, py);\n    }\n    return path.join(\"\");\n  }\n  function d3_svg_lineBundle(points, tension) {\n    var n = points.length - 1;\n    if (n) {\n      var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t;\n      while (++i <= n) {\n        p = points[i];\n        t = i / n;\n        p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);\n        p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);\n      }\n    }\n    return d3_svg_lineBasis(points);\n  }\n  function d3_svg_lineDot4(a, b) {\n    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];\n  }\n  var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ];\n  function d3_svg_lineBasisBezier(path, x, y) {\n    path.push(\"C\", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), \",\", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));\n  }\n  function d3_svg_lineSlope(p0, p1) {\n    return (p1[1] - p0[1]) / (p1[0] - p0[0]);\n  }\n  function d3_svg_lineFiniteDifferences(points) {\n    var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1);\n    while (++i < j) {\n      m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2;\n    }\n    m[i] = d;\n    return m;\n  }\n  function d3_svg_lineMonotoneTangents(points) {\n    var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1;\n    while (++i < j) {\n      d = d3_svg_lineSlope(points[i], points[i + 1]);\n      if (abs(d) < ε) {\n        m[i] = m[i + 1] = 0;\n      } else {\n        a = m[i] / d;\n        b = m[i + 1] / d;\n        s = a * a + b * b;\n        if (s > 9) {\n          s = d * 3 / Math.sqrt(s);\n          m[i] = s * a;\n          m[i + 1] = s * b;\n        }\n      }\n    }\n    i = -1;\n    while (++i <= j) {\n      s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));\n      tangents.push([ s || 0, m[i] * s || 0 ]);\n    }\n    return tangents;\n  }\n  function d3_svg_lineMonotone(points) {\n    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));\n  }\n  d3.svg.line.radial = function() {\n    var line = d3_svg_line(d3_svg_lineRadial);\n    line.radius = line.x, delete line.x;\n    line.angle = line.y, delete line.y;\n    return line;\n  };\n  function d3_svg_lineRadial(points) {\n    var point, i = -1, n = points.length, r, a;\n    while (++i < n) {\n      point = points[i];\n      r = point[0];\n      a = point[1] - halfπ;\n      point[0] = r * Math.cos(a);\n      point[1] = r * Math.sin(a);\n    }\n    return points;\n  }\n  function d3_svg_area(projection) {\n    var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = \"L\", tension = .7;\n    function area(data) {\n      var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() {\n        return x;\n      } : d3_functor(x1), fy1 = y0 === y1 ? function() {\n        return y;\n      } : d3_functor(y1), x, y;\n      function segment() {\n        segments.push(\"M\", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), \"Z\");\n      }\n      while (++i < n) {\n        if (defined.call(this, d = data[i], i)) {\n          points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]);\n          points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]);\n        } else if (points0.length) {\n          segment();\n          points0 = [];\n          points1 = [];\n        }\n      }\n      if (points0.length) segment();\n      return segments.length ? segments.join(\"\") : null;\n    }\n    area.x = function(_) {\n      if (!arguments.length) return x1;\n      x0 = x1 = _;\n      return area;\n    };\n    area.x0 = function(_) {\n      if (!arguments.length) return x0;\n      x0 = _;\n      return area;\n    };\n    area.x1 = function(_) {\n      if (!arguments.length) return x1;\n      x1 = _;\n      return area;\n    };\n    area.y = function(_) {\n      if (!arguments.length) return y1;\n      y0 = y1 = _;\n      return area;\n    };\n    area.y0 = function(_) {\n      if (!arguments.length) return y0;\n      y0 = _;\n      return area;\n    };\n    area.y1 = function(_) {\n      if (!arguments.length) return y1;\n      y1 = _;\n      return area;\n    };\n    area.defined = function(_) {\n      if (!arguments.length) return defined;\n      defined = _;\n      return area;\n    };\n    area.interpolate = function(_) {\n      if (!arguments.length) return interpolateKey;\n      if (typeof _ === \"function\") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;\n      interpolateReverse = interpolate.reverse || interpolate;\n      L = interpolate.closed ? \"M\" : \"L\";\n      return area;\n    };\n    area.tension = function(_) {\n      if (!arguments.length) return tension;\n      tension = _;\n      return area;\n    };\n    return area;\n  }\n  d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;\n  d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;\n  d3.svg.area = function() {\n    return d3_svg_area(d3_identity);\n  };\n  d3.svg.area.radial = function() {\n    var area = d3_svg_area(d3_svg_lineRadial);\n    area.radius = area.x, delete area.x;\n    area.innerRadius = area.x0, delete area.x0;\n    area.outerRadius = area.x1, delete area.x1;\n    area.angle = area.y, delete area.y;\n    area.startAngle = area.y0, delete area.y0;\n    area.endAngle = area.y1, delete area.y1;\n    return area;\n  };\n  d3.svg.chord = function() {\n    var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle;\n    function chord(d, i) {\n      var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i);\n      return \"M\" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + \"Z\";\n    }\n    function subgroup(self, f, d, i) {\n      var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ;\n      return {\n        r: r,\n        a0: a0,\n        a1: a1,\n        p0: [ r * Math.cos(a0), r * Math.sin(a0) ],\n        p1: [ r * Math.cos(a1), r * Math.sin(a1) ]\n      };\n    }\n    function equals(a, b) {\n      return a.a0 == b.a0 && a.a1 == b.a1;\n    }\n    function arc(r, p, a) {\n      return \"A\" + r + \",\" + r + \" 0 \" + +(a > π) + \",1 \" + p;\n    }\n    function curve(r0, p0, r1, p1) {\n      return \"Q 0,0 \" + p1;\n    }\n    chord.radius = function(v) {\n      if (!arguments.length) return radius;\n      radius = d3_functor(v);\n      return chord;\n    };\n    chord.source = function(v) {\n      if (!arguments.length) return source;\n      source = d3_functor(v);\n      return chord;\n    };\n    chord.target = function(v) {\n      if (!arguments.length) return target;\n      target = d3_functor(v);\n      return chord;\n    };\n    chord.startAngle = function(v) {\n      if (!arguments.length) return startAngle;\n      startAngle = d3_functor(v);\n      return chord;\n    };\n    chord.endAngle = function(v) {\n      if (!arguments.length) return endAngle;\n      endAngle = d3_functor(v);\n      return chord;\n    };\n    return chord;\n  };\n  function d3_svg_chordRadius(d) {\n    return d.radius;\n  }\n  d3.svg.diagonal = function() {\n    var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection;\n    function diagonal(d, i) {\n      var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {\n        x: p0.x,\n        y: m\n      }, {\n        x: p3.x,\n        y: m\n      }, p3 ];\n      p = p.map(projection);\n      return \"M\" + p[0] + \"C\" + p[1] + \" \" + p[2] + \" \" + p[3];\n    }\n    diagonal.source = function(x) {\n      if (!arguments.length) return source;\n      source = d3_functor(x);\n      return diagonal;\n    };\n    diagonal.target = function(x) {\n      if (!arguments.length) return target;\n      target = d3_functor(x);\n      return diagonal;\n    };\n    diagonal.projection = function(x) {\n      if (!arguments.length) return projection;\n      projection = x;\n      return diagonal;\n    };\n    return diagonal;\n  };\n  function d3_svg_diagonalProjection(d) {\n    return [ d.x, d.y ];\n  }\n  d3.svg.diagonal.radial = function() {\n    var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection;\n    diagonal.projection = function(x) {\n      return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection;\n    };\n    return diagonal;\n  };\n  function d3_svg_diagonalRadialProjection(projection) {\n    return function() {\n      var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ;\n      return [ r * Math.cos(a), r * Math.sin(a) ];\n    };\n  }\n  d3.svg.symbol = function() {\n    var type = d3_svg_symbolType, size = d3_svg_symbolSize;\n    function symbol(d, i) {\n      return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i));\n    }\n    symbol.type = function(x) {\n      if (!arguments.length) return type;\n      type = d3_functor(x);\n      return symbol;\n    };\n    symbol.size = function(x) {\n      if (!arguments.length) return size;\n      size = d3_functor(x);\n      return symbol;\n    };\n    return symbol;\n  };\n  function d3_svg_symbolSize() {\n    return 64;\n  }\n  function d3_svg_symbolType() {\n    return \"circle\";\n  }\n  function d3_svg_symbolCircle(size) {\n    var r = Math.sqrt(size / π);\n    return \"M0,\" + r + \"A\" + r + \",\" + r + \" 0 1,1 0,\" + -r + \"A\" + r + \",\" + r + \" 0 1,1 0,\" + r + \"Z\";\n  }\n  var d3_svg_symbols = d3.map({\n    circle: d3_svg_symbolCircle,\n    cross: function(size) {\n      var r = Math.sqrt(size / 5) / 2;\n      return \"M\" + -3 * r + \",\" + -r + \"H\" + -r + \"V\" + -3 * r + \"H\" + r + \"V\" + -r + \"H\" + 3 * r + \"V\" + r + \"H\" + r + \"V\" + 3 * r + \"H\" + -r + \"V\" + r + \"H\" + -3 * r + \"Z\";\n    },\n    diamond: function(size) {\n      var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30;\n      return \"M0,\" + -ry + \"L\" + rx + \",0\" + \" 0,\" + ry + \" \" + -rx + \",0\" + \"Z\";\n    },\n    square: function(size) {\n      var r = Math.sqrt(size) / 2;\n      return \"M\" + -r + \",\" + -r + \"L\" + r + \",\" + -r + \" \" + r + \",\" + r + \" \" + -r + \",\" + r + \"Z\";\n    },\n    \"triangle-down\": function(size) {\n      var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;\n      return \"M0,\" + ry + \"L\" + rx + \",\" + -ry + \" \" + -rx + \",\" + -ry + \"Z\";\n    },\n    \"triangle-up\": function(size) {\n      var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;\n      return \"M0,\" + -ry + \"L\" + rx + \",\" + ry + \" \" + -rx + \",\" + ry + \"Z\";\n    }\n  });\n  d3.svg.symbolTypes = d3_svg_symbols.keys();\n  var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians);\n  d3_selectionPrototype.transition = function(name) {\n    var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || {\n      time: Date.now(),\n      ease: d3_ease_cubicInOut,\n      delay: 0,\n      duration: 250\n    };\n    for (var j = -1, m = this.length; ++j < m; ) {\n      subgroups.push(subgroup = []);\n      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {\n        if (node = group[i]) d3_transitionNode(node, i, ns, id, transition);\n        subgroup.push(node);\n      }\n    }\n    return d3_transition(subgroups, ns, id);\n  };\n  d3_selectionPrototype.interrupt = function(name) {\n    return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name)));\n  };\n  var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace());\n  function d3_selection_interruptNS(ns) {\n    return function() {\n      var lock, activeId, active;\n      if ((lock = this[ns]) && (active = lock[activeId = lock.active])) {\n        active.timer.c = null;\n        active.timer.t = NaN;\n        if (--lock.count) delete lock[activeId]; else delete this[ns];\n        lock.active += .5;\n        active.event && active.event.interrupt.call(this, this.__data__, active.index);\n      }\n    };\n  }\n  function d3_transition(groups, ns, id) {\n    d3_subclass(groups, d3_transitionPrototype);\n    groups.namespace = ns;\n    groups.id = id;\n    return groups;\n  }\n  var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit;\n  d3_transitionPrototype.call = d3_selectionPrototype.call;\n  d3_transitionPrototype.empty = d3_selectionPrototype.empty;\n  d3_transitionPrototype.node = d3_selectionPrototype.node;\n  d3_transitionPrototype.size = d3_selectionPrototype.size;\n  d3.transition = function(selection, name) {\n    return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection);\n  };\n  d3.transition.prototype = d3_transitionPrototype;\n  d3_transitionPrototype.select = function(selector) {\n    var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node;\n    selector = d3_selection_selector(selector);\n    for (var j = -1, m = this.length; ++j < m; ) {\n      subgroups.push(subgroup = []);\n      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {\n        if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) {\n          if (\"__data__\" in node) subnode.__data__ = node.__data__;\n          d3_transitionNode(subnode, i, ns, id, node[ns][id]);\n          subgroup.push(subnode);\n        } else {\n          subgroup.push(null);\n        }\n      }\n    }\n    return d3_transition(subgroups, ns, id);\n  };\n  d3_transitionPrototype.selectAll = function(selector) {\n    var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition;\n    selector = d3_selection_selectorAll(selector);\n    for (var j = -1, m = this.length; ++j < m; ) {\n      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {\n        if (node = group[i]) {\n          transition = node[ns][id];\n          subnodes = selector.call(node, node.__data__, i, j);\n          subgroups.push(subgroup = []);\n          for (var k = -1, o = subnodes.length; ++k < o; ) {\n            if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition);\n            subgroup.push(subnode);\n          }\n        }\n      }\n    }\n    return d3_transition(subgroups, ns, id);\n  };\n  d3_transitionPrototype.filter = function(filter) {\n    var subgroups = [], subgroup, group, node;\n    if (typeof filter !== \"function\") filter = d3_selection_filter(filter);\n    for (var j = 0, m = this.length; j < m; j++) {\n      subgroups.push(subgroup = []);\n      for (var group = this[j], i = 0, n = group.length; i < n; i++) {\n        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {\n          subgroup.push(node);\n        }\n      }\n    }\n    return d3_transition(subgroups, this.namespace, this.id);\n  };\n  d3_transitionPrototype.tween = function(name, tween) {\n    var id = this.id, ns = this.namespace;\n    if (arguments.length < 2) return this.node()[ns][id].tween.get(name);\n    return d3_selection_each(this, tween == null ? function(node) {\n      node[ns][id].tween.remove(name);\n    } : function(node) {\n      node[ns][id].tween.set(name, tween);\n    });\n  };\n  function d3_transition_tween(groups, name, value, tween) {\n    var id = groups.id, ns = groups.namespace;\n    return d3_selection_each(groups, typeof value === \"function\" ? function(node, i, j) {\n      node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j)));\n    } : (value = tween(value), function(node) {\n      node[ns][id].tween.set(name, value);\n    }));\n  }\n  d3_transitionPrototype.attr = function(nameNS, value) {\n    if (arguments.length < 2) {\n      for (value in nameNS) this.attr(value, nameNS[value]);\n      return this;\n    }\n    var interpolate = nameNS == \"transform\" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);\n    function attrNull() {\n      this.removeAttribute(name);\n    }\n    function attrNullNS() {\n      this.removeAttributeNS(name.space, name.local);\n    }\n    function attrTween(b) {\n      return b == null ? attrNull : (b += \"\", function() {\n        var a = this.getAttribute(name), i;\n        return a !== b && (i = interpolate(a, b), function(t) {\n          this.setAttribute(name, i(t));\n        });\n      });\n    }\n    function attrTweenNS(b) {\n      return b == null ? attrNullNS : (b += \"\", function() {\n        var a = this.getAttributeNS(name.space, name.local), i;\n        return a !== b && (i = interpolate(a, b), function(t) {\n          this.setAttributeNS(name.space, name.local, i(t));\n        });\n      });\n    }\n    return d3_transition_tween(this, \"attr.\" + nameNS, value, name.local ? attrTweenNS : attrTween);\n  };\n  d3_transitionPrototype.attrTween = function(nameNS, tween) {\n    var name = d3.ns.qualify(nameNS);\n    function attrTween(d, i) {\n      var f = tween.call(this, d, i, this.getAttribute(name));\n      return f && function(t) {\n        this.setAttribute(name, f(t));\n      };\n    }\n    function attrTweenNS(d, i) {\n      var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));\n      return f && function(t) {\n        this.setAttributeNS(name.space, name.local, f(t));\n      };\n    }\n    return this.tween(\"attr.\" + nameNS, name.local ? attrTweenNS : attrTween);\n  };\n  d3_transitionPrototype.style = function(name, value, priority) {\n    var n = arguments.length;\n    if (n < 3) {\n      if (typeof name !== \"string\") {\n        if (n < 2) value = \"\";\n        for (priority in name) this.style(priority, name[priority], value);\n        return this;\n      }\n      priority = \"\";\n    }\n    function styleNull() {\n      this.style.removeProperty(name);\n    }\n    function styleString(b) {\n      return b == null ? styleNull : (b += \"\", function() {\n        var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i;\n        return a !== b && (i = d3_interpolate(a, b), function(t) {\n          this.style.setProperty(name, i(t), priority);\n        });\n      });\n    }\n    return d3_transition_tween(this, \"style.\" + name, value, styleString);\n  };\n  d3_transitionPrototype.styleTween = function(name, tween, priority) {\n    if (arguments.length < 3) priority = \"\";\n    function styleTween(d, i) {\n      var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name));\n      return f && function(t) {\n        this.style.setProperty(name, f(t), priority);\n      };\n    }\n    return this.tween(\"style.\" + name, styleTween);\n  };\n  d3_transitionPrototype.text = function(value) {\n    return d3_transition_tween(this, \"text\", value, d3_transition_text);\n  };\n  function d3_transition_text(b) {\n    if (b == null) b = \"\";\n    return function() {\n      this.textContent = b;\n    };\n  }\n  d3_transitionPrototype.remove = function() {\n    var ns = this.namespace;\n    return this.each(\"end.transition\", function() {\n      var p;\n      if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this);\n    });\n  };\n  d3_transitionPrototype.ease = function(value) {\n    var id = this.id, ns = this.namespace;\n    if (arguments.length < 1) return this.node()[ns][id].ease;\n    if (typeof value !== \"function\") value = d3.ease.apply(d3, arguments);\n    return d3_selection_each(this, function(node) {\n      node[ns][id].ease = value;\n    });\n  };\n  d3_transitionPrototype.delay = function(value) {\n    var id = this.id, ns = this.namespace;\n    if (arguments.length < 1) return this.node()[ns][id].delay;\n    return d3_selection_each(this, typeof value === \"function\" ? function(node, i, j) {\n      node[ns][id].delay = +value.call(node, node.__data__, i, j);\n    } : (value = +value, function(node) {\n      node[ns][id].delay = value;\n    }));\n  };\n  d3_transitionPrototype.duration = function(value) {\n    var id = this.id, ns = this.namespace;\n    if (arguments.length < 1) return this.node()[ns][id].duration;\n    return d3_selection_each(this, typeof value === \"function\" ? function(node, i, j) {\n      node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j));\n    } : (value = Math.max(1, value), function(node) {\n      node[ns][id].duration = value;\n    }));\n  };\n  d3_transitionPrototype.each = function(type, listener) {\n    var id = this.id, ns = this.namespace;\n    if (arguments.length < 2) {\n      var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId;\n      try {\n        d3_transitionInheritId = id;\n        d3_selection_each(this, function(node, i, j) {\n          d3_transitionInherit = node[ns][id];\n          type.call(node, node.__data__, i, j);\n        });\n      } finally {\n        d3_transitionInherit = inherit;\n        d3_transitionInheritId = inheritId;\n      }\n    } else {\n      d3_selection_each(this, function(node) {\n        var transition = node[ns][id];\n        (transition.event || (transition.event = d3.dispatch(\"start\", \"end\", \"interrupt\"))).on(type, listener);\n      });\n    }\n    return this;\n  };\n  d3_transitionPrototype.transition = function() {\n    var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition;\n    for (var j = 0, m = this.length; j < m; j++) {\n      subgroups.push(subgroup = []);\n      for (var group = this[j], i = 0, n = group.length; i < n; i++) {\n        if (node = group[i]) {\n          transition = node[ns][id0];\n          d3_transitionNode(node, i, ns, id1, {\n            time: transition.time,\n            ease: transition.ease,\n            delay: transition.delay + transition.duration,\n            duration: transition.duration\n          });\n        }\n        subgroup.push(node);\n      }\n    }\n    return d3_transition(subgroups, ns, id1);\n  };\n  function d3_transitionNamespace(name) {\n    return name == null ? \"__transition__\" : \"__transition_\" + name + \"__\";\n  }\n  function d3_transitionNode(node, i, ns, id, inherit) {\n    var lock = node[ns] || (node[ns] = {\n      active: 0,\n      count: 0\n    }), transition = lock[id], time, timer, duration, ease, tweens;\n    function schedule(elapsed) {\n      var delay = transition.delay;\n      timer.t = delay + time;\n      if (delay <= elapsed) return start(elapsed - delay);\n      timer.c = start;\n    }\n    function start(elapsed) {\n      var activeId = lock.active, active = lock[activeId];\n      if (active) {\n        active.timer.c = null;\n        active.timer.t = NaN;\n        --lock.count;\n        delete lock[activeId];\n        active.event && active.event.interrupt.call(node, node.__data__, active.index);\n      }\n      for (var cancelId in lock) {\n        if (+cancelId < id) {\n          var cancel = lock[cancelId];\n          cancel.timer.c = null;\n          cancel.timer.t = NaN;\n          --lock.count;\n          delete lock[cancelId];\n        }\n      }\n      timer.c = tick;\n      d3_timer(function() {\n        if (timer.c && tick(elapsed || 1)) {\n          timer.c = null;\n          timer.t = NaN;\n        }\n        return 1;\n      }, 0, time);\n      lock.active = id;\n      transition.event && transition.event.start.call(node, node.__data__, i);\n      tweens = [];\n      transition.tween.forEach(function(key, value) {\n        if (value = value.call(node, node.__data__, i)) {\n          tweens.push(value);\n        }\n      });\n      ease = transition.ease;\n      duration = transition.duration;\n    }\n    function tick(elapsed) {\n      var t = elapsed / duration, e = ease(t), n = tweens.length;\n      while (n > 0) {\n        tweens[--n].call(node, e);\n      }\n      if (t >= 1) {\n        transition.event && transition.event.end.call(node, node.__data__, i);\n        if (--lock.count) delete lock[id]; else delete node[ns];\n        return 1;\n      }\n    }\n    if (!transition) {\n      time = inherit.time;\n      timer = d3_timer(schedule, 0, time);\n      transition = lock[id] = {\n        tween: new d3_Map(),\n        time: time,\n        timer: timer,\n        delay: inherit.delay,\n        duration: inherit.duration,\n        ease: inherit.ease,\n        index: i\n      };\n      inherit = null;\n      ++lock.count;\n    }\n  }\n  d3.svg.axis = function() {\n    var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_;\n    function axis(g) {\n      g.each(function() {\n        var g = d3.select(this);\n        var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy();\n        var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(\".tick\").data(ticks, scale1), tickEnter = tick.enter().insert(\"g\", \".domain\").attr(\"class\", \"tick\").style(\"opacity\", ε), tickExit = d3.transition(tick.exit()).style(\"opacity\", ε).remove(), tickUpdate = d3.transition(tick.order()).style(\"opacity\", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform;\n        var range = d3_scaleRange(scale1), path = g.selectAll(\".domain\").data([ 0 ]), pathUpdate = (path.enter().append(\"path\").attr(\"class\", \"domain\"), \n        d3.transition(path));\n        tickEnter.append(\"line\");\n        tickEnter.append(\"text\");\n        var lineEnter = tickEnter.select(\"line\"), lineUpdate = tickUpdate.select(\"line\"), text = tick.select(\"text\").text(tickFormat), textEnter = tickEnter.select(\"text\"), textUpdate = tickUpdate.select(\"text\"), sign = orient === \"top\" || orient === \"left\" ? -1 : 1, x1, x2, y1, y2;\n        if (orient === \"bottom\" || orient === \"top\") {\n          tickTransform = d3_svg_axisX, x1 = \"x\", y1 = \"y\", x2 = \"x2\", y2 = \"y2\";\n          text.attr(\"dy\", sign < 0 ? \"0em\" : \".71em\").style(\"text-anchor\", \"middle\");\n          pathUpdate.attr(\"d\", \"M\" + range[0] + \",\" + sign * outerTickSize + \"V0H\" + range[1] + \"V\" + sign * outerTickSize);\n        } else {\n          tickTransform = d3_svg_axisY, x1 = \"y\", y1 = \"x\", x2 = \"y2\", y2 = \"x2\";\n          text.attr(\"dy\", \".32em\").style(\"text-anchor\", sign < 0 ? \"end\" : \"start\");\n          pathUpdate.attr(\"d\", \"M\" + sign * outerTickSize + \",\" + range[0] + \"H0V\" + range[1] + \"H\" + sign * outerTickSize);\n        }\n        lineEnter.attr(y2, sign * innerTickSize);\n        textEnter.attr(y1, sign * tickSpacing);\n        lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize);\n        textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing);\n        if (scale1.rangeBand) {\n          var x = scale1, dx = x.rangeBand() / 2;\n          scale0 = scale1 = function(d) {\n            return x(d) + dx;\n          };\n        } else if (scale0.rangeBand) {\n          scale0 = scale1;\n        } else {\n          tickExit.call(tickTransform, scale1, scale0);\n        }\n        tickEnter.call(tickTransform, scale0, scale1);\n        tickUpdate.call(tickTransform, scale1, scale1);\n      });\n    }\n    axis.scale = function(x) {\n      if (!arguments.length) return scale;\n      scale = x;\n      return axis;\n    };\n    axis.orient = function(x) {\n      if (!arguments.length) return orient;\n      orient = x in d3_svg_axisOrients ? x + \"\" : d3_svg_axisDefaultOrient;\n      return axis;\n    };\n    axis.ticks = function() {\n      if (!arguments.length) return tickArguments_;\n      tickArguments_ = d3_array(arguments);\n      return axis;\n    };\n    axis.tickValues = function(x) {\n      if (!arguments.length) return tickValues;\n      tickValues = x;\n      return axis;\n    };\n    axis.tickFormat = function(x) {\n      if (!arguments.length) return tickFormat_;\n      tickFormat_ = x;\n      return axis;\n    };\n    axis.tickSize = function(x) {\n      var n = arguments.length;\n      if (!n) return innerTickSize;\n      innerTickSize = +x;\n      outerTickSize = +arguments[n - 1];\n      return axis;\n    };\n    axis.innerTickSize = function(x) {\n      if (!arguments.length) return innerTickSize;\n      innerTickSize = +x;\n      return axis;\n    };\n    axis.outerTickSize = function(x) {\n      if (!arguments.length) return outerTickSize;\n      outerTickSize = +x;\n      return axis;\n    };\n    axis.tickPadding = function(x) {\n      if (!arguments.length) return tickPadding;\n      tickPadding = +x;\n      return axis;\n    };\n    axis.tickSubdivide = function() {\n      return arguments.length && axis;\n    };\n    return axis;\n  };\n  var d3_svg_axisDefaultOrient = \"bottom\", d3_svg_axisOrients = {\n    top: 1,\n    right: 1,\n    bottom: 1,\n    left: 1\n  };\n  function d3_svg_axisX(selection, x0, x1) {\n    selection.attr(\"transform\", function(d) {\n      var v0 = x0(d);\n      return \"translate(\" + (isFinite(v0) ? v0 : x1(d)) + \",0)\";\n    });\n  }\n  function d3_svg_axisY(selection, y0, y1) {\n    selection.attr(\"transform\", function(d) {\n      var v0 = y0(d);\n      return \"translate(0,\" + (isFinite(v0) ? v0 : y1(d)) + \")\";\n    });\n  }\n  d3.svg.brush = function() {\n    var event = d3_eventDispatch(brush, \"brushstart\", \"brush\", \"brushend\"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0];\n    function brush(g) {\n      g.each(function() {\n        var g = d3.select(this).style(\"pointer-events\", \"all\").style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\").on(\"mousedown.brush\", brushstart).on(\"touchstart.brush\", brushstart);\n        var background = g.selectAll(\".background\").data([ 0 ]);\n        background.enter().append(\"rect\").attr(\"class\", \"background\").style(\"visibility\", \"hidden\").style(\"cursor\", \"crosshair\");\n        g.selectAll(\".extent\").data([ 0 ]).enter().append(\"rect\").attr(\"class\", \"extent\").style(\"cursor\", \"move\");\n        var resize = g.selectAll(\".resize\").data(resizes, d3_identity);\n        resize.exit().remove();\n        resize.enter().append(\"g\").attr(\"class\", function(d) {\n          return \"resize \" + d;\n        }).style(\"cursor\", function(d) {\n          return d3_svg_brushCursor[d];\n        }).append(\"rect\").attr(\"x\", function(d) {\n          return /[ew]$/.test(d) ? -3 : null;\n        }).attr(\"y\", function(d) {\n          return /^[ns]/.test(d) ? -3 : null;\n        }).attr(\"width\", 6).attr(\"height\", 6).style(\"visibility\", \"hidden\");\n        resize.style(\"display\", brush.empty() ? \"none\" : null);\n        var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range;\n        if (x) {\n          range = d3_scaleRange(x);\n          backgroundUpdate.attr(\"x\", range[0]).attr(\"width\", range[1] - range[0]);\n          redrawX(gUpdate);\n        }\n        if (y) {\n          range = d3_scaleRange(y);\n          backgroundUpdate.attr(\"y\", range[0]).attr(\"height\", range[1] - range[0]);\n          redrawY(gUpdate);\n        }\n        redraw(gUpdate);\n      });\n    }\n    brush.event = function(g) {\n      g.each(function() {\n        var event_ = event.of(this, arguments), extent1 = {\n          x: xExtent,\n          y: yExtent,\n          i: xExtentDomain,\n          j: yExtentDomain\n        }, extent0 = this.__chart__ || extent1;\n        this.__chart__ = extent1;\n        if (d3_transitionInheritId) {\n          d3.select(this).transition().each(\"start.brush\", function() {\n            xExtentDomain = extent0.i;\n            yExtentDomain = extent0.j;\n            xExtent = extent0.x;\n            yExtent = extent0.y;\n            event_({\n              type: \"brushstart\"\n            });\n          }).tween(\"brush:brush\", function() {\n            var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y);\n            xExtentDomain = yExtentDomain = null;\n            return function(t) {\n              xExtent = extent1.x = xi(t);\n              yExtent = extent1.y = yi(t);\n              event_({\n                type: \"brush\",\n                mode: \"resize\"\n              });\n            };\n          }).each(\"end.brush\", function() {\n            xExtentDomain = extent1.i;\n            yExtentDomain = extent1.j;\n            event_({\n              type: \"brush\",\n              mode: \"resize\"\n            });\n            event_({\n              type: \"brushend\"\n            });\n          });\n        } else {\n          event_({\n            type: \"brushstart\"\n          });\n          event_({\n            type: \"brush\",\n            mode: \"resize\"\n          });\n          event_({\n            type: \"brushend\"\n          });\n        }\n      });\n    };\n    function redraw(g) {\n      g.selectAll(\".resize\").attr(\"transform\", function(d) {\n        return \"translate(\" + xExtent[+/e$/.test(d)] + \",\" + yExtent[+/^s/.test(d)] + \")\";\n      });\n    }\n    function redrawX(g) {\n      g.select(\".extent\").attr(\"x\", xExtent[0]);\n      g.selectAll(\".extent,.n>rect,.s>rect\").attr(\"width\", xExtent[1] - xExtent[0]);\n    }\n    function redrawY(g) {\n      g.select(\".extent\").attr(\"y\", yExtent[0]);\n      g.selectAll(\".extent,.e>rect,.w>rect\").attr(\"height\", yExtent[1] - yExtent[0]);\n    }\n    function brushstart() {\n      var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed(\"extent\"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset;\n      var w = d3.select(d3_window(target)).on(\"keydown.brush\", keydown).on(\"keyup.brush\", keyup);\n      if (d3.event.changedTouches) {\n        w.on(\"touchmove.brush\", brushmove).on(\"touchend.brush\", brushend);\n      } else {\n        w.on(\"mousemove.brush\", brushmove).on(\"mouseup.brush\", brushend);\n      }\n      g.interrupt().selectAll(\"*\").interrupt();\n      if (dragging) {\n        origin[0] = xExtent[0] - origin[0];\n        origin[1] = yExtent[0] - origin[1];\n      } else if (resizing) {\n        var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing);\n        offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ];\n        origin[0] = xExtent[ex];\n        origin[1] = yExtent[ey];\n      } else if (d3.event.altKey) center = origin.slice();\n      g.style(\"pointer-events\", \"none\").selectAll(\".resize\").style(\"display\", null);\n      d3.select(\"body\").style(\"cursor\", eventTarget.style(\"cursor\"));\n      event_({\n        type: \"brushstart\"\n      });\n      brushmove();\n      function keydown() {\n        if (d3.event.keyCode == 32) {\n          if (!dragging) {\n            center = null;\n            origin[0] -= xExtent[1];\n            origin[1] -= yExtent[1];\n            dragging = 2;\n          }\n          d3_eventPreventDefault();\n        }\n      }\n      function keyup() {\n        if (d3.event.keyCode == 32 && dragging == 2) {\n          origin[0] += xExtent[1];\n          origin[1] += yExtent[1];\n          dragging = 0;\n          d3_eventPreventDefault();\n        }\n      }\n      function brushmove() {\n        var point = d3.mouse(target), moved = false;\n        if (offset) {\n          point[0] += offset[0];\n          point[1] += offset[1];\n        }\n        if (!dragging) {\n          if (d3.event.altKey) {\n            if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ];\n            origin[0] = xExtent[+(point[0] < center[0])];\n            origin[1] = yExtent[+(point[1] < center[1])];\n          } else center = null;\n        }\n        if (resizingX && move1(point, x, 0)) {\n          redrawX(g);\n          moved = true;\n        }\n        if (resizingY && move1(point, y, 1)) {\n          redrawY(g);\n          moved = true;\n        }\n        if (moved) {\n          redraw(g);\n          event_({\n            type: \"brush\",\n            mode: dragging ? \"move\" : \"resize\"\n          });\n        }\n      }\n      function move1(point, scale, i) {\n        var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max;\n        if (dragging) {\n          r0 -= position;\n          r1 -= size + position;\n        }\n        min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i];\n        if (dragging) {\n          max = (min += position) + size;\n        } else {\n          if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min));\n          if (position < min) {\n            max = min;\n            min = position;\n          } else {\n            max = position;\n          }\n        }\n        if (extent[0] != min || extent[1] != max) {\n          if (i) yExtentDomain = null; else xExtentDomain = null;\n          extent[0] = min;\n          extent[1] = max;\n          return true;\n        }\n      }\n      function brushend() {\n        brushmove();\n        g.style(\"pointer-events\", \"all\").selectAll(\".resize\").style(\"display\", brush.empty() ? \"none\" : null);\n        d3.select(\"body\").style(\"cursor\", null);\n        w.on(\"mousemove.brush\", null).on(\"mouseup.brush\", null).on(\"touchmove.brush\", null).on(\"touchend.brush\", null).on(\"keydown.brush\", null).on(\"keyup.brush\", null);\n        dragRestore();\n        event_({\n          type: \"brushend\"\n        });\n      }\n    }\n    brush.x = function(z) {\n      if (!arguments.length) return x;\n      x = z;\n      resizes = d3_svg_brushResizes[!x << 1 | !y];\n      return brush;\n    };\n    brush.y = function(z) {\n      if (!arguments.length) return y;\n      y = z;\n      resizes = d3_svg_brushResizes[!x << 1 | !y];\n      return brush;\n    };\n    brush.clamp = function(z) {\n      if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null;\n      if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z;\n      return brush;\n    };\n    brush.extent = function(z) {\n      var x0, x1, y0, y1, t;\n      if (!arguments.length) {\n        if (x) {\n          if (xExtentDomain) {\n            x0 = xExtentDomain[0], x1 = xExtentDomain[1];\n          } else {\n            x0 = xExtent[0], x1 = xExtent[1];\n            if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1);\n            if (x1 < x0) t = x0, x0 = x1, x1 = t;\n          }\n        }\n        if (y) {\n          if (yExtentDomain) {\n            y0 = yExtentDomain[0], y1 = yExtentDomain[1];\n          } else {\n            y0 = yExtent[0], y1 = yExtent[1];\n            if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1);\n            if (y1 < y0) t = y0, y0 = y1, y1 = t;\n          }\n        }\n        return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ];\n      }\n      if (x) {\n        x0 = z[0], x1 = z[1];\n        if (y) x0 = x0[0], x1 = x1[0];\n        xExtentDomain = [ x0, x1 ];\n        if (x.invert) x0 = x(x0), x1 = x(x1);\n        if (x1 < x0) t = x0, x0 = x1, x1 = t;\n        if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ];\n      }\n      if (y) {\n        y0 = z[0], y1 = z[1];\n        if (x) y0 = y0[1], y1 = y1[1];\n        yExtentDomain = [ y0, y1 ];\n        if (y.invert) y0 = y(y0), y1 = y(y1);\n        if (y1 < y0) t = y0, y0 = y1, y1 = t;\n        if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ];\n      }\n      return brush;\n    };\n    brush.clear = function() {\n      if (!brush.empty()) {\n        xExtent = [ 0, 0 ], yExtent = [ 0, 0 ];\n        xExtentDomain = yExtentDomain = null;\n      }\n      return brush;\n    };\n    brush.empty = function() {\n      return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1];\n    };\n    return d3.rebind(brush, event, \"on\");\n  };\n  var d3_svg_brushCursor = {\n    n: \"ns-resize\",\n    e: \"ew-resize\",\n    s: \"ns-resize\",\n    w: \"ew-resize\",\n    nw: \"nwse-resize\",\n    ne: \"nesw-resize\",\n    se: \"nwse-resize\",\n    sw: \"nesw-resize\"\n  };\n  var d3_svg_brushResizes = [ [ \"n\", \"e\", \"s\", \"w\", \"nw\", \"ne\", \"se\", \"sw\" ], [ \"e\", \"w\" ], [ \"n\", \"s\" ], [] ];\n  var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat;\n  var d3_time_formatUtc = d3_time_format.utc;\n  var d3_time_formatIso = d3_time_formatUtc(\"%Y-%m-%dT%H:%M:%S.%LZ\");\n  d3_time_format.iso = Date.prototype.toISOString && +new Date(\"2000-01-01T00:00:00.000Z\") ? d3_time_formatIsoNative : d3_time_formatIso;\n  function d3_time_formatIsoNative(date) {\n    return date.toISOString();\n  }\n  d3_time_formatIsoNative.parse = function(string) {\n    var date = new Date(string);\n    return isNaN(date) ? null : date;\n  };\n  d3_time_formatIsoNative.toString = d3_time_formatIso.toString;\n  d3_time.second = d3_time_interval(function(date) {\n    return new d3_date(Math.floor(date / 1e3) * 1e3);\n  }, function(date, offset) {\n    date.setTime(date.getTime() + Math.floor(offset) * 1e3);\n  }, function(date) {\n    return date.getSeconds();\n  });\n  d3_time.seconds = d3_time.second.range;\n  d3_time.seconds.utc = d3_time.second.utc.range;\n  d3_time.minute = d3_time_interval(function(date) {\n    return new d3_date(Math.floor(date / 6e4) * 6e4);\n  }, function(date, offset) {\n    date.setTime(date.getTime() + Math.floor(offset) * 6e4);\n  }, function(date) {\n    return date.getMinutes();\n  });\n  d3_time.minutes = d3_time.minute.range;\n  d3_time.minutes.utc = d3_time.minute.utc.range;\n  d3_time.hour = d3_time_interval(function(date) {\n    var timezone = date.getTimezoneOffset() / 60;\n    return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5);\n  }, function(date, offset) {\n    date.setTime(date.getTime() + Math.floor(offset) * 36e5);\n  }, function(date) {\n    return date.getHours();\n  });\n  d3_time.hours = d3_time.hour.range;\n  d3_time.hours.utc = d3_time.hour.utc.range;\n  d3_time.month = d3_time_interval(function(date) {\n    date = d3_time.day(date);\n    date.setDate(1);\n    return date;\n  }, function(date, offset) {\n    date.setMonth(date.getMonth() + offset);\n  }, function(date) {\n    return date.getMonth();\n  });\n  d3_time.months = d3_time.month.range;\n  d3_time.months.utc = d3_time.month.utc.range;\n  function d3_time_scale(linear, methods, format) {\n    function scale(x) {\n      return linear(x);\n    }\n    scale.invert = function(x) {\n      return d3_time_scaleDate(linear.invert(x));\n    };\n    scale.domain = function(x) {\n      if (!arguments.length) return linear.domain().map(d3_time_scaleDate);\n      linear.domain(x);\n      return scale;\n    };\n    function tickMethod(extent, count) {\n      var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target);\n      return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) {\n        return d / 31536e6;\n      }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i];\n    }\n    scale.nice = function(interval, skip) {\n      var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === \"number\" && tickMethod(extent, interval);\n      if (method) interval = method[0], skip = method[1];\n      function skipped(date) {\n        return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length;\n      }\n      return scale.domain(d3_scale_nice(domain, skip > 1 ? {\n        floor: function(date) {\n          while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1);\n          return date;\n        },\n        ceil: function(date) {\n          while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1);\n          return date;\n        }\n      } : interval));\n    };\n    scale.ticks = function(interval, skip) {\n      var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === \"number\" ? tickMethod(extent, interval) : !interval.range && [ {\n        range: interval\n      }, skip ];\n      if (method) interval = method[0], skip = method[1];\n      return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip);\n    };\n    scale.tickFormat = function() {\n      return format;\n    };\n    scale.copy = function() {\n      return d3_time_scale(linear.copy(), methods, format);\n    };\n    return d3_scale_linearRebind(scale, linear);\n  }\n  function d3_time_scaleDate(t) {\n    return new Date(t);\n  }\n  var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ];\n  var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ];\n  var d3_time_scaleLocalFormat = d3_time_format.multi([ [ \".%L\", function(d) {\n    return d.getMilliseconds();\n  } ], [ \":%S\", function(d) {\n    return d.getSeconds();\n  } ], [ \"%I:%M\", function(d) {\n    return d.getMinutes();\n  } ], [ \"%I %p\", function(d) {\n    return d.getHours();\n  } ], [ \"%a %d\", function(d) {\n    return d.getDay() && d.getDate() != 1;\n  } ], [ \"%b %d\", function(d) {\n    return d.getDate() != 1;\n  } ], [ \"%B\", function(d) {\n    return d.getMonth();\n  } ], [ \"%Y\", d3_true ] ]);\n  var d3_time_scaleMilliseconds = {\n    range: function(start, stop, step) {\n      return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate);\n    },\n    floor: d3_identity,\n    ceil: d3_identity\n  };\n  d3_time_scaleLocalMethods.year = d3_time.year;\n  d3_time.scale = function() {\n    return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);\n  };\n  var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) {\n    return [ m[0].utc, m[1] ];\n  });\n  var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ \".%L\", function(d) {\n    return d.getUTCMilliseconds();\n  } ], [ \":%S\", function(d) {\n    return d.getUTCSeconds();\n  } ], [ \"%I:%M\", function(d) {\n    return d.getUTCMinutes();\n  } ], [ \"%I %p\", function(d) {\n    return d.getUTCHours();\n  } ], [ \"%a %d\", function(d) {\n    return d.getUTCDay() && d.getUTCDate() != 1;\n  } ], [ \"%b %d\", function(d) {\n    return d.getUTCDate() != 1;\n  } ], [ \"%B\", function(d) {\n    return d.getUTCMonth();\n  } ], [ \"%Y\", d3_true ] ]);\n  d3_time_scaleUtcMethods.year = d3_time.year.utc;\n  d3_time.scale.utc = function() {\n    return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat);\n  };\n  d3.text = d3_xhrType(function(request) {\n    return request.responseText;\n  });\n  d3.json = function(url, callback) {\n    return d3_xhr(url, \"application/json\", d3_json, callback);\n  };\n  function d3_json(request) {\n    return JSON.parse(request.responseText);\n  }\n  d3.html = function(url, callback) {\n    return d3_xhr(url, \"text/html\", d3_html, callback);\n  };\n  function d3_html(request) {\n    var range = d3_document.createRange();\n    range.selectNode(d3_document.body);\n    return range.createContextualFragment(request.responseText);\n  }\n  d3.xml = d3_xhrType(function(request) {\n    return request.responseXML;\n  });\n  if (typeof define === \"function\" && define.amd) this.d3 = d3, define(d3); else if (typeof module === \"object\" && module.exports) module.exports = d3; else this.d3 = d3;\n}();\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/d3/d3.js\n ** module id = 379\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\nconst TEMPLATE = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\nexport default function guid(len = TEMPLATE.length) {\n\t// http://byronsalau.com/blog/how-to-create-a-guid-uuid-in-javascript/\n\treturn TEMPLATE.replace(/[xy]/g, function (c) {\n\t\tvar r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);\n\t\treturn v.toString(16);\n\t}).substring(0, len);\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/guid.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/23/15.\n */\n\nimport _ from 'lodash'\nimport guid from '../guid'\nimport Position from '../graph/Position'\nimport IconFactory from './IconFactory'\nimport SelectionManager from '../SelectionManager'\nimport DescriptorModelMetaFactory from './DescriptorModelMetaFactory'\n\n/**\n * Abstract base class for the CONFD MANO Descriptors as defined by the Rift.ware YANG configuration files.\n *\n * Sub-classes should specify the type and qualified-type properties.\n */\nexport default class DescriptorModel {\n\n\tconstructor(model = {meta: {}}, parent = null) {\n\t\t// when our instance has no more strong references\n\t\t// then our properties will get garbage collected.\n\t\tthis._props_ = new WeakMap();\n\t\tthis._props_.set(this, {\n\t\t\tposition: new Position(),\n\t\t\tchildren: new Set(),\n\t\t\tvalues: {},\n\t\t\tmodel: model\n\t\t});\n\t\tthis.className = 'DescriptorModel';\n\t\tthis.uid = this.uid || guid();\n\t\tif (parent instanceof DescriptorModel) {\n\t\t\tparent.addChild(this);\n\t\t}\n\t}\n\n\tget fieldNames() {\n\t\treturn DescriptorModelMetaFactory.getModelFieldNamesForType(this.meta['qualified-type'] || this.type);\n\t}\n\n\tget property() {\n\t\treturn DescriptorModelMetaFactory.getModelMetaForType(this.meta['qualified-type'] || this.type);\n\t}\n\n\tget model() {\n\t\tlet model = this._props_.get(this).model;\n\t\tif (!model) {\n\t\t\tmodel = this.model = {meta: {}};\n\t\t}\n\t\treturn model;\n\t}\n\n\tset model(model) {\n\t\tthis._props_.get(this).model = model;\n\t\treturn this;\n\t}\n\n\tget meta() {\n\t\treturn this.model.meta = this.model.meta || {};\n\t}\n\n\tset meta(meta) {\n\t\tthis.model.meta = meta;\n\t\treturn this;\n\t}\n\n\tget uid() {\n\t\treturn this.meta[':uid'];\n\t}\n\n\tset uid(uid) {\n\t\tthis.meta[':uid'] = uid;\n\t\treturn this;\n\t}\n\n\tget key() {\n\t\treturn this.id;\n\t}\n\n\t// key is read only by design\n\n\tget id() {\n\t\treturn this.model.id;\n\t}\n\n\tset id(id) {\n\t\tthis.model.id = id;\n\t\treturn this;\n\t}\n\n\tget title() {\n\t\treturn this.model['short-name'] || this.model.name;\n\t}\n\n\t// title is read only by design\n\n\tget type() {\n\t\treturn this.meta.type;\n\t}\n\n\tset type(type) {\n\t\tthis.meta.type = type;\n\t\treturn this;\n\t}\n\n\tget qualifiedType() {\n\t\treturn this.meta['qualified-type'] || this.type;\n\t}\n\n\tset qualifiedType(type) {\n\t\tthis.meta['qualified-type'] = type;\n\t}\n\n\tget position() {\n\t\treturn this._props_.get(this).position;\n\t}\n\n\tset position(position) {\n\t\tif (!(position instanceof Position)) {\n\n\t\t}\n\t\tthis._props_.get(this).position = position;\n\t\treturn this;\n\t}\n\n\tget location() {\n\t\treturn this.meta.location;\n\t}\n\n\tset location(v) {\n\t\tthis.meta.location = v;\n\t}\n\n\tget children() {\n\t\treturn Array.from(this._props_.get(this).children);\n\t}\n\n\taddProp(name, value) {\n\t\tthis._props_.get(this).values[name] = value;\n\t\treturn this;\n\t}\n\n\tgetProp(name) {\n\t\treturn this._props_.get(this).values[name];\n\t}\n\n\taddChild(child) {\n\t\tif (!child instanceof DescriptorModel) {\n\t\t\tthrow new ReferenceError('child must be an instance of DescriptorModel class');\n\t\t}\n\t\tif (this.findChildByUid(child.uid)) {\n\t\t\tthrow new ReferenceError('child already exists');\n\t\t}\n\t\tif (child.parent instanceof DescriptorModel) {\n\t\t\tthrow new ReferenceError('child already has a parent');\n\t\t}\n\t\tchild.parent = this;\n\t\tthis._props_.get(this).children.add(child);\n\t}\n\n\tfindChildByUid(uid) {\n\t\t// uid can be a DescriptorModel instance,  JSON model object, or a uid string\n\t\tif (typeof uid === 'object') {\n\t\t\tuid = uid.meta && uid.meta[':uid'];\n\t\t}\n\t\tif (typeof uid === 'string') {\n\t\t\treturn this.children.filter(d => d.uid === uid)[0];\n\t\t}\n\t}\n\n\tremoveChild(child) {\n\t\tlet uid;\n\t\t// warn don't clear parent so that removed ones can get to root for updating the catalog json model\n\t\t//child.parent = null;\n\t\t// uid can be a DescriptorModel instance, JSON model object, or a uid string\n\t\tif (typeof uid === 'object') {\n\t\t\tuid = uid.meta && uid.meta[':uid'];\n\t\t}\n\t\tif (typeof uid === 'string') {\n\t\t\tthis.children.filter(d => d.uid === uid).forEach(d => this._props_.get(this).children.delete(d));\n\t\t} else {\n\t\t\tthis._props_.get(this).children.delete(child);\n\t\t}\n\t}\n\n\tgetRoot() {\n\t\tlet root = this;\n\t\twhile (root && root.parent) {\n\t\t\troot = root.parent;\n\t\t}\n\t\treturn root;\n\t}\n\n\tgetRootNSDContainer() {\n\t\tlet container = this.parent;\n\t\twhile(container) {\n\t\t\tif (container.type === 'nsd') {\n\t\t\t\treturn container;\n\t\t\t}\n\t\t\tcontainer = container.parent;\n\t\t}\n\t}\n\n\tsetPosition(position) {\n\t\tthis.position = new Position(position);\n\t}\n\n\tget selected() {\n\t\treturn SelectionManager.isSelected(this);\n\t}\n\n\tget colors() {\n\t\treturn this.meta.colors || {primary: 'black', secondary: 'white'};\n\t}\n\n\tset colors(colors) {\n\t\tthis.meta.colors = colors;\n\t}\n\n\tget icon() {\n\t\treturn IconFactory.getIconForType(this.type);\n\t}\n\n\tget width() {\n\t\treturn this.position.width;\n\t}\n\n\tget height() {\n\t\treturn this.position.height;\n\t}\n\n\tget displayData() {\n\t\treturn {\n\t\t\tname: this.model.name,\n\t\t\ttype: this.model.type\n\t\t};\n\t}\n\n\tupdateModelList(modelFieldName, modelFieldValue, descriptorClass = DescriptorModel, newItemAddedSuccessCallback = () => {}) {\n\t\t// value can be Array of (DescriptorModel | json model), DescriptorModel, or json model\n\t\tif (_.isArray(modelFieldValue)) {\n\t\t\tthis.model[modelFieldName] = modelFieldValue.map(d => d instanceof descriptorClass ? d.model : d);\n\t\t\treturn true;\n\t\t}\n\t\tconst size = this.model[modelFieldName].length;\n\t\tif (modelFieldValue instanceof descriptorClass) {\n\t\t\tthis.model[modelFieldName].push(modelFieldValue.model);\n\t\t\tnewItemAddedSuccessCallback(modelFieldValue);\n\t\t} else if (typeof modelFieldValue === 'object') {\n\t\t\tthis.model[modelFieldName].push(modelFieldValue);\n\t\t\tnewItemAddedSuccessCallback(new descriptorClass(modelFieldValue, this));\n\t\t} else {\n\t\t\tthrow new ReferenceError(`expect object to be either an Array, ${descriptorClass.name} or JSON object`);\n\t\t}\n\t\treturn size !== this.model[modelFieldName].length;\n\t}\n\n\tremoveModelListItem(propertyName, child) {\n\t\t// ensure child is a DescriptorModel instance\n\t\tchild = this.findChildByUid(child) || child;\n\t\tif (!child) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.removeChild(child);\n\t\tconst uid = child.uid;\n\t\tconst length = this[propertyName].length;\n\t\tthis[propertyName] = this[propertyName].filter(d => d.uid !== uid);\n\t\treturn length !== this[propertyName].length;\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorModel.js\n **/","/**\n * @license\n * lodash 3.10.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern -d -o ./index.js`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n;(function() {\n\n  /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n  var undefined;\n\n  /** Used as the semantic version number. */\n  var VERSION = '3.10.1';\n\n  /** Used to compose bitmasks for wrapper metadata. */\n  var BIND_FLAG = 1,\n      BIND_KEY_FLAG = 2,\n      CURRY_BOUND_FLAG = 4,\n      CURRY_FLAG = 8,\n      CURRY_RIGHT_FLAG = 16,\n      PARTIAL_FLAG = 32,\n      PARTIAL_RIGHT_FLAG = 64,\n      ARY_FLAG = 128,\n      REARG_FLAG = 256;\n\n  /** Used as default options for `_.trunc`. */\n  var DEFAULT_TRUNC_LENGTH = 30,\n      DEFAULT_TRUNC_OMISSION = '...';\n\n  /** Used to detect when a function becomes hot. */\n  var HOT_COUNT = 150,\n      HOT_SPAN = 16;\n\n  /** Used as the size to enable large array optimizations. */\n  var LARGE_ARRAY_SIZE = 200;\n\n  /** Used to indicate the type of lazy iteratees. */\n  var LAZY_FILTER_FLAG = 1,\n      LAZY_MAP_FLAG = 2;\n\n  /** Used as the `TypeError` message for \"Functions\" methods. */\n  var FUNC_ERROR_TEXT = 'Expected a function';\n\n  /** Used as the internal argument placeholder. */\n  var PLACEHOLDER = '__lodash_placeholder__';\n\n  /** `Object#toString` result references. */\n  var argsTag = '[object Arguments]',\n      arrayTag = '[object Array]',\n      boolTag = '[object Boolean]',\n      dateTag = '[object Date]',\n      errorTag = '[object Error]',\n      funcTag = '[object Function]',\n      mapTag = '[object Map]',\n      numberTag = '[object Number]',\n      objectTag = '[object Object]',\n      regexpTag = '[object RegExp]',\n      setTag = '[object Set]',\n      stringTag = '[object String]',\n      weakMapTag = '[object WeakMap]';\n\n  var arrayBufferTag = '[object ArrayBuffer]',\n      float32Tag = '[object Float32Array]',\n      float64Tag = '[object Float64Array]',\n      int8Tag = '[object Int8Array]',\n      int16Tag = '[object Int16Array]',\n      int32Tag = '[object Int32Array]',\n      uint8Tag = '[object Uint8Array]',\n      uint8ClampedTag = '[object Uint8ClampedArray]',\n      uint16Tag = '[object Uint16Array]',\n      uint32Tag = '[object Uint32Array]';\n\n  /** Used to match empty string literals in compiled template source. */\n  var reEmptyStringLeading = /\\b__p \\+= '';/g,\n      reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n      reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n  /** Used to match HTML entities and HTML characters. */\n  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,\n      reUnescapedHtml = /[&<>\"'`]/g,\n      reHasEscapedHtml = RegExp(reEscapedHtml.source),\n      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n  /** Used to match template delimiters. */\n  var reEscape = /<%-([\\s\\S]+?)%>/g,\n      reEvaluate = /<%([\\s\\S]+?)%>/g,\n      reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n  /** Used to match property names within property paths. */\n  var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\n\\\\]|\\\\.)*?\\1)\\]/,\n      reIsPlainProp = /^\\w*$/,\n      rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\n\\\\]|\\\\.)*?)\\2)\\]/g;\n\n  /**\n   * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns)\n   * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).\n   */\n  var reRegExpChars = /^[:!,]|[\\\\^$.*+?()[\\]{}|\\/]|(^[0-9a-fA-Fnrtuvx])|([\\n\\r\\u2028\\u2029])/g,\n      reHasRegExpChars = RegExp(reRegExpChars.source);\n\n  /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */\n  var reComboMark = /[\\u0300-\\u036f\\ufe20-\\ufe23]/g;\n\n  /** Used to match backslashes in property paths. */\n  var reEscapeChar = /\\\\(\\\\)?/g;\n\n  /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */\n  var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n  /** Used to match `RegExp` flags from their coerced string values. */\n  var reFlags = /\\w*$/;\n\n  /** Used to detect hexadecimal string values. */\n  var reHasHexPrefix = /^0[xX]/;\n\n  /** Used to detect host constructors (Safari > 5). */\n  var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n  /** Used to detect unsigned integer values. */\n  var reIsUint = /^\\d+$/;\n\n  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */\n  var reLatin1 = /[\\xc0-\\xd6\\xd8-\\xde\\xdf-\\xf6\\xf8-\\xff]/g;\n\n  /** Used to ensure capturing order of template delimiters. */\n  var reNoMatch = /($^)/;\n\n  /** Used to match unescaped characters in compiled string literals. */\n  var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n  /** Used to match words to create compound words. */\n  var reWords = (function() {\n    var upper = '[A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde]',\n        lower = '[a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff]+';\n\n    return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');\n  }());\n\n  /** Used to assign default `context` object properties. */\n  var contextProps = [\n    'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',\n    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',\n    'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',\n    'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',\n    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'\n  ];\n\n  /** Used to make template sourceURLs easier to identify. */\n  var templateCounter = -1;\n\n  /** Used to identify `toStringTag` values of typed arrays. */\n  var typedArrayTags = {};\n  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n  typedArrayTags[uint32Tag] = true;\n  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n  typedArrayTags[dateTag] = typedArrayTags[errorTag] =\n  typedArrayTags[funcTag] = typedArrayTags[mapTag] =\n  typedArrayTags[numberTag] = typedArrayTags[objectTag] =\n  typedArrayTags[regexpTag] = typedArrayTags[setTag] =\n  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;\n\n  /** Used to identify `toStringTag` values supported by `_.clone`. */\n  var cloneableTags = {};\n  cloneableTags[argsTag] = cloneableTags[arrayTag] =\n  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =\n  cloneableTags[dateTag] = cloneableTags[float32Tag] =\n  cloneableTags[float64Tag] = cloneableTags[int8Tag] =\n  cloneableTags[int16Tag] = cloneableTags[int32Tag] =\n  cloneableTags[numberTag] = cloneableTags[objectTag] =\n  cloneableTags[regexpTag] = cloneableTags[stringTag] =\n  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n  cloneableTags[errorTag] = cloneableTags[funcTag] =\n  cloneableTags[mapTag] = cloneableTags[setTag] =\n  cloneableTags[weakMapTag] = false;\n\n  /** Used to map latin-1 supplementary letters to basic latin letters. */\n  var deburredLetters = {\n    '\\xc0': 'A',  '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n    '\\xe0': 'a',  '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n    '\\xc7': 'C',  '\\xe7': 'c',\n    '\\xd0': 'D',  '\\xf0': 'd',\n    '\\xc8': 'E',  '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n    '\\xe8': 'e',  '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n    '\\xcC': 'I',  '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n    '\\xeC': 'i',  '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n    '\\xd1': 'N',  '\\xf1': 'n',\n    '\\xd2': 'O',  '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n    '\\xf2': 'o',  '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n    '\\xd9': 'U',  '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n    '\\xf9': 'u',  '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n    '\\xdd': 'Y',  '\\xfd': 'y', '\\xff': 'y',\n    '\\xc6': 'Ae', '\\xe6': 'ae',\n    '\\xde': 'Th', '\\xfe': 'th',\n    '\\xdf': 'ss'\n  };\n\n  /** Used to map characters to HTML entities. */\n  var htmlEscapes = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#39;',\n    '`': '&#96;'\n  };\n\n  /** Used to map HTML entities to characters. */\n  var htmlUnescapes = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#39;': \"'\",\n    '&#96;': '`'\n  };\n\n  /** Used to determine if values are of the language type `Object`. */\n  var objectTypes = {\n    'function': true,\n    'object': true\n  };\n\n  /** Used to escape characters for inclusion in compiled regexes. */\n  var regexpEscapes = {\n    '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34',\n    '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39',\n    'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46',\n    'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66',\n    'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78'\n  };\n\n  /** Used to escape characters for inclusion in compiled string literals. */\n  var stringEscapes = {\n    '\\\\': '\\\\',\n    \"'\": \"'\",\n    '\\n': 'n',\n    '\\r': 'r',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  /** Detect free variable `exports`. */\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  /** Detect free variable `module`. */\n  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;\n\n  /** Detect free variable `global` from Node.js. */\n  var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;\n\n  /** Detect free variable `self`. */\n  var freeSelf = objectTypes[typeof self] && self && self.Object && self;\n\n  /** Detect free variable `window`. */\n  var freeWindow = objectTypes[typeof window] && window && window.Object && window;\n\n  /** Detect the popular CommonJS extension `module.exports`. */\n  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;\n\n  /**\n   * Used as a reference to the global object.\n   *\n   * The `this` value is used if it's the global object to avoid Greasemonkey's\n   * restricted `window` object, otherwise the `window` object is used.\n   */\n  var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * The base implementation of `compareAscending` which compares values and\n   * sorts them in ascending order without guaranteeing a stable sort.\n   *\n   * @private\n   * @param {*} value The value to compare.\n   * @param {*} other The other value to compare.\n   * @returns {number} Returns the sort order indicator for `value`.\n   */\n  function baseCompareAscending(value, other) {\n    if (value !== other) {\n      var valIsNull = value === null,\n          valIsUndef = value === undefined,\n          valIsReflexive = value === value;\n\n      var othIsNull = other === null,\n          othIsUndef = other === undefined,\n          othIsReflexive = other === other;\n\n      if ((value > other && !othIsNull) || !valIsReflexive ||\n          (valIsNull && !othIsUndef && othIsReflexive) ||\n          (valIsUndef && othIsReflexive)) {\n        return 1;\n      }\n      if ((value < other && !valIsNull) || !othIsReflexive ||\n          (othIsNull && !valIsUndef && valIsReflexive) ||\n          (othIsUndef && valIsReflexive)) {\n        return -1;\n      }\n    }\n    return 0;\n  }\n\n  /**\n   * The base implementation of `_.findIndex` and `_.findLastIndex` without\n   * support for callback shorthands and `this` binding.\n   *\n   * @private\n   * @param {Array} array The array to search.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {boolean} [fromRight] Specify iterating from right to left.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseFindIndex(array, predicate, fromRight) {\n    var length = array.length,\n        index = fromRight ? length : -1;\n\n    while ((fromRight ? index-- : ++index < length)) {\n      if (predicate(array[index], index, array)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.indexOf` without support for binary searches.\n   *\n   * @private\n   * @param {Array} array The array to search.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOf(array, value, fromIndex) {\n    if (value !== value) {\n      return indexOfNaN(array, fromIndex);\n    }\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.isFunction` without support for environments\n   * with incorrect `typeof` results.\n   *\n   * @private\n   * @param {*} value The value to check.\n   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n   */\n  function baseIsFunction(value) {\n    // Avoid a Chakra JIT bug in compatibility modes of IE 11.\n    // See https://github.com/jashkenas/underscore/issues/1621 for more details.\n    return typeof value == 'function' || false;\n  }\n\n  /**\n   * Converts `value` to a string if it's not one. An empty string is returned\n   * for `null` or `undefined` values.\n   *\n   * @private\n   * @param {*} value The value to process.\n   * @returns {string} Returns the string.\n   */\n  function baseToString(value) {\n    return value == null ? '' : (value + '');\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimLeft` to get the index of the first character\n   * of `string` that is not found in `chars`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @param {string} chars The characters to find.\n   * @returns {number} Returns the index of the first character not found in `chars`.\n   */\n  function charsLeftIndex(string, chars) {\n    var index = -1,\n        length = string.length;\n\n    while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimRight` to get the index of the last character\n   * of `string` that is not found in `chars`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @param {string} chars The characters to find.\n   * @returns {number} Returns the index of the last character not found in `chars`.\n   */\n  function charsRightIndex(string, chars) {\n    var index = string.length;\n\n    while (index-- && chars.indexOf(string.charAt(index)) > -1) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.sortBy` to compare transformed elements of a collection and stable\n   * sort them in ascending order.\n   *\n   * @private\n   * @param {Object} object The object to compare.\n   * @param {Object} other The other object to compare.\n   * @returns {number} Returns the sort order indicator for `object`.\n   */\n  function compareAscending(object, other) {\n    return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);\n  }\n\n  /**\n   * Used by `_.sortByOrder` to compare multiple properties of a value to another\n   * and stable sort them.\n   *\n   * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise,\n   * a value is sorted in ascending order if its corresponding order is \"asc\", and\n   * descending if \"desc\".\n   *\n   * @private\n   * @param {Object} object The object to compare.\n   * @param {Object} other The other object to compare.\n   * @param {boolean[]} orders The order to sort by for each property.\n   * @returns {number} Returns the sort order indicator for `object`.\n   */\n  function compareMultiple(object, other, orders) {\n    var index = -1,\n        objCriteria = object.criteria,\n        othCriteria = other.criteria,\n        length = objCriteria.length,\n        ordersLength = orders.length;\n\n    while (++index < length) {\n      var result = baseCompareAscending(objCriteria[index], othCriteria[index]);\n      if (result) {\n        if (index >= ordersLength) {\n          return result;\n        }\n        var order = orders[index];\n        return result * ((order === 'asc' || order === true) ? 1 : -1);\n      }\n    }\n    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n    // that causes it, under certain circumstances, to provide the same value for\n    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n    // for more details.\n    //\n    // This also ensures a stable sort in V8 and other engines.\n    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.\n    return object.index - other.index;\n  }\n\n  /**\n   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.\n   *\n   * @private\n   * @param {string} letter The matched letter to deburr.\n   * @returns {string} Returns the deburred letter.\n   */\n  function deburrLetter(letter) {\n    return deburredLetters[letter];\n  }\n\n  /**\n   * Used by `_.escape` to convert characters to HTML entities.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  function escapeHtmlChar(chr) {\n    return htmlEscapes[chr];\n  }\n\n  /**\n   * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @param {string} leadingChar The capture group for a leading character.\n   * @param {string} whitespaceChar The capture group for a whitespace character.\n   * @returns {string} Returns the escaped character.\n   */\n  function escapeRegExpChar(chr, leadingChar, whitespaceChar) {\n    if (leadingChar) {\n      chr = regexpEscapes[chr];\n    } else if (whitespaceChar) {\n      chr = stringEscapes[chr];\n    }\n    return '\\\\' + chr;\n  }\n\n  /**\n   * Used by `_.template` to escape characters for inclusion in compiled string literals.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  function escapeStringChar(chr) {\n    return '\\\\' + stringEscapes[chr];\n  }\n\n  /**\n   * Gets the index at which the first occurrence of `NaN` is found in `array`.\n   *\n   * @private\n   * @param {Array} array The array to search.\n   * @param {number} fromIndex The index to search from.\n   * @param {boolean} [fromRight] Specify iterating from right to left.\n   * @returns {number} Returns the index of the matched `NaN`, else `-1`.\n   */\n  function indexOfNaN(array, fromIndex, fromRight) {\n    var length = array.length,\n        index = fromIndex + (fromRight ? 0 : -1);\n\n    while ((fromRight ? index-- : ++index < length)) {\n      var other = array[index];\n      if (other !== other) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * Checks if `value` is object-like.\n   *\n   * @private\n   * @param {*} value The value to check.\n   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n   */\n  function isObjectLike(value) {\n    return !!value && typeof value == 'object';\n  }\n\n  /**\n   * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a\n   * character code is whitespace.\n   *\n   * @private\n   * @param {number} charCode The character code to inspect.\n   * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`.\n   */\n  function isSpace(charCode) {\n    return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||\n      (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));\n  }\n\n  /**\n   * Replaces all `placeholder` elements in `array` with an internal placeholder\n   * and returns an array of their indexes.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {*} placeholder The placeholder to replace.\n   * @returns {Array} Returns the new array of placeholder indexes.\n   */\n  function replaceHolders(array, placeholder) {\n    var index = -1,\n        length = array.length,\n        resIndex = -1,\n        result = [];\n\n    while (++index < length) {\n      if (array[index] === placeholder) {\n        array[index] = PLACEHOLDER;\n        result[++resIndex] = index;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * An implementation of `_.uniq` optimized for sorted arrays without support\n   * for callback shorthands and `this` binding.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {Function} [iteratee] The function invoked per iteration.\n   * @returns {Array} Returns the new duplicate-value-free array.\n   */\n  function sortedUniq(array, iteratee) {\n    var seen,\n        index = -1,\n        length = array.length,\n        resIndex = -1,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index],\n          computed = iteratee ? iteratee(value, index, array) : value;\n\n      if (!index || seen !== computed) {\n        seen = computed;\n        result[++resIndex] = value;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace\n   * character of `string`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {number} Returns the index of the first non-whitespace character.\n   */\n  function trimmedLeftIndex(string) {\n    var index = -1,\n        length = string.length;\n\n    while (++index < length && isSpace(string.charCodeAt(index))) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace\n   * character of `string`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {number} Returns the index of the last non-whitespace character.\n   */\n  function trimmedRightIndex(string) {\n    var index = string.length;\n\n    while (index-- && isSpace(string.charCodeAt(index))) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.unescape` to convert HTML entities to characters.\n   *\n   * @private\n   * @param {string} chr The matched character to unescape.\n   * @returns {string} Returns the unescaped character.\n   */\n  function unescapeHtmlChar(chr) {\n    return htmlUnescapes[chr];\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Create a new pristine `lodash` function using the given `context` object.\n   *\n   * @static\n   * @memberOf _\n   * @category Utility\n   * @param {Object} [context=root] The context object.\n   * @returns {Function} Returns a new `lodash` function.\n   * @example\n   *\n   * _.mixin({ 'foo': _.constant('foo') });\n   *\n   * var lodash = _.runInContext();\n   * lodash.mixin({ 'bar': lodash.constant('bar') });\n   *\n   * _.isFunction(_.foo);\n   * // => true\n   * _.isFunction(_.bar);\n   * // => false\n   *\n   * lodash.isFunction(lodash.foo);\n   * // => false\n   * lodash.isFunction(lodash.bar);\n   * // => true\n   *\n   * // using `context` to mock `Date#getTime` use in `_.now`\n   * var mock = _.runInContext({\n   *   'Date': function() {\n   *     return { 'getTime': getTimeMock };\n   *   }\n   * });\n   *\n   * // or creating a suped-up `defer` in Node.js\n   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n   */\n  function runInContext(context) {\n    // Avoid issues with some ES3 environments that attempt to use values, named\n    // after built-in constructors like `Object`, for the creation of literals.\n    // ES5 clears this up by stating that literals must use built-in constructors.\n    // See https://es5.github.io/#x11.1.5 for more details.\n    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;\n\n    /** Native constructor references. */\n    var Array = context.Array,\n        Date = context.Date,\n        Error = context.Error,\n        Function = context.Function,\n        Math = context.Math,\n        Number = context.Number,\n        Object = context.Object,\n        RegExp = context.RegExp,\n        String = context.String,\n        TypeError = context.TypeError;\n\n    /** Used for native method references. */\n    var arrayProto = Array.prototype,\n        objectProto = Object.prototype,\n        stringProto = String.prototype;\n\n    /** Used to resolve the decompiled source of functions. */\n    var fnToString = Function.prototype.toString;\n\n    /** Used to check objects for own properties. */\n    var hasOwnProperty = objectProto.hasOwnProperty;\n\n    /** Used to generate unique IDs. */\n    var idCounter = 0;\n\n    /**\n     * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n     * of values.\n     */\n    var objToString = objectProto.toString;\n\n    /** Used to restore the original `_` reference in `_.noConflict`. */\n    var oldDash = root._;\n\n    /** Used to detect if a method is native. */\n    var reIsNative = RegExp('^' +\n      fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n      .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n    );\n\n    /** Native method references. */\n    var ArrayBuffer = context.ArrayBuffer,\n        clearTimeout = context.clearTimeout,\n        parseFloat = context.parseFloat,\n        pow = Math.pow,\n        propertyIsEnumerable = objectProto.propertyIsEnumerable,\n        Set = getNative(context, 'Set'),\n        setTimeout = context.setTimeout,\n        splice = arrayProto.splice,\n        Uint8Array = context.Uint8Array,\n        WeakMap = getNative(context, 'WeakMap');\n\n    /* Native method references for those with the same name as other `lodash` methods. */\n    var nativeCeil = Math.ceil,\n        nativeCreate = getNative(Object, 'create'),\n        nativeFloor = Math.floor,\n        nativeIsArray = getNative(Array, 'isArray'),\n        nativeIsFinite = context.isFinite,\n        nativeKeys = getNative(Object, 'keys'),\n        nativeMax = Math.max,\n        nativeMin = Math.min,\n        nativeNow = getNative(Date, 'now'),\n        nativeParseInt = context.parseInt,\n        nativeRandom = Math.random;\n\n    /** Used as references for `-Infinity` and `Infinity`. */\n    var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,\n        POSITIVE_INFINITY = Number.POSITIVE_INFINITY;\n\n    /** Used as references for the maximum length and index of an array. */\n    var MAX_ARRAY_LENGTH = 4294967295,\n        MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n        HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n    /**\n     * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n     * of an array-like value.\n     */\n    var MAX_SAFE_INTEGER = 9007199254740991;\n\n    /** Used to store function metadata. */\n    var metaMap = WeakMap && new WeakMap;\n\n    /** Used to lookup unminified function names. */\n    var realNames = {};\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` object which wraps `value` to enable implicit chaining.\n     * Methods that operate on and return arrays, collections, and functions can\n     * be chained together. Methods that retrieve a single value or may return a\n     * primitive value will automatically end the chain returning the unwrapped\n     * value. Explicit chaining may be enabled using `_.chain`. The execution of\n     * chained methods is lazy, that is, execution is deferred until `_#value`\n     * is implicitly or explicitly called.\n     *\n     * Lazy evaluation allows several methods to support shortcut fusion. Shortcut\n     * fusion is an optimization strategy which merge iteratee calls; this can help\n     * to avoid the creation of intermediate data structures and greatly reduce the\n     * number of iteratee executions.\n     *\n     * Chaining is supported in custom builds as long as the `_#value` method is\n     * directly or indirectly included in the build.\n     *\n     * In addition to lodash methods, wrappers have `Array` and `String` methods.\n     *\n     * The wrapper `Array` methods are:\n     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,\n     * `splice`, and `unshift`\n     *\n     * The wrapper `String` methods are:\n     * `replace` and `split`\n     *\n     * The wrapper methods that support shortcut fusion are:\n     * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,\n     * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,\n     * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,\n     * and `where`\n     *\n     * The chainable wrapper methods are:\n     * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,\n     * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,\n     * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,\n     * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,\n     * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,\n     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,\n     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,\n     * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,\n     * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,\n     * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,\n     * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,\n     * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,\n     * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,\n     * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,\n     * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,\n     * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,\n     * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`\n     *\n     * The wrapper methods that are **not** chainable by default are:\n     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,\n     * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,\n     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,\n     * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,\n     * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,\n     * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,\n     * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,\n     * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,\n     * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,\n     * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,\n     * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,\n     * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,\n     * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,\n     * `unescape`, `uniqueId`, `value`, and `words`\n     *\n     * The wrapper method `sample` will return a wrapped value when `n` is provided,\n     * otherwise an unwrapped value is returned.\n     *\n     * @name _\n     * @constructor\n     * @category Chain\n     * @param {*} value The value to wrap in a `lodash` instance.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var wrapped = _([1, 2, 3]);\n     *\n     * // returns an unwrapped value\n     * wrapped.reduce(function(total, n) {\n     *   return total + n;\n     * });\n     * // => 6\n     *\n     * // returns a wrapped value\n     * var squares = wrapped.map(function(n) {\n     *   return n * n;\n     * });\n     *\n     * _.isArray(squares);\n     * // => false\n     *\n     * _.isArray(squares.value());\n     * // => true\n     */\n    function lodash(value) {\n      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n        if (value instanceof LodashWrapper) {\n          return value;\n        }\n        if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {\n          return wrapperClone(value);\n        }\n      }\n      return new LodashWrapper(value);\n    }\n\n    /**\n     * The function whose prototype all chaining wrappers inherit from.\n     *\n     * @private\n     */\n    function baseLodash() {\n      // No operation performed.\n    }\n\n    /**\n     * The base constructor for creating `lodash` wrapper objects.\n     *\n     * @private\n     * @param {*} value The value to wrap.\n     * @param {boolean} [chainAll] Enable chaining for all wrapper methods.\n     * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.\n     */\n    function LodashWrapper(value, chainAll, actions) {\n      this.__wrapped__ = value;\n      this.__actions__ = actions || [];\n      this.__chain__ = !!chainAll;\n    }\n\n    /**\n     * An object environment feature flags.\n     *\n     * @static\n     * @memberOf _\n     * @type Object\n     */\n    var support = lodash.support = {};\n\n    /**\n     * By default, the template delimiters used by lodash are like those in\n     * embedded Ruby (ERB). Change the following template settings to use\n     * alternative delimiters.\n     *\n     * @static\n     * @memberOf _\n     * @type Object\n     */\n    lodash.templateSettings = {\n\n      /**\n       * Used to detect `data` property values to be HTML-escaped.\n       *\n       * @memberOf _.templateSettings\n       * @type RegExp\n       */\n      'escape': reEscape,\n\n      /**\n       * Used to detect code to be evaluated.\n       *\n       * @memberOf _.templateSettings\n       * @type RegExp\n       */\n      'evaluate': reEvaluate,\n\n      /**\n       * Used to detect `data` property values to inject.\n       *\n       * @memberOf _.templateSettings\n       * @type RegExp\n       */\n      'interpolate': reInterpolate,\n\n      /**\n       * Used to reference the data object in the template text.\n       *\n       * @memberOf _.templateSettings\n       * @type string\n       */\n      'variable': '',\n\n      /**\n       * Used to import variables into the compiled template.\n       *\n       * @memberOf _.templateSettings\n       * @type Object\n       */\n      'imports': {\n\n        /**\n         * A reference to the `lodash` function.\n         *\n         * @memberOf _.templateSettings.imports\n         * @type Function\n         */\n        '_': lodash\n      }\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n     *\n     * @private\n     * @param {*} value The value to wrap.\n     */\n    function LazyWrapper(value) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__dir__ = 1;\n      this.__filtered__ = false;\n      this.__iteratees__ = [];\n      this.__takeCount__ = POSITIVE_INFINITY;\n      this.__views__ = [];\n    }\n\n    /**\n     * Creates a clone of the lazy wrapper object.\n     *\n     * @private\n     * @name clone\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the cloned `LazyWrapper` object.\n     */\n    function lazyClone() {\n      var result = new LazyWrapper(this.__wrapped__);\n      result.__actions__ = arrayCopy(this.__actions__);\n      result.__dir__ = this.__dir__;\n      result.__filtered__ = this.__filtered__;\n      result.__iteratees__ = arrayCopy(this.__iteratees__);\n      result.__takeCount__ = this.__takeCount__;\n      result.__views__ = arrayCopy(this.__views__);\n      return result;\n    }\n\n    /**\n     * Reverses the direction of lazy iteration.\n     *\n     * @private\n     * @name reverse\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the new reversed `LazyWrapper` object.\n     */\n    function lazyReverse() {\n      if (this.__filtered__) {\n        var result = new LazyWrapper(this);\n        result.__dir__ = -1;\n        result.__filtered__ = true;\n      } else {\n        result = this.clone();\n        result.__dir__ *= -1;\n      }\n      return result;\n    }\n\n    /**\n     * Extracts the unwrapped value from its lazy wrapper.\n     *\n     * @private\n     * @name value\n     * @memberOf LazyWrapper\n     * @returns {*} Returns the unwrapped value.\n     */\n    function lazyValue() {\n      var array = this.__wrapped__.value(),\n          dir = this.__dir__,\n          isArr = isArray(array),\n          isRight = dir < 0,\n          arrLength = isArr ? array.length : 0,\n          view = getView(0, arrLength, this.__views__),\n          start = view.start,\n          end = view.end,\n          length = end - start,\n          index = isRight ? end : (start - 1),\n          iteratees = this.__iteratees__,\n          iterLength = iteratees.length,\n          resIndex = 0,\n          takeCount = nativeMin(length, this.__takeCount__);\n\n      if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {\n        return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__);\n      }\n      var result = [];\n\n      outer:\n      while (length-- && resIndex < takeCount) {\n        index += dir;\n\n        var iterIndex = -1,\n            value = array[index];\n\n        while (++iterIndex < iterLength) {\n          var data = iteratees[iterIndex],\n              iteratee = data.iteratee,\n              type = data.type,\n              computed = iteratee(value);\n\n          if (type == LAZY_MAP_FLAG) {\n            value = computed;\n          } else if (!computed) {\n            if (type == LAZY_FILTER_FLAG) {\n              continue outer;\n            } else {\n              break outer;\n            }\n          }\n        }\n        result[resIndex++] = value;\n      }\n      return result;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a cache object to store key/value pairs.\n     *\n     * @private\n     * @static\n     * @name Cache\n     * @memberOf _.memoize\n     */\n    function MapCache() {\n      this.__data__ = {};\n    }\n\n    /**\n     * Removes `key` and its value from the cache.\n     *\n     * @private\n     * @name delete\n     * @memberOf _.memoize.Cache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`.\n     */\n    function mapDelete(key) {\n      return this.has(key) && delete this.__data__[key];\n    }\n\n    /**\n     * Gets the cached value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf _.memoize.Cache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the cached value.\n     */\n    function mapGet(key) {\n      return key == '__proto__' ? undefined : this.__data__[key];\n    }\n\n    /**\n     * Checks if a cached value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf _.memoize.Cache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function mapHas(key) {\n      return key != '__proto__' && hasOwnProperty.call(this.__data__, key);\n    }\n\n    /**\n     * Sets `value` to `key` of the cache.\n     *\n     * @private\n     * @name set\n     * @memberOf _.memoize.Cache\n     * @param {string} key The key of the value to cache.\n     * @param {*} value The value to cache.\n     * @returns {Object} Returns the cache object.\n     */\n    function mapSet(key, value) {\n      if (key != '__proto__') {\n        this.__data__[key] = value;\n      }\n      return this;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     *\n     * Creates a cache object to store unique values.\n     *\n     * @private\n     * @param {Array} [values] The values to cache.\n     */\n    function SetCache(values) {\n      var length = values ? values.length : 0;\n\n      this.data = { 'hash': nativeCreate(null), 'set': new Set };\n      while (length--) {\n        this.push(values[length]);\n      }\n    }\n\n    /**\n     * Checks if `value` is in `cache` mimicking the return signature of\n     * `_.indexOf` by returning `0` if the value is found, else `-1`.\n     *\n     * @private\n     * @param {Object} cache The cache to search.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns `0` if `value` is found, else `-1`.\n     */\n    function cacheIndexOf(cache, value) {\n      var data = cache.data,\n          result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];\n\n      return result ? 0 : -1;\n    }\n\n    /**\n     * Adds `value` to the cache.\n     *\n     * @private\n     * @name push\n     * @memberOf SetCache\n     * @param {*} value The value to cache.\n     */\n    function cachePush(value) {\n      var data = this.data;\n      if (typeof value == 'string' || isObject(value)) {\n        data.set.add(value);\n      } else {\n        data.hash[value] = true;\n      }\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a new array joining `array` with `other`.\n     *\n     * @private\n     * @param {Array} array The array to join.\n     * @param {Array} other The other array to join.\n     * @returns {Array} Returns the new concatenated array.\n     */\n    function arrayConcat(array, other) {\n      var index = -1,\n          length = array.length,\n          othIndex = -1,\n          othLength = other.length,\n          result = Array(length + othLength);\n\n      while (++index < length) {\n        result[index] = array[index];\n      }\n      while (++othIndex < othLength) {\n        result[index++] = other[othIndex];\n      }\n      return result;\n    }\n\n    /**\n     * Copies the values of `source` to `array`.\n     *\n     * @private\n     * @param {Array} source The array to copy values from.\n     * @param {Array} [array=[]] The array to copy values to.\n     * @returns {Array} Returns `array`.\n     */\n    function arrayCopy(source, array) {\n      var index = -1,\n          length = source.length;\n\n      array || (array = Array(length));\n      while (++index < length) {\n        array[index] = source[index];\n      }\n      return array;\n    }\n\n    /**\n     * A specialized version of `_.forEach` for arrays without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns `array`.\n     */\n    function arrayEach(array, iteratee) {\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        if (iteratee(array[index], index, array) === false) {\n          break;\n        }\n      }\n      return array;\n    }\n\n    /**\n     * A specialized version of `_.forEachRight` for arrays without support for\n     * callback shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns `array`.\n     */\n    function arrayEachRight(array, iteratee) {\n      var length = array.length;\n\n      while (length--) {\n        if (iteratee(array[length], length, array) === false) {\n          break;\n        }\n      }\n      return array;\n    }\n\n    /**\n     * A specialized version of `_.every` for arrays without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`.\n     */\n    function arrayEvery(array, predicate) {\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        if (!predicate(array[index], index, array)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * A specialized version of `baseExtremum` for arrays which invokes `iteratee`\n     * with one argument: (value).\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} comparator The function used to compare values.\n     * @param {*} exValue The initial extremum value.\n     * @returns {*} Returns the extremum value.\n     */\n    function arrayExtremum(array, iteratee, comparator, exValue) {\n      var index = -1,\n          length = array.length,\n          computed = exValue,\n          result = computed;\n\n      while (++index < length) {\n        var value = array[index],\n            current = +iteratee(value);\n\n        if (comparator(current, computed)) {\n          computed = current;\n          result = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `_.filter` for arrays without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     */\n    function arrayFilter(array, predicate) {\n      var index = -1,\n          length = array.length,\n          resIndex = -1,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index];\n        if (predicate(value, index, array)) {\n          result[++resIndex] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `_.map` for arrays without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     */\n    function arrayMap(array, iteratee) {\n      var index = -1,\n          length = array.length,\n          result = Array(length);\n\n      while (++index < length) {\n        result[index] = iteratee(array[index], index, array);\n      }\n      return result;\n    }\n\n    /**\n     * Appends the elements of `values` to `array`.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to append.\n     * @returns {Array} Returns `array`.\n     */\n    function arrayPush(array, values) {\n      var index = -1,\n          length = values.length,\n          offset = array.length;\n\n      while (++index < length) {\n        array[offset + index] = values[index];\n      }\n      return array;\n    }\n\n    /**\n     * A specialized version of `_.reduce` for arrays without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @param {boolean} [initFromArray] Specify using the first element of `array`\n     *  as the initial value.\n     * @returns {*} Returns the accumulated value.\n     */\n    function arrayReduce(array, iteratee, accumulator, initFromArray) {\n      var index = -1,\n          length = array.length;\n\n      if (initFromArray && length) {\n        accumulator = array[++index];\n      }\n      while (++index < length) {\n        accumulator = iteratee(accumulator, array[index], index, array);\n      }\n      return accumulator;\n    }\n\n    /**\n     * A specialized version of `_.reduceRight` for arrays without support for\n     * callback shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @param {boolean} [initFromArray] Specify using the last element of `array`\n     *  as the initial value.\n     * @returns {*} Returns the accumulated value.\n     */\n    function arrayReduceRight(array, iteratee, accumulator, initFromArray) {\n      var length = array.length;\n      if (initFromArray && length) {\n        accumulator = array[--length];\n      }\n      while (length--) {\n        accumulator = iteratee(accumulator, array[length], length, array);\n      }\n      return accumulator;\n    }\n\n    /**\n     * A specialized version of `_.some` for arrays without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     */\n    function arraySome(array, predicate) {\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        if (predicate(array[index], index, array)) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n    /**\n     * A specialized version of `_.sum` for arrays without support for callback\n     * shorthands and `this` binding..\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {number} Returns the sum.\n     */\n    function arraySum(array, iteratee) {\n      var length = array.length,\n          result = 0;\n\n      while (length--) {\n        result += +iteratee(array[length]) || 0;\n      }\n      return result;\n    }\n\n    /**\n     * Used by `_.defaults` to customize its `_.assign` use.\n     *\n     * @private\n     * @param {*} objectValue The destination object property value.\n     * @param {*} sourceValue The source object property value.\n     * @returns {*} Returns the value to assign to the destination object.\n     */\n    function assignDefaults(objectValue, sourceValue) {\n      return objectValue === undefined ? sourceValue : objectValue;\n    }\n\n    /**\n     * Used by `_.template` to customize its `_.assign` use.\n     *\n     * **Note:** This function is like `assignDefaults` except that it ignores\n     * inherited property values when checking if a property is `undefined`.\n     *\n     * @private\n     * @param {*} objectValue The destination object property value.\n     * @param {*} sourceValue The source object property value.\n     * @param {string} key The key associated with the object and source values.\n     * @param {Object} object The destination object.\n     * @returns {*} Returns the value to assign to the destination object.\n     */\n    function assignOwnDefaults(objectValue, sourceValue, key, object) {\n      return (objectValue === undefined || !hasOwnProperty.call(object, key))\n        ? sourceValue\n        : objectValue;\n    }\n\n    /**\n     * A specialized version of `_.assign` for customizing assigned values without\n     * support for argument juggling, multiple sources, and `this` binding `customizer`\n     * functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {Function} customizer The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     */\n    function assignWith(object, source, customizer) {\n      var index = -1,\n          props = keys(source),\n          length = props.length;\n\n      while (++index < length) {\n        var key = props[index],\n            value = object[key],\n            result = customizer(value, source[key], key, object, source);\n\n        if ((result === result ? (result !== value) : (value === value)) ||\n            (value === undefined && !(key in object))) {\n          object[key] = result;\n        }\n      }\n      return object;\n    }\n\n    /**\n     * The base implementation of `_.assign` without support for argument juggling,\n     * multiple sources, and `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssign(object, source) {\n      return source == null\n        ? object\n        : baseCopy(source, keys(source), object);\n    }\n\n    /**\n     * The base implementation of `_.at` without support for string collections\n     * and individual key arguments.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {number[]|string[]} props The property names or indexes of elements to pick.\n     * @returns {Array} Returns the new array of picked elements.\n     */\n    function baseAt(collection, props) {\n      var index = -1,\n          isNil = collection == null,\n          isArr = !isNil && isArrayLike(collection),\n          length = isArr ? collection.length : 0,\n          propsLength = props.length,\n          result = Array(propsLength);\n\n      while(++index < propsLength) {\n        var key = props[index];\n        if (isArr) {\n          result[index] = isIndex(key, length) ? collection[key] : undefined;\n        } else {\n          result[index] = isNil ? undefined : collection[key];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Copies properties of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy properties from.\n     * @param {Array} props The property names to copy.\n     * @param {Object} [object={}] The object to copy properties to.\n     * @returns {Object} Returns `object`.\n     */\n    function baseCopy(source, props, object) {\n      object || (object = {});\n\n      var index = -1,\n          length = props.length;\n\n      while (++index < length) {\n        var key = props[index];\n        object[key] = source[key];\n      }\n      return object;\n    }\n\n    /**\n     * The base implementation of `_.callback` which supports specifying the\n     * number of arguments to provide to `func`.\n     *\n     * @private\n     * @param {*} [func=_.identity] The value to convert to a callback.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {number} [argCount] The number of arguments to provide to `func`.\n     * @returns {Function} Returns the callback.\n     */\n    function baseCallback(func, thisArg, argCount) {\n      var type = typeof func;\n      if (type == 'function') {\n        return thisArg === undefined\n          ? func\n          : bindCallback(func, thisArg, argCount);\n      }\n      if (func == null) {\n        return identity;\n      }\n      if (type == 'object') {\n        return baseMatches(func);\n      }\n      return thisArg === undefined\n        ? property(func)\n        : baseMatchesProperty(func, thisArg);\n    }\n\n    /**\n     * The base implementation of `_.clone` without support for argument juggling\n     * and `this` binding `customizer` functions.\n     *\n     * @private\n     * @param {*} value The value to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @param {Function} [customizer] The function to customize cloning values.\n     * @param {string} [key] The key of `value`.\n     * @param {Object} [object] The object `value` belongs to.\n     * @param {Array} [stackA=[]] Tracks traversed source objects.\n     * @param {Array} [stackB=[]] Associates clones with source counterparts.\n     * @returns {*} Returns the cloned value.\n     */\n    function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {\n      var result;\n      if (customizer) {\n        result = object ? customizer(value, key, object) : customizer(value);\n      }\n      if (result !== undefined) {\n        return result;\n      }\n      if (!isObject(value)) {\n        return value;\n      }\n      var isArr = isArray(value);\n      if (isArr) {\n        result = initCloneArray(value);\n        if (!isDeep) {\n          return arrayCopy(value, result);\n        }\n      } else {\n        var tag = objToString.call(value),\n            isFunc = tag == funcTag;\n\n        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n          result = initCloneObject(isFunc ? {} : value);\n          if (!isDeep) {\n            return baseAssign(result, value);\n          }\n        } else {\n          return cloneableTags[tag]\n            ? initCloneByTag(value, tag, isDeep)\n            : (object ? value : {});\n        }\n      }\n      // Check for circular references and return its corresponding clone.\n      stackA || (stackA = []);\n      stackB || (stackB = []);\n\n      var length = stackA.length;\n      while (length--) {\n        if (stackA[length] == value) {\n          return stackB[length];\n        }\n      }\n      // Add the source value to the stack of traversed objects and associate it with its clone.\n      stackA.push(value);\n      stackB.push(result);\n\n      // Recursively populate clone (susceptible to call stack limits).\n      (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {\n        result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.create` without support for assigning\n     * properties to the created object.\n     *\n     * @private\n     * @param {Object} prototype The object to inherit from.\n     * @returns {Object} Returns the new object.\n     */\n    var baseCreate = (function() {\n      function object() {}\n      return function(prototype) {\n        if (isObject(prototype)) {\n          object.prototype = prototype;\n          var result = new object;\n          object.prototype = undefined;\n        }\n        return result || {};\n      };\n    }());\n\n    /**\n     * The base implementation of `_.delay` and `_.defer` which accepts an index\n     * of where to slice the arguments to provide to `func`.\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {Object} args The arguments provide to `func`.\n     * @returns {number} Returns the timer id.\n     */\n    function baseDelay(func, wait, args) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return setTimeout(function() { func.apply(undefined, args); }, wait);\n    }\n\n    /**\n     * The base implementation of `_.difference` which accepts a single array\n     * of values to exclude.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Array} values The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     */\n    function baseDifference(array, values) {\n      var length = array ? array.length : 0,\n          result = [];\n\n      if (!length) {\n        return result;\n      }\n      var index = -1,\n          indexOf = getIndexOf(),\n          isCommon = indexOf == baseIndexOf,\n          cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,\n          valuesLength = values.length;\n\n      if (cache) {\n        indexOf = cacheIndexOf;\n        isCommon = false;\n        values = cache;\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index];\n\n        if (isCommon && value === value) {\n          var valuesIndex = valuesLength;\n          while (valuesIndex--) {\n            if (values[valuesIndex] === value) {\n              continue outer;\n            }\n          }\n          result.push(value);\n        }\n        else if (indexOf(values, value, 0) < 0) {\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.forEach` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object|string} Returns `collection`.\n     */\n    var baseEach = createBaseEach(baseForOwn);\n\n    /**\n     * The base implementation of `_.forEachRight` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object|string} Returns `collection`.\n     */\n    var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n    /**\n     * The base implementation of `_.every` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`\n     */\n    function baseEvery(collection, predicate) {\n      var result = true;\n      baseEach(collection, function(value, index, collection) {\n        result = !!predicate(value, index, collection);\n        return result;\n      });\n      return result;\n    }\n\n    /**\n     * Gets the extremum value of `collection` invoking `iteratee` for each value\n     * in `collection` to generate the criterion by which the value is ranked.\n     * The `iteratee` is invoked with three arguments: (value, index|key, collection).\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} comparator The function used to compare values.\n     * @param {*} exValue The initial extremum value.\n     * @returns {*} Returns the extremum value.\n     */\n    function baseExtremum(collection, iteratee, comparator, exValue) {\n      var computed = exValue,\n          result = computed;\n\n      baseEach(collection, function(value, index, collection) {\n        var current = +iteratee(value, index, collection);\n        if (comparator(current, computed) || (current === exValue && current === result)) {\n          computed = current;\n          result = value;\n        }\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.fill` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     */\n    function baseFill(array, value, start, end) {\n      var length = array.length;\n\n      start = start == null ? 0 : (+start || 0);\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = (end === undefined || end > length) ? length : (+end || 0);\n      if (end < 0) {\n        end += length;\n      }\n      length = start > end ? 0 : (end >>> 0);\n      start >>>= 0;\n\n      while (start < length) {\n        array[start++] = value;\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.filter` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     */\n    function baseFilter(collection, predicate) {\n      var result = [];\n      baseEach(collection, function(value, index, collection) {\n        if (predicate(value, index, collection)) {\n          result.push(value);\n        }\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,\n     * without support for callback shorthands and `this` binding, which iterates\n     * over `collection` using the provided `eachFunc`.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to search.\n     * @param {Function} predicate The function invoked per iteration.\n     * @param {Function} eachFunc The function to iterate over `collection`.\n     * @param {boolean} [retKey] Specify returning the key of the found element\n     *  instead of the element itself.\n     * @returns {*} Returns the found element or its key, else `undefined`.\n     */\n    function baseFind(collection, predicate, eachFunc, retKey) {\n      var result;\n      eachFunc(collection, function(value, key, collection) {\n        if (predicate(value, key, collection)) {\n          result = retKey ? key : value;\n          return false;\n        }\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.flatten` with added support for restricting\n     * flattening and specifying the start index.\n     *\n     * @private\n     * @param {Array} array The array to flatten.\n     * @param {boolean} [isDeep] Specify a deep flatten.\n     * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.\n     * @param {Array} [result=[]] The initial result value.\n     * @returns {Array} Returns the new flattened array.\n     */\n    function baseFlatten(array, isDeep, isStrict, result) {\n      result || (result = []);\n\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        var value = array[index];\n        if (isObjectLike(value) && isArrayLike(value) &&\n            (isStrict || isArray(value) || isArguments(value))) {\n          if (isDeep) {\n            // Recursively flatten arrays (susceptible to call stack limits).\n            baseFlatten(value, isDeep, isStrict, result);\n          } else {\n            arrayPush(result, value);\n          }\n        } else if (!isStrict) {\n          result[result.length] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `baseForIn` and `baseForOwn` which iterates\n     * over `object` properties returned by `keysFunc` invoking `iteratee` for\n     * each property. Iteratee functions may exit iteration early by explicitly\n     * returning `false`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseFor = createBaseFor();\n\n    /**\n     * This function is like `baseFor` except that it iterates over properties\n     * in the opposite order.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseForRight = createBaseFor(true);\n\n    /**\n     * The base implementation of `_.forIn` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForIn(object, iteratee) {\n      return baseFor(object, iteratee, keysIn);\n    }\n\n    /**\n     * The base implementation of `_.forOwn` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwn(object, iteratee) {\n      return baseFor(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.forOwnRight` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwnRight(object, iteratee) {\n      return baseForRight(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.functions` which creates an array of\n     * `object` function property names filtered from those provided.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Array} props The property names to filter.\n     * @returns {Array} Returns the new array of filtered property names.\n     */\n    function baseFunctions(object, props) {\n      var index = -1,\n          length = props.length,\n          resIndex = -1,\n          result = [];\n\n      while (++index < length) {\n        var key = props[index];\n        if (isFunction(object[key])) {\n          result[++resIndex] = key;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `get` without support for string paths\n     * and default values.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array} path The path of the property to get.\n     * @param {string} [pathKey] The key representation of path.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseGet(object, path, pathKey) {\n      if (object == null) {\n        return;\n      }\n      if (pathKey !== undefined && pathKey in toObject(object)) {\n        path = [pathKey];\n      }\n      var index = 0,\n          length = path.length;\n\n      while (object != null && index < length) {\n        object = object[path[index++]];\n      }\n      return (index && index == length) ? object : undefined;\n    }\n\n    /**\n     * The base implementation of `_.isEqual` without support for `this` binding\n     * `customizer` functions.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {Function} [customizer] The function to customize comparing values.\n     * @param {boolean} [isLoose] Specify performing partial comparisons.\n     * @param {Array} [stackA] Tracks traversed `value` objects.\n     * @param {Array} [stackB] Tracks traversed `other` objects.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     */\n    function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {\n      if (value === other) {\n        return true;\n      }\n      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {\n        return value !== value && other !== other;\n      }\n      return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);\n    }\n\n    /**\n     * A specialized version of `baseIsEqual` for arrays and objects which performs\n     * deep comparisons and tracks traversed objects enabling objects with circular\n     * references to be compared.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Function} [customizer] The function to customize comparing objects.\n     * @param {boolean} [isLoose] Specify performing partial comparisons.\n     * @param {Array} [stackA=[]] Tracks traversed `value` objects.\n     * @param {Array} [stackB=[]] Tracks traversed `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {\n      var objIsArr = isArray(object),\n          othIsArr = isArray(other),\n          objTag = arrayTag,\n          othTag = arrayTag;\n\n      if (!objIsArr) {\n        objTag = objToString.call(object);\n        if (objTag == argsTag) {\n          objTag = objectTag;\n        } else if (objTag != objectTag) {\n          objIsArr = isTypedArray(object);\n        }\n      }\n      if (!othIsArr) {\n        othTag = objToString.call(other);\n        if (othTag == argsTag) {\n          othTag = objectTag;\n        } else if (othTag != objectTag) {\n          othIsArr = isTypedArray(other);\n        }\n      }\n      var objIsObj = objTag == objectTag,\n          othIsObj = othTag == objectTag,\n          isSameTag = objTag == othTag;\n\n      if (isSameTag && !(objIsArr || objIsObj)) {\n        return equalByTag(object, other, objTag);\n      }\n      if (!isLoose) {\n        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n        if (objIsWrapped || othIsWrapped) {\n          return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);\n        }\n      }\n      if (!isSameTag) {\n        return false;\n      }\n      // Assume cyclic values are equal.\n      // For more information on detecting circular references see https://es5.github.io/#JO.\n      stackA || (stackA = []);\n      stackB || (stackB = []);\n\n      var length = stackA.length;\n      while (length--) {\n        if (stackA[length] == object) {\n          return stackB[length] == other;\n        }\n      }\n      // Add `object` and `other` to the stack of traversed objects.\n      stackA.push(object);\n      stackB.push(other);\n\n      var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);\n\n      stackA.pop();\n      stackB.pop();\n\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.isMatch` without support for callback\n     * shorthands and `this` binding.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Array} matchData The propery names, values, and compare flags to match.\n     * @param {Function} [customizer] The function to customize comparing objects.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     */\n    function baseIsMatch(object, matchData, customizer) {\n      var index = matchData.length,\n          length = index,\n          noCustomizer = !customizer;\n\n      if (object == null) {\n        return !length;\n      }\n      object = toObject(object);\n      while (index--) {\n        var data = matchData[index];\n        if ((noCustomizer && data[2])\n              ? data[1] !== object[data[0]]\n              : !(data[0] in object)\n            ) {\n          return false;\n        }\n      }\n      while (++index < length) {\n        data = matchData[index];\n        var key = data[0],\n            objValue = object[key],\n            srcValue = data[1];\n\n        if (noCustomizer && data[2]) {\n          if (objValue === undefined && !(key in object)) {\n            return false;\n          }\n        } else {\n          var result = customizer ? customizer(objValue, srcValue, key) : undefined;\n          if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {\n            return false;\n          }\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.map` without support for callback shorthands\n     * and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     */\n    function baseMap(collection, iteratee) {\n      var index = -1,\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value, key, collection) {\n        result[++index] = iteratee(value, key, collection);\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.matches` which does not clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new function.\n     */\n    function baseMatches(source) {\n      var matchData = getMatchData(source);\n      if (matchData.length == 1 && matchData[0][2]) {\n        var key = matchData[0][0],\n            value = matchData[0][1];\n\n        return function(object) {\n          if (object == null) {\n            return false;\n          }\n          return object[key] === value && (value !== undefined || (key in toObject(object)));\n        };\n      }\n      return function(object) {\n        return baseIsMatch(object, matchData);\n      };\n    }\n\n    /**\n     * The base implementation of `_.matchesProperty` which does not clone `srcValue`.\n     *\n     * @private\n     * @param {string} path The path of the property to get.\n     * @param {*} srcValue The value to compare.\n     * @returns {Function} Returns the new function.\n     */\n    function baseMatchesProperty(path, srcValue) {\n      var isArr = isArray(path),\n          isCommon = isKey(path) && isStrictComparable(srcValue),\n          pathKey = (path + '');\n\n      path = toPath(path);\n      return function(object) {\n        if (object == null) {\n          return false;\n        }\n        var key = pathKey;\n        object = toObject(object);\n        if ((isArr || !isCommon) && !(key in object)) {\n          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));\n          if (object == null) {\n            return false;\n          }\n          key = last(path);\n          object = toObject(object);\n        }\n        return object[key] === srcValue\n          ? (srcValue !== undefined || (key in object))\n          : baseIsEqual(srcValue, object[key], undefined, true);\n      };\n    }\n\n    /**\n     * The base implementation of `_.merge` without support for argument juggling,\n     * multiple sources, and `this` binding `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {Function} [customizer] The function to customize merged values.\n     * @param {Array} [stackA=[]] Tracks traversed source objects.\n     * @param {Array} [stackB=[]] Associates values with source counterparts.\n     * @returns {Object} Returns `object`.\n     */\n    function baseMerge(object, source, customizer, stackA, stackB) {\n      if (!isObject(object)) {\n        return object;\n      }\n      var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),\n          props = isSrcArr ? undefined : keys(source);\n\n      arrayEach(props || source, function(srcValue, key) {\n        if (props) {\n          key = srcValue;\n          srcValue = source[key];\n        }\n        if (isObjectLike(srcValue)) {\n          stackA || (stackA = []);\n          stackB || (stackB = []);\n          baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);\n        }\n        else {\n          var value = object[key],\n              result = customizer ? customizer(value, srcValue, key, object, source) : undefined,\n              isCommon = result === undefined;\n\n          if (isCommon) {\n            result = srcValue;\n          }\n          if ((result !== undefined || (isSrcArr && !(key in object))) &&\n              (isCommon || (result === result ? (result !== value) : (value === value)))) {\n            object[key] = result;\n          }\n        }\n      });\n      return object;\n    }\n\n    /**\n     * A specialized version of `baseMerge` for arrays and objects which performs\n     * deep merges and tracks traversed objects enabling objects with circular\n     * references to be merged.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {string} key The key of the value to merge.\n     * @param {Function} mergeFunc The function to merge values.\n     * @param {Function} [customizer] The function to customize merged values.\n     * @param {Array} [stackA=[]] Tracks traversed source objects.\n     * @param {Array} [stackB=[]] Associates values with source counterparts.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {\n      var length = stackA.length,\n          srcValue = source[key];\n\n      while (length--) {\n        if (stackA[length] == srcValue) {\n          object[key] = stackB[length];\n          return;\n        }\n      }\n      var value = object[key],\n          result = customizer ? customizer(value, srcValue, key, object, source) : undefined,\n          isCommon = result === undefined;\n\n      if (isCommon) {\n        result = srcValue;\n        if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {\n          result = isArray(value)\n            ? value\n            : (isArrayLike(value) ? arrayCopy(value) : []);\n        }\n        else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n          result = isArguments(value)\n            ? toPlainObject(value)\n            : (isPlainObject(value) ? value : {});\n        }\n        else {\n          isCommon = false;\n        }\n      }\n      // Add the source value to the stack of traversed objects and associate\n      // it with its merged value.\n      stackA.push(srcValue);\n      stackB.push(result);\n\n      if (isCommon) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);\n      } else if (result === result ? (result !== value) : (value === value)) {\n        object[key] = result;\n      }\n    }\n\n    /**\n     * The base implementation of `_.property` without support for deep paths.\n     *\n     * @private\n     * @param {string} key The key of the property to get.\n     * @returns {Function} Returns the new function.\n     */\n    function baseProperty(key) {\n      return function(object) {\n        return object == null ? undefined : object[key];\n      };\n    }\n\n    /**\n     * A specialized version of `baseProperty` which supports deep paths.\n     *\n     * @private\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new function.\n     */\n    function basePropertyDeep(path) {\n      var pathKey = (path + '');\n      path = toPath(path);\n      return function(object) {\n        return baseGet(object, path, pathKey);\n      };\n    }\n\n    /**\n     * The base implementation of `_.pullAt` without support for individual\n     * index arguments and capturing the removed elements.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {number[]} indexes The indexes of elements to remove.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAt(array, indexes) {\n      var length = array ? indexes.length : 0;\n      while (length--) {\n        var index = indexes[length];\n        if (index != previous && isIndex(index)) {\n          var previous = index;\n          splice.call(array, index, 1);\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.random` without support for argument juggling\n     * and returning floating-point numbers.\n     *\n     * @private\n     * @param {number} min The minimum possible value.\n     * @param {number} max The maximum possible value.\n     * @returns {number} Returns the random number.\n     */\n    function baseRandom(min, max) {\n      return min + nativeFloor(nativeRandom() * (max - min + 1));\n    }\n\n    /**\n     * The base implementation of `_.reduce` and `_.reduceRight` without support\n     * for callback shorthands and `this` binding, which iterates over `collection`\n     * using the provided `eachFunc`.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {*} accumulator The initial value.\n     * @param {boolean} initFromCollection Specify using the first or last element\n     *  of `collection` as the initial value.\n     * @param {Function} eachFunc The function to iterate over `collection`.\n     * @returns {*} Returns the accumulated value.\n     */\n    function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {\n      eachFunc(collection, function(value, index, collection) {\n        accumulator = initFromCollection\n          ? (initFromCollection = false, value)\n          : iteratee(accumulator, value, index, collection);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `setData` without support for hot loop detection.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetData = !metaMap ? identity : function(func, data) {\n      metaMap.set(func, data);\n      return func;\n    };\n\n    /**\n     * The base implementation of `_.slice` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseSlice(array, start, end) {\n      var index = -1,\n          length = array.length;\n\n      start = start == null ? 0 : (+start || 0);\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = (end === undefined || end > length) ? length : (+end || 0);\n      if (end < 0) {\n        end += length;\n      }\n      length = start > end ? 0 : ((end - start) >>> 0);\n      start >>>= 0;\n\n      var result = Array(length);\n      while (++index < length) {\n        result[index] = array[index + start];\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.some` without support for callback shorthands\n     * and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     */\n    function baseSome(collection, predicate) {\n      var result;\n\n      baseEach(collection, function(value, index, collection) {\n        result = predicate(value, index, collection);\n        return !result;\n      });\n      return !!result;\n    }\n\n    /**\n     * The base implementation of `_.sortBy` which uses `comparer` to define\n     * the sort order of `array` and replaces criteria objects with their\n     * corresponding values.\n     *\n     * @private\n     * @param {Array} array The array to sort.\n     * @param {Function} comparer The function to define sort order.\n     * @returns {Array} Returns `array`.\n     */\n    function baseSortBy(array, comparer) {\n      var length = array.length;\n\n      array.sort(comparer);\n      while (length--) {\n        array[length] = array[length].value;\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.sortByOrder` without param guards.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n     * @param {boolean[]} orders The sort orders of `iteratees`.\n     * @returns {Array} Returns the new sorted array.\n     */\n    function baseSortByOrder(collection, iteratees, orders) {\n      var callback = getCallback(),\n          index = -1;\n\n      iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); });\n\n      var result = baseMap(collection, function(value) {\n        var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); });\n        return { 'criteria': criteria, 'index': ++index, 'value': value };\n      });\n\n      return baseSortBy(result, function(object, other) {\n        return compareMultiple(object, other, orders);\n      });\n    }\n\n    /**\n     * The base implementation of `_.sum` without support for callback shorthands\n     * and `this` binding.\n     *\n     * @private\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {number} Returns the sum.\n     */\n    function baseSum(collection, iteratee) {\n      var result = 0;\n      baseEach(collection, function(value, index, collection) {\n        result += +iteratee(value, index, collection) || 0;\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.uniq` without support for callback shorthands\n     * and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The function invoked per iteration.\n     * @returns {Array} Returns the new duplicate-value-free array.\n     */\n    function baseUniq(array, iteratee) {\n      var index = -1,\n          indexOf = getIndexOf(),\n          length = array.length,\n          isCommon = indexOf == baseIndexOf,\n          isLarge = isCommon && length >= LARGE_ARRAY_SIZE,\n          seen = isLarge ? createCache() : null,\n          result = [];\n\n      if (seen) {\n        indexOf = cacheIndexOf;\n        isCommon = false;\n      } else {\n        isLarge = false;\n        seen = iteratee ? [] : result;\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value, index, array) : value;\n\n        if (isCommon && value === value) {\n          var seenIndex = seen.length;\n          while (seenIndex--) {\n            if (seen[seenIndex] === computed) {\n              continue outer;\n            }\n          }\n          if (iteratee) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n        else if (indexOf(seen, computed, 0) < 0) {\n          if (iteratee || isLarge) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.values` and `_.valuesIn` which creates an\n     * array of `object` property values corresponding to the property names\n     * of `props`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array} props The property names to get values for.\n     * @returns {Object} Returns the array of property values.\n     */\n    function baseValues(object, props) {\n      var index = -1,\n          length = props.length,\n          result = Array(length);\n\n      while (++index < length) {\n        result[index] = object[props[index]];\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,\n     * and `_.takeWhile` without support for callback shorthands and `this` binding.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {Function} predicate The function invoked per iteration.\n     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseWhile(array, predicate, isDrop, fromRight) {\n      var length = array.length,\n          index = fromRight ? length : -1;\n\n      while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}\n      return isDrop\n        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n    }\n\n    /**\n     * The base implementation of `wrapperValue` which returns the result of\n     * performing a sequence of actions on the unwrapped `value`, where each\n     * successive action is supplied the return value of the previous.\n     *\n     * @private\n     * @param {*} value The unwrapped value.\n     * @param {Array} actions Actions to peform to resolve the unwrapped value.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseWrapperValue(value, actions) {\n      var result = value;\n      if (result instanceof LazyWrapper) {\n        result = result.value();\n      }\n      var index = -1,\n          length = actions.length;\n\n      while (++index < length) {\n        var action = actions[index];\n        result = action.func.apply(action.thisArg, arrayPush([result], action.args));\n      }\n      return result;\n    }\n\n    /**\n     * Performs a binary search of `array` to determine the index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function binaryIndex(array, value, retHighest) {\n      var low = 0,\n          high = array ? array.length : low;\n\n      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n        while (low < high) {\n          var mid = (low + high) >>> 1,\n              computed = array[mid];\n\n          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {\n            low = mid + 1;\n          } else {\n            high = mid;\n          }\n        }\n        return high;\n      }\n      return binaryIndexBy(array, value, identity, retHighest);\n    }\n\n    /**\n     * This function is like `binaryIndex` except that it invokes `iteratee` for\n     * `value` and each element of `array` to compute their sort ranking. The\n     * iteratee is invoked with one argument; (value).\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function binaryIndexBy(array, value, iteratee, retHighest) {\n      value = iteratee(value);\n\n      var low = 0,\n          high = array ? array.length : 0,\n          valIsNaN = value !== value,\n          valIsNull = value === null,\n          valIsUndef = value === undefined;\n\n      while (low < high) {\n        var mid = nativeFloor((low + high) / 2),\n            computed = iteratee(array[mid]),\n            isDef = computed !== undefined,\n            isReflexive = computed === computed;\n\n        if (valIsNaN) {\n          var setLow = isReflexive || retHighest;\n        } else if (valIsNull) {\n          setLow = isReflexive && isDef && (retHighest || computed != null);\n        } else if (valIsUndef) {\n          setLow = isReflexive && (retHighest || isDef);\n        } else if (computed == null) {\n          setLow = false;\n        } else {\n          setLow = retHighest ? (computed <= value) : (computed < value);\n        }\n        if (setLow) {\n          low = mid + 1;\n        } else {\n          high = mid;\n        }\n      }\n      return nativeMin(high, MAX_ARRAY_INDEX);\n    }\n\n    /**\n     * A specialized version of `baseCallback` which only supports `this` binding\n     * and specifying the number of arguments to provide to `func`.\n     *\n     * @private\n     * @param {Function} func The function to bind.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {number} [argCount] The number of arguments to provide to `func`.\n     * @returns {Function} Returns the callback.\n     */\n    function bindCallback(func, thisArg, argCount) {\n      if (typeof func != 'function') {\n        return identity;\n      }\n      if (thisArg === undefined) {\n        return func;\n      }\n      switch (argCount) {\n        case 1: return function(value) {\n          return func.call(thisArg, value);\n        };\n        case 3: return function(value, index, collection) {\n          return func.call(thisArg, value, index, collection);\n        };\n        case 4: return function(accumulator, value, index, collection) {\n          return func.call(thisArg, accumulator, value, index, collection);\n        };\n        case 5: return function(value, other, key, object, source) {\n          return func.call(thisArg, value, other, key, object, source);\n        };\n      }\n      return function() {\n        return func.apply(thisArg, arguments);\n      };\n    }\n\n    /**\n     * Creates a clone of the given array buffer.\n     *\n     * @private\n     * @param {ArrayBuffer} buffer The array buffer to clone.\n     * @returns {ArrayBuffer} Returns the cloned array buffer.\n     */\n    function bufferClone(buffer) {\n      var result = new ArrayBuffer(buffer.byteLength),\n          view = new Uint8Array(result);\n\n      view.set(new Uint8Array(buffer));\n      return result;\n    }\n\n    /**\n     * Creates an array that is the composition of partially applied arguments,\n     * placeholders, and provided arguments into a single array of arguments.\n     *\n     * @private\n     * @param {Array|Object} args The provided arguments.\n     * @param {Array} partials The arguments to prepend to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgs(args, partials, holders) {\n      var holdersLength = holders.length,\n          argsIndex = -1,\n          argsLength = nativeMax(args.length - holdersLength, 0),\n          leftIndex = -1,\n          leftLength = partials.length,\n          result = Array(leftLength + argsLength);\n\n      while (++leftIndex < leftLength) {\n        result[leftIndex] = partials[leftIndex];\n      }\n      while (++argsIndex < holdersLength) {\n        result[holders[argsIndex]] = args[argsIndex];\n      }\n      while (argsLength--) {\n        result[leftIndex++] = args[argsIndex++];\n      }\n      return result;\n    }\n\n    /**\n     * This function is like `composeArgs` except that the arguments composition\n     * is tailored for `_.partialRight`.\n     *\n     * @private\n     * @param {Array|Object} args The provided arguments.\n     * @param {Array} partials The arguments to append to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgsRight(args, partials, holders) {\n      var holdersIndex = -1,\n          holdersLength = holders.length,\n          argsIndex = -1,\n          argsLength = nativeMax(args.length - holdersLength, 0),\n          rightIndex = -1,\n          rightLength = partials.length,\n          result = Array(argsLength + rightLength);\n\n      while (++argsIndex < argsLength) {\n        result[argsIndex] = args[argsIndex];\n      }\n      var offset = argsIndex;\n      while (++rightIndex < rightLength) {\n        result[offset + rightIndex] = partials[rightIndex];\n      }\n      while (++holdersIndex < holdersLength) {\n        result[offset + holders[holdersIndex]] = args[argsIndex++];\n      }\n      return result;\n    }\n\n    /**\n     * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.\n     *\n     * @private\n     * @param {Function} setter The function to set keys and values of the accumulator object.\n     * @param {Function} [initializer] The function to initialize the accumulator object.\n     * @returns {Function} Returns the new aggregator function.\n     */\n    function createAggregator(setter, initializer) {\n      return function(collection, iteratee, thisArg) {\n        var result = initializer ? initializer() : {};\n        iteratee = getCallback(iteratee, thisArg, 3);\n\n        if (isArray(collection)) {\n          var index = -1,\n              length = collection.length;\n\n          while (++index < length) {\n            var value = collection[index];\n            setter(result, value, iteratee(value, index, collection), collection);\n          }\n        } else {\n          baseEach(collection, function(value, key, collection) {\n            setter(result, value, iteratee(value, key, collection), collection);\n          });\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a `_.assign`, `_.defaults`, or `_.merge` function.\n     *\n     * @private\n     * @param {Function} assigner The function to assign values.\n     * @returns {Function} Returns the new assigner function.\n     */\n    function createAssigner(assigner) {\n      return restParam(function(object, sources) {\n        var index = -1,\n            length = object == null ? 0 : sources.length,\n            customizer = length > 2 ? sources[length - 2] : undefined,\n            guard = length > 2 ? sources[2] : undefined,\n            thisArg = length > 1 ? sources[length - 1] : undefined;\n\n        if (typeof customizer == 'function') {\n          customizer = bindCallback(customizer, thisArg, 5);\n          length -= 2;\n        } else {\n          customizer = typeof thisArg == 'function' ? thisArg : undefined;\n          length -= (customizer ? 1 : 0);\n        }\n        if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n          customizer = length < 3 ? undefined : customizer;\n          length = 1;\n        }\n        while (++index < length) {\n          var source = sources[index];\n          if (source) {\n            assigner(object, source, customizer);\n          }\n        }\n        return object;\n      });\n    }\n\n    /**\n     * Creates a `baseEach` or `baseEachRight` function.\n     *\n     * @private\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseEach(eachFunc, fromRight) {\n      return function(collection, iteratee) {\n        var length = collection ? getLength(collection) : 0;\n        if (!isLength(length)) {\n          return eachFunc(collection, iteratee);\n        }\n        var index = fromRight ? length : -1,\n            iterable = toObject(collection);\n\n        while ((fromRight ? index-- : ++index < length)) {\n          if (iteratee(iterable[index], index, iterable) === false) {\n            break;\n          }\n        }\n        return collection;\n      };\n    }\n\n    /**\n     * Creates a base function for `_.forIn` or `_.forInRight`.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseFor(fromRight) {\n      return function(object, iteratee, keysFunc) {\n        var iterable = toObject(object),\n            props = keysFunc(object),\n            length = props.length,\n            index = fromRight ? length : -1;\n\n        while ((fromRight ? index-- : ++index < length)) {\n          var key = props[index];\n          if (iteratee(iterable[key], key, iterable) === false) {\n            break;\n          }\n        }\n        return object;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` and invokes it with the `this`\n     * binding of `thisArg`.\n     *\n     * @private\n     * @param {Function} func The function to bind.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @returns {Function} Returns the new bound function.\n     */\n    function createBindWrapper(func, thisArg) {\n      var Ctor = createCtorWrapper(func);\n\n      function wrapper() {\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return fn.apply(thisArg, arguments);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `Set` cache object to optimize linear searches of large arrays.\n     *\n     * @private\n     * @param {Array} [values] The values to cache.\n     * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.\n     */\n    function createCache(values) {\n      return (nativeCreate && Set) ? new SetCache(values) : null;\n    }\n\n    /**\n     * Creates a function that produces compound words out of the words in a\n     * given string.\n     *\n     * @private\n     * @param {Function} callback The function to combine each word.\n     * @returns {Function} Returns the new compounder function.\n     */\n    function createCompounder(callback) {\n      return function(string) {\n        var index = -1,\n            array = words(deburr(string)),\n            length = array.length,\n            result = '';\n\n        while (++index < length) {\n          result = callback(result, array[index], index);\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function that produces an instance of `Ctor` regardless of\n     * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n     *\n     * @private\n     * @param {Function} Ctor The constructor to wrap.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCtorWrapper(Ctor) {\n      return function() {\n        // Use a `switch` statement to work with class constructors.\n        // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n        // for more details.\n        var args = arguments;\n        switch (args.length) {\n          case 0: return new Ctor;\n          case 1: return new Ctor(args[0]);\n          case 2: return new Ctor(args[0], args[1]);\n          case 3: return new Ctor(args[0], args[1], args[2]);\n          case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n        }\n        var thisBinding = baseCreate(Ctor.prototype),\n            result = Ctor.apply(thisBinding, args);\n\n        // Mimic the constructor's `return` behavior.\n        // See https://es5.github.io/#x13.2.2 for more details.\n        return isObject(result) ? result : thisBinding;\n      };\n    }\n\n    /**\n     * Creates a `_.curry` or `_.curryRight` function.\n     *\n     * @private\n     * @param {boolean} flag The curry bit flag.\n     * @returns {Function} Returns the new curry function.\n     */\n    function createCurry(flag) {\n      function curryFunc(func, arity, guard) {\n        if (guard && isIterateeCall(func, arity, guard)) {\n          arity = undefined;\n        }\n        var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);\n        result.placeholder = curryFunc.placeholder;\n        return result;\n      }\n      return curryFunc;\n    }\n\n    /**\n     * Creates a `_.defaults` or `_.defaultsDeep` function.\n     *\n     * @private\n     * @param {Function} assigner The function to assign values.\n     * @param {Function} customizer The function to customize assigned values.\n     * @returns {Function} Returns the new defaults function.\n     */\n    function createDefaults(assigner, customizer) {\n      return restParam(function(args) {\n        var object = args[0];\n        if (object == null) {\n          return object;\n        }\n        args.push(customizer);\n        return assigner.apply(undefined, args);\n      });\n    }\n\n    /**\n     * Creates a `_.max` or `_.min` function.\n     *\n     * @private\n     * @param {Function} comparator The function used to compare values.\n     * @param {*} exValue The initial extremum value.\n     * @returns {Function} Returns the new extremum function.\n     */\n    function createExtremum(comparator, exValue) {\n      return function(collection, iteratee, thisArg) {\n        if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {\n          iteratee = undefined;\n        }\n        iteratee = getCallback(iteratee, thisArg, 3);\n        if (iteratee.length == 1) {\n          collection = isArray(collection) ? collection : toIterable(collection);\n          var result = arrayExtremum(collection, iteratee, comparator, exValue);\n          if (!(collection.length && result === exValue)) {\n            return result;\n          }\n        }\n        return baseExtremum(collection, iteratee, comparator, exValue);\n      };\n    }\n\n    /**\n     * Creates a `_.find` or `_.findLast` function.\n     *\n     * @private\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new find function.\n     */\n    function createFind(eachFunc, fromRight) {\n      return function(collection, predicate, thisArg) {\n        predicate = getCallback(predicate, thisArg, 3);\n        if (isArray(collection)) {\n          var index = baseFindIndex(collection, predicate, fromRight);\n          return index > -1 ? collection[index] : undefined;\n        }\n        return baseFind(collection, predicate, eachFunc);\n      };\n    }\n\n    /**\n     * Creates a `_.findIndex` or `_.findLastIndex` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new find function.\n     */\n    function createFindIndex(fromRight) {\n      return function(array, predicate, thisArg) {\n        if (!(array && array.length)) {\n          return -1;\n        }\n        predicate = getCallback(predicate, thisArg, 3);\n        return baseFindIndex(array, predicate, fromRight);\n      };\n    }\n\n    /**\n     * Creates a `_.findKey` or `_.findLastKey` function.\n     *\n     * @private\n     * @param {Function} objectFunc The function to iterate over an object.\n     * @returns {Function} Returns the new find function.\n     */\n    function createFindKey(objectFunc) {\n      return function(object, predicate, thisArg) {\n        predicate = getCallback(predicate, thisArg, 3);\n        return baseFind(object, predicate, objectFunc, true);\n      };\n    }\n\n    /**\n     * Creates a `_.flow` or `_.flowRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new flow function.\n     */\n    function createFlow(fromRight) {\n      return function() {\n        var wrapper,\n            length = arguments.length,\n            index = fromRight ? length : -1,\n            leftIndex = 0,\n            funcs = Array(length);\n\n        while ((fromRight ? index-- : ++index < length)) {\n          var func = funcs[leftIndex++] = arguments[index];\n          if (typeof func != 'function') {\n            throw new TypeError(FUNC_ERROR_TEXT);\n          }\n          if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {\n            wrapper = new LodashWrapper([], true);\n          }\n        }\n        index = wrapper ? -1 : length;\n        while (++index < length) {\n          func = funcs[index];\n\n          var funcName = getFuncName(func),\n              data = funcName == 'wrapper' ? getData(func) : undefined;\n\n          if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {\n            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n          } else {\n            wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);\n          }\n        }\n        return function() {\n          var args = arguments,\n              value = args[0];\n\n          if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {\n            return wrapper.plant(value).value();\n          }\n          var index = 0,\n              result = length ? funcs[index].apply(this, args) : value;\n\n          while (++index < length) {\n            result = funcs[index].call(this, result);\n          }\n          return result;\n        };\n      };\n    }\n\n    /**\n     * Creates a function for `_.forEach` or `_.forEachRight`.\n     *\n     * @private\n     * @param {Function} arrayFunc The function to iterate over an array.\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @returns {Function} Returns the new each function.\n     */\n    function createForEach(arrayFunc, eachFunc) {\n      return function(collection, iteratee, thisArg) {\n        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))\n          ? arrayFunc(collection, iteratee)\n          : eachFunc(collection, bindCallback(iteratee, thisArg, 3));\n      };\n    }\n\n    /**\n     * Creates a function for `_.forIn` or `_.forInRight`.\n     *\n     * @private\n     * @param {Function} objectFunc The function to iterate over an object.\n     * @returns {Function} Returns the new each function.\n     */\n    function createForIn(objectFunc) {\n      return function(object, iteratee, thisArg) {\n        if (typeof iteratee != 'function' || thisArg !== undefined) {\n          iteratee = bindCallback(iteratee, thisArg, 3);\n        }\n        return objectFunc(object, iteratee, keysIn);\n      };\n    }\n\n    /**\n     * Creates a function for `_.forOwn` or `_.forOwnRight`.\n     *\n     * @private\n     * @param {Function} objectFunc The function to iterate over an object.\n     * @returns {Function} Returns the new each function.\n     */\n    function createForOwn(objectFunc) {\n      return function(object, iteratee, thisArg) {\n        if (typeof iteratee != 'function' || thisArg !== undefined) {\n          iteratee = bindCallback(iteratee, thisArg, 3);\n        }\n        return objectFunc(object, iteratee);\n      };\n    }\n\n    /**\n     * Creates a function for `_.mapKeys` or `_.mapValues`.\n     *\n     * @private\n     * @param {boolean} [isMapKeys] Specify mapping keys instead of values.\n     * @returns {Function} Returns the new map function.\n     */\n    function createObjectMapper(isMapKeys) {\n      return function(object, iteratee, thisArg) {\n        var result = {};\n        iteratee = getCallback(iteratee, thisArg, 3);\n\n        baseForOwn(object, function(value, key, object) {\n          var mapped = iteratee(value, key, object);\n          key = isMapKeys ? mapped : key;\n          value = isMapKeys ? value : mapped;\n          result[key] = value;\n        });\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function for `_.padLeft` or `_.padRight`.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify padding from the right.\n     * @returns {Function} Returns the new pad function.\n     */\n    function createPadDir(fromRight) {\n      return function(string, length, chars) {\n        string = baseToString(string);\n        return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);\n      };\n    }\n\n    /**\n     * Creates a `_.partial` or `_.partialRight` function.\n     *\n     * @private\n     * @param {boolean} flag The partial bit flag.\n     * @returns {Function} Returns the new partial function.\n     */\n    function createPartial(flag) {\n      var partialFunc = restParam(function(func, partials) {\n        var holders = replaceHolders(partials, partialFunc.placeholder);\n        return createWrapper(func, flag, undefined, partials, holders);\n      });\n      return partialFunc;\n    }\n\n    /**\n     * Creates a function for `_.reduce` or `_.reduceRight`.\n     *\n     * @private\n     * @param {Function} arrayFunc The function to iterate over an array.\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @returns {Function} Returns the new each function.\n     */\n    function createReduce(arrayFunc, eachFunc) {\n      return function(collection, iteratee, accumulator, thisArg) {\n        var initFromArray = arguments.length < 3;\n        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))\n          ? arrayFunc(collection, iteratee, accumulator, initFromArray)\n          : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` and invokes it with optional `this`\n     * binding of, partial application, and currying.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to reference.\n     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [partialsRight] The arguments to append to those provided to the new function.\n     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n      var isAry = bitmask & ARY_FLAG,\n          isBind = bitmask & BIND_FLAG,\n          isBindKey = bitmask & BIND_KEY_FLAG,\n          isCurry = bitmask & CURRY_FLAG,\n          isCurryBound = bitmask & CURRY_BOUND_FLAG,\n          isCurryRight = bitmask & CURRY_RIGHT_FLAG,\n          Ctor = isBindKey ? undefined : createCtorWrapper(func);\n\n      function wrapper() {\n        // Avoid `arguments` object use disqualifying optimizations by\n        // converting it to an array before providing it to other functions.\n        var length = arguments.length,\n            index = length,\n            args = Array(length);\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        if (partials) {\n          args = composeArgs(args, partials, holders);\n        }\n        if (partialsRight) {\n          args = composeArgsRight(args, partialsRight, holdersRight);\n        }\n        if (isCurry || isCurryRight) {\n          var placeholder = wrapper.placeholder,\n              argsHolders = replaceHolders(args, placeholder);\n\n          length -= argsHolders.length;\n          if (length < arity) {\n            var newArgPos = argPos ? arrayCopy(argPos) : undefined,\n                newArity = nativeMax(arity - length, 0),\n                newsHolders = isCurry ? argsHolders : undefined,\n                newHoldersRight = isCurry ? undefined : argsHolders,\n                newPartials = isCurry ? args : undefined,\n                newPartialsRight = isCurry ? undefined : args;\n\n            bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);\n            bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);\n\n            if (!isCurryBound) {\n              bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);\n            }\n            var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],\n                result = createHybridWrapper.apply(undefined, newData);\n\n            if (isLaziable(func)) {\n              setData(result, newData);\n            }\n            result.placeholder = placeholder;\n            return result;\n          }\n        }\n        var thisBinding = isBind ? thisArg : this,\n            fn = isBindKey ? thisBinding[func] : func;\n\n        if (argPos) {\n          args = reorder(args, argPos);\n        }\n        if (isAry && ary < args.length) {\n          args.length = ary;\n        }\n        if (this && this !== root && this instanceof wrapper) {\n          fn = Ctor || createCtorWrapper(func);\n        }\n        return fn.apply(thisBinding, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates the padding required for `string` based on the given `length`.\n     * The `chars` string is truncated if the number of characters exceeds `length`.\n     *\n     * @private\n     * @param {string} string The string to create padding for.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the pad for `string`.\n     */\n    function createPadding(string, length, chars) {\n      var strLength = string.length;\n      length = +length;\n\n      if (strLength >= length || !nativeIsFinite(length)) {\n        return '';\n      }\n      var padLength = length - strLength;\n      chars = chars == null ? ' ' : (chars + '');\n      return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);\n    }\n\n    /**\n     * Creates a function that wraps `func` and invokes it with the optional `this`\n     * binding of `thisArg` and the `partials` prepended to those provided to\n     * the wrapper.\n     *\n     * @private\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {Array} partials The arguments to prepend to those provided to the new function.\n     * @returns {Function} Returns the new bound function.\n     */\n    function createPartialWrapper(func, bitmask, thisArg, partials) {\n      var isBind = bitmask & BIND_FLAG,\n          Ctor = createCtorWrapper(func);\n\n      function wrapper() {\n        // Avoid `arguments` object use disqualifying optimizations by\n        // converting it to an array before providing it `func`.\n        var argsIndex = -1,\n            argsLength = arguments.length,\n            leftIndex = -1,\n            leftLength = partials.length,\n            args = Array(leftLength + argsLength);\n\n        while (++leftIndex < leftLength) {\n          args[leftIndex] = partials[leftIndex];\n        }\n        while (argsLength--) {\n          args[leftIndex++] = arguments[++argsIndex];\n        }\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return fn.apply(isBind ? thisArg : this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.ceil`, `_.floor`, or `_.round` function.\n     *\n     * @private\n     * @param {string} methodName The name of the `Math` method to use when rounding.\n     * @returns {Function} Returns the new round function.\n     */\n    function createRound(methodName) {\n      var func = Math[methodName];\n      return function(number, precision) {\n        precision = precision === undefined ? 0 : (+precision || 0);\n        if (precision) {\n          precision = pow(10, precision);\n          return func(number * precision) / precision;\n        }\n        return func(number);\n      };\n    }\n\n    /**\n     * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.\n     *\n     * @private\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {Function} Returns the new index function.\n     */\n    function createSortedIndex(retHighest) {\n      return function(array, value, iteratee, thisArg) {\n        var callback = getCallback(iteratee);\n        return (iteratee == null && callback === baseCallback)\n          ? binaryIndex(array, value, retHighest)\n          : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest);\n      };\n    }\n\n    /**\n     * Creates a function that either curries or invokes `func` with optional\n     * `this` binding and partially applied arguments.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to reference.\n     * @param {number} bitmask The bitmask of flags.\n     *  The bitmask may be composed of the following flags:\n     *     1 - `_.bind`\n     *     2 - `_.bindKey`\n     *     4 - `_.curry` or `_.curryRight` of a bound function\n     *     8 - `_.curry`\n     *    16 - `_.curryRight`\n     *    32 - `_.partial`\n     *    64 - `_.partialRight`\n     *   128 - `_.rearg`\n     *   256 - `_.ary`\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to be partially applied.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n      var isBindKey = bitmask & BIND_KEY_FLAG;\n      if (!isBindKey && typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var length = partials ? partials.length : 0;\n      if (!length) {\n        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);\n        partials = holders = undefined;\n      }\n      length -= (holders ? holders.length : 0);\n      if (bitmask & PARTIAL_RIGHT_FLAG) {\n        var partialsRight = partials,\n            holdersRight = holders;\n\n        partials = holders = undefined;\n      }\n      var data = isBindKey ? undefined : getData(func),\n          newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];\n\n      if (data) {\n        mergeData(newData, data);\n        bitmask = newData[1];\n        arity = newData[9];\n      }\n      newData[9] = arity == null\n        ? (isBindKey ? 0 : func.length)\n        : (nativeMax(arity - length, 0) || 0);\n\n      if (bitmask == BIND_FLAG) {\n        var result = createBindWrapper(newData[0], newData[2]);\n      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {\n        result = createPartialWrapper.apply(undefined, newData);\n      } else {\n        result = createHybridWrapper.apply(undefined, newData);\n      }\n      var setter = data ? baseSetData : setData;\n      return setter(result, newData);\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for arrays with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Array} array The array to compare.\n     * @param {Array} other The other array to compare.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Function} [customizer] The function to customize comparing arrays.\n     * @param {boolean} [isLoose] Specify performing partial comparisons.\n     * @param {Array} [stackA] Tracks traversed `value` objects.\n     * @param {Array} [stackB] Tracks traversed `other` objects.\n     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n     */\n    function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {\n      var index = -1,\n          arrLength = array.length,\n          othLength = other.length;\n\n      if (arrLength != othLength && !(isLoose && othLength > arrLength)) {\n        return false;\n      }\n      // Ignore non-index properties.\n      while (++index < arrLength) {\n        var arrValue = array[index],\n            othValue = other[index],\n            result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;\n\n        if (result !== undefined) {\n          if (result) {\n            continue;\n          }\n          return false;\n        }\n        // Recursively compare arrays (susceptible to call stack limits).\n        if (isLoose) {\n          if (!arraySome(other, function(othValue) {\n                return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);\n              })) {\n            return false;\n          }\n        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for comparing objects of\n     * the same `toStringTag`.\n     *\n     * **Note:** This function only supports comparing values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {string} tag The `toStringTag` of the objects to compare.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalByTag(object, other, tag) {\n      switch (tag) {\n        case boolTag:\n        case dateTag:\n          // Coerce dates and booleans to numbers, dates to milliseconds and booleans\n          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.\n          return +object == +other;\n\n        case errorTag:\n          return object.name == other.name && object.message == other.message;\n\n        case numberTag:\n          // Treat `NaN` vs. `NaN` as equal.\n          return (object != +object)\n            ? other != +other\n            : object == +other;\n\n        case regexpTag:\n        case stringTag:\n          // Coerce regexes to strings and treat strings primitives and string\n          // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.\n          return object == (other + '');\n      }\n      return false;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for objects with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Function} [customizer] The function to customize comparing values.\n     * @param {boolean} [isLoose] Specify performing partial comparisons.\n     * @param {Array} [stackA] Tracks traversed `value` objects.\n     * @param {Array} [stackB] Tracks traversed `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {\n      var objProps = keys(object),\n          objLength = objProps.length,\n          othProps = keys(other),\n          othLength = othProps.length;\n\n      if (objLength != othLength && !isLoose) {\n        return false;\n      }\n      var index = objLength;\n      while (index--) {\n        var key = objProps[index];\n        if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {\n          return false;\n        }\n      }\n      var skipCtor = isLoose;\n      while (++index < objLength) {\n        key = objProps[index];\n        var objValue = object[key],\n            othValue = other[key],\n            result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;\n\n        // Recursively compare objects (susceptible to call stack limits).\n        if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {\n          return false;\n        }\n        skipCtor || (skipCtor = key == 'constructor');\n      }\n      if (!skipCtor) {\n        var objCtor = object.constructor,\n            othCtor = other.constructor;\n\n        // Non `Object` object instances with different constructors are not equal.\n        if (objCtor != othCtor &&\n            ('constructor' in object && 'constructor' in other) &&\n            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n              typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * Gets the appropriate \"callback\" function. If the `_.callback` method is\n     * customized this function returns the custom method, otherwise it returns\n     * the `baseCallback` function. If arguments are provided the chosen function\n     * is invoked with them and its result is returned.\n     *\n     * @private\n     * @returns {Function} Returns the chosen function or its result.\n     */\n    function getCallback(func, thisArg, argCount) {\n      var result = lodash.callback || callback;\n      result = result === callback ? baseCallback : result;\n      return argCount ? result(func, thisArg, argCount) : result;\n    }\n\n    /**\n     * Gets metadata for `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {*} Returns the metadata for `func`.\n     */\n    var getData = !metaMap ? noop : function(func) {\n      return metaMap.get(func);\n    };\n\n    /**\n     * Gets the name of `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {string} Returns the function name.\n     */\n    function getFuncName(func) {\n      var result = func.name,\n          array = realNames[result],\n          length = array ? array.length : 0;\n\n      while (length--) {\n        var data = array[length],\n            otherFunc = data.func;\n        if (otherFunc == null || otherFunc == func) {\n          return data.name;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Gets the appropriate \"indexOf\" function. If the `_.indexOf` method is\n     * customized this function returns the custom method, otherwise it returns\n     * the `baseIndexOf` function. If arguments are provided the chosen function\n     * is invoked with them and its result is returned.\n     *\n     * @private\n     * @returns {Function|number} Returns the chosen function or its result.\n     */\n    function getIndexOf(collection, target, fromIndex) {\n      var result = lodash.indexOf || indexOf;\n      result = result === indexOf ? baseIndexOf : result;\n      return collection ? result(collection, target, fromIndex) : result;\n    }\n\n    /**\n     * Gets the \"length\" property value of `object`.\n     *\n     * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n     * that affects Safari on at least iOS 8.1-8.3 ARM64.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {*} Returns the \"length\" value.\n     */\n    var getLength = baseProperty('length');\n\n    /**\n     * Gets the propery names, values, and compare flags of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the match data of `object`.\n     */\n    function getMatchData(object) {\n      var result = pairs(object),\n          length = result.length;\n\n      while (length--) {\n        result[length][2] = isStrictComparable(result[length][1]);\n      }\n      return result;\n    }\n\n    /**\n     * Gets the native function at `key` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {string} key The key of the method to get.\n     * @returns {*} Returns the function if it's native, else `undefined`.\n     */\n    function getNative(object, key) {\n      var value = object == null ? undefined : object[key];\n      return isNative(value) ? value : undefined;\n    }\n\n    /**\n     * Gets the view, applying any `transforms` to the `start` and `end` positions.\n     *\n     * @private\n     * @param {number} start The start of the view.\n     * @param {number} end The end of the view.\n     * @param {Array} transforms The transformations to apply to the view.\n     * @returns {Object} Returns an object containing the `start` and `end`\n     *  positions of the view.\n     */\n    function getView(start, end, transforms) {\n      var index = -1,\n          length = transforms.length;\n\n      while (++index < length) {\n        var data = transforms[index],\n            size = data.size;\n\n        switch (data.type) {\n          case 'drop':      start += size; break;\n          case 'dropRight': end -= size; break;\n          case 'take':      end = nativeMin(end, start + size); break;\n          case 'takeRight': start = nativeMax(start, end - size); break;\n        }\n      }\n      return { 'start': start, 'end': end };\n    }\n\n    /**\n     * Initializes an array clone.\n     *\n     * @private\n     * @param {Array} array The array to clone.\n     * @returns {Array} Returns the initialized clone.\n     */\n    function initCloneArray(array) {\n      var length = array.length,\n          result = new array.constructor(length);\n\n      // Add array properties assigned by `RegExp#exec`.\n      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n        result.index = array.index;\n        result.input = array.input;\n      }\n      return result;\n    }\n\n    /**\n     * Initializes an object clone.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneObject(object) {\n      var Ctor = object.constructor;\n      if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {\n        Ctor = Object;\n      }\n      return new Ctor;\n    }\n\n    /**\n     * Initializes an object clone based on its `toStringTag`.\n     *\n     * **Note:** This function only supports cloning values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @param {string} tag The `toStringTag` of the object to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneByTag(object, tag, isDeep) {\n      var Ctor = object.constructor;\n      switch (tag) {\n        case arrayBufferTag:\n          return bufferClone(object);\n\n        case boolTag:\n        case dateTag:\n          return new Ctor(+object);\n\n        case float32Tag: case float64Tag:\n        case int8Tag: case int16Tag: case int32Tag:\n        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n          var buffer = object.buffer;\n          return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);\n\n        case numberTag:\n        case stringTag:\n          return new Ctor(object);\n\n        case regexpTag:\n          var result = new Ctor(object.source, reFlags.exec(object));\n          result.lastIndex = object.lastIndex;\n      }\n      return result;\n    }\n\n    /**\n     * Invokes the method at `path` on `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {Array} args The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     */\n    function invokePath(object, path, args) {\n      if (object != null && !isKey(path, object)) {\n        path = toPath(path);\n        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));\n        path = last(path);\n      }\n      var func = object == null ? object : object[path];\n      return func == null ? undefined : func.apply(object, args);\n    }\n\n    /**\n     * Checks if `value` is array-like.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n     */\n    function isArrayLike(value) {\n      return value != null && isLength(getLength(value));\n    }\n\n    /**\n     * Checks if `value` is a valid array-like index.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n     */\n    function isIndex(value, length) {\n      value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n      length = length == null ? MAX_SAFE_INTEGER : length;\n      return value > -1 && value % 1 == 0 && value < length;\n    }\n\n    /**\n     * Checks if the provided arguments are from an iteratee call.\n     *\n     * @private\n     * @param {*} value The potential iteratee value argument.\n     * @param {*} index The potential iteratee index or key argument.\n     * @param {*} object The potential iteratee object argument.\n     * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n     */\n    function isIterateeCall(value, index, object) {\n      if (!isObject(object)) {\n        return false;\n      }\n      var type = typeof index;\n      if (type == 'number'\n          ? (isArrayLike(object) && isIndex(index, object.length))\n          : (type == 'string' && index in object)) {\n        var other = object[index];\n        return value === value ? (value === other) : (other !== other);\n      }\n      return false;\n    }\n\n    /**\n     * Checks if `value` is a property name and not a property path.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n     */\n    function isKey(value, object) {\n      var type = typeof value;\n      if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {\n        return true;\n      }\n      if (isArray(value)) {\n        return false;\n      }\n      var result = !reIsDeepProp.test(value);\n      return result || (object != null && value in toObject(object));\n    }\n\n    /**\n     * Checks if `func` has a lazy counterpart.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.\n     */\n    function isLaziable(func) {\n      var funcName = getFuncName(func);\n      if (!(funcName in LazyWrapper.prototype)) {\n        return false;\n      }\n      var other = lodash[funcName];\n      if (func === other) {\n        return true;\n      }\n      var data = getData(other);\n      return !!data && func === data[0];\n    }\n\n    /**\n     * Checks if `value` is a valid array-like length.\n     *\n     * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n     */\n    function isLength(value) {\n      return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` if suitable for strict\n     *  equality comparisons, else `false`.\n     */\n    function isStrictComparable(value) {\n      return value === value && !isObject(value);\n    }\n\n    /**\n     * Merges the function metadata of `source` into `data`.\n     *\n     * Merging metadata reduces the number of wrappers required to invoke a function.\n     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n     * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`\n     * augment function arguments, making the order in which they are executed important,\n     * preventing the merging of metadata. However, we make an exception for a safe\n     * common case where curried functions have `_.ary` and or `_.rearg` applied.\n     *\n     * @private\n     * @param {Array} data The destination metadata.\n     * @param {Array} source The source metadata.\n     * @returns {Array} Returns `data`.\n     */\n    function mergeData(data, source) {\n      var bitmask = data[1],\n          srcBitmask = source[1],\n          newBitmask = bitmask | srcBitmask,\n          isCommon = newBitmask < ARY_FLAG;\n\n      var isCombo =\n        (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||\n        (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||\n        (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);\n\n      // Exit early if metadata can't be merged.\n      if (!(isCommon || isCombo)) {\n        return data;\n      }\n      // Use source `thisArg` if available.\n      if (srcBitmask & BIND_FLAG) {\n        data[2] = source[2];\n        // Set when currying a bound function.\n        newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;\n      }\n      // Compose partial arguments.\n      var value = source[3];\n      if (value) {\n        var partials = data[3];\n        data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);\n        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);\n      }\n      // Compose partial right arguments.\n      value = source[5];\n      if (value) {\n        partials = data[5];\n        data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);\n        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);\n      }\n      // Use source `argPos` if available.\n      value = source[7];\n      if (value) {\n        data[7] = arrayCopy(value);\n      }\n      // Use source `ary` if it's smaller.\n      if (srcBitmask & ARY_FLAG) {\n        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n      }\n      // Use source `arity` if one is not provided.\n      if (data[9] == null) {\n        data[9] = source[9];\n      }\n      // Use source `func` and merge bitmasks.\n      data[0] = source[0];\n      data[1] = newBitmask;\n\n      return data;\n    }\n\n    /**\n     * Used by `_.defaultsDeep` to customize its `_.merge` use.\n     *\n     * @private\n     * @param {*} objectValue The destination object property value.\n     * @param {*} sourceValue The source object property value.\n     * @returns {*} Returns the value to assign to the destination object.\n     */\n    function mergeDefaults(objectValue, sourceValue) {\n      return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);\n    }\n\n    /**\n     * A specialized version of `_.pick` which picks `object` properties specified\n     * by `props`.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} props The property names to pick.\n     * @returns {Object} Returns the new object.\n     */\n    function pickByArray(object, props) {\n      object = toObject(object);\n\n      var index = -1,\n          length = props.length,\n          result = {};\n\n      while (++index < length) {\n        var key = props[index];\n        if (key in object) {\n          result[key] = object[key];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `_.pick` which picks `object` properties `predicate`\n     * returns truthy for.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {Object} Returns the new object.\n     */\n    function pickByCallback(object, predicate) {\n      var result = {};\n      baseForIn(object, function(value, key, object) {\n        if (predicate(value, key, object)) {\n          result[key] = value;\n        }\n      });\n      return result;\n    }\n\n    /**\n     * Reorder `array` according to the specified indexes where the element at\n     * the first index is assigned as the first element, the element at\n     * the second index is assigned as the second element, and so on.\n     *\n     * @private\n     * @param {Array} array The array to reorder.\n     * @param {Array} indexes The arranged array indexes.\n     * @returns {Array} Returns `array`.\n     */\n    function reorder(array, indexes) {\n      var arrLength = array.length,\n          length = nativeMin(indexes.length, arrLength),\n          oldArray = arrayCopy(array);\n\n      while (length--) {\n        var index = indexes[length];\n        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n      }\n      return array;\n    }\n\n    /**\n     * Sets metadata for `func`.\n     *\n     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n     * period of time, it will trip its breaker and transition to an identity function\n     * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)\n     * for more details.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var setData = (function() {\n      var count = 0,\n          lastCalled = 0;\n\n      return function(key, value) {\n        var stamp = now(),\n            remaining = HOT_SPAN - (stamp - lastCalled);\n\n        lastCalled = stamp;\n        if (remaining > 0) {\n          if (++count >= HOT_COUNT) {\n            return key;\n          }\n        } else {\n          count = 0;\n        }\n        return baseSetData(key, value);\n      };\n    }());\n\n    /**\n     * A fallback implementation of `Object.keys` which creates an array of the\n     * own enumerable property names of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function shimKeys(object) {\n      var props = keysIn(object),\n          propsLength = props.length,\n          length = propsLength && object.length;\n\n      var allowIndexes = !!length && isLength(length) &&\n        (isArray(object) || isArguments(object));\n\n      var index = -1,\n          result = [];\n\n      while (++index < propsLength) {\n        var key = props[index];\n        if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to an array-like object if it's not one.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {Array|Object} Returns the array-like object.\n     */\n    function toIterable(value) {\n      if (value == null) {\n        return [];\n      }\n      if (!isArrayLike(value)) {\n        return values(value);\n      }\n      return isObject(value) ? value : Object(value);\n    }\n\n    /**\n     * Converts `value` to an object if it's not one.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {Object} Returns the object.\n     */\n    function toObject(value) {\n      return isObject(value) ? value : Object(value);\n    }\n\n    /**\n     * Converts `value` to property path array if it's not one.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {Array} Returns the property path array.\n     */\n    function toPath(value) {\n      if (isArray(value)) {\n        return value;\n      }\n      var result = [];\n      baseToString(value).replace(rePropName, function(match, number, quote, string) {\n        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n      });\n      return result;\n    }\n\n    /**\n     * Creates a clone of `wrapper`.\n     *\n     * @private\n     * @param {Object} wrapper The wrapper to clone.\n     * @returns {Object} Returns the cloned wrapper.\n     */\n    function wrapperClone(wrapper) {\n      return wrapper instanceof LazyWrapper\n        ? wrapper.clone()\n        : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of elements split into groups the length of `size`.\n     * If `collection` can't be split evenly, the final chunk will be the remaining\n     * elements.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to process.\n     * @param {number} [size=1] The length of each chunk.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the new array containing chunks.\n     * @example\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 2);\n     * // => [['a', 'b'], ['c', 'd']]\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 3);\n     * // => [['a', 'b', 'c'], ['d']]\n     */\n    function chunk(array, size, guard) {\n      if (guard ? isIterateeCall(array, size, guard) : size == null) {\n        size = 1;\n      } else {\n        size = nativeMax(nativeFloor(size) || 1, 1);\n      }\n      var index = 0,\n          length = array ? array.length : 0,\n          resIndex = -1,\n          result = Array(nativeCeil(length / size));\n\n      while (index < length) {\n        result[++resIndex] = baseSlice(array, index, (index += size));\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array with all falsey values removed. The values `false`, `null`,\n     * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to compact.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.compact([0, 1, false, 2, '', 3]);\n     * // => [1, 2, 3]\n     */\n    function compact(array) {\n      var index = -1,\n          length = array ? array.length : 0,\n          resIndex = -1,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index];\n        if (value) {\n          result[++resIndex] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array of unique `array` values not included in the other\n     * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The arrays of values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.difference([1, 2, 3], [4, 2]);\n     * // => [1, 3]\n     */\n    var difference = restParam(function(array, values) {\n      return (isObjectLike(array) && isArrayLike(array))\n        ? baseDifference(array, baseFlatten(values, false, true))\n        : [];\n    });\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.drop([1, 2, 3]);\n     * // => [2, 3]\n     *\n     * _.drop([1, 2, 3], 2);\n     * // => [3]\n     *\n     * _.drop([1, 2, 3], 5);\n     * // => []\n     *\n     * _.drop([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function drop(array, n, guard) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (guard ? isIterateeCall(array, n, guard) : n == null) {\n        n = 1;\n      }\n      return baseSlice(array, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the end.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.dropRight([1, 2, 3]);\n     * // => [1, 2]\n     *\n     * _.dropRight([1, 2, 3], 2);\n     * // => [1]\n     *\n     * _.dropRight([1, 2, 3], 5);\n     * // => []\n     *\n     * _.dropRight([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function dropRight(array, n, guard) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (guard ? isIterateeCall(array, n, guard) : n == null) {\n        n = 1;\n      }\n      n = length - (+n || 0);\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the end.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * bound to `thisArg` and invoked with three arguments: (value, index, array).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that match the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.dropRightWhile([1, 2, 3], function(n) {\n     *   return n > 1;\n     * });\n     * // => [1]\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');\n     * // => ['barney', 'fred']\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.pluck(_.dropRightWhile(users, 'active', false), 'user');\n     * // => ['barney']\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.dropRightWhile(users, 'active'), 'user');\n     * // => ['barney', 'fred', 'pebbles']\n     */\n    function dropRightWhile(array, predicate, thisArg) {\n      return (array && array.length)\n        ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the beginning.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * bound to `thisArg` and invoked with three arguments: (value, index, array).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.dropWhile([1, 2, 3], function(n) {\n     *   return n < 3;\n     * });\n     * // => [3]\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user');\n     * // => ['fred', 'pebbles']\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.pluck(_.dropWhile(users, 'active', false), 'user');\n     * // => ['pebbles']\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.dropWhile(users, 'active'), 'user');\n     * // => ['barney', 'fred', 'pebbles']\n     */\n    function dropWhile(array, predicate, thisArg) {\n      return (array && array.length)\n        ? baseWhile(array, getCallback(predicate, thisArg, 3), true)\n        : [];\n    }\n\n    /**\n     * Fills elements of `array` with `value` from `start` up to, but not\n     * including, `end`.\n     *\n     * **Note:** This method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.fill(array, 'a');\n     * console.log(array);\n     * // => ['a', 'a', 'a']\n     *\n     * _.fill(Array(3), 2);\n     * // => [2, 2, 2]\n     *\n     * _.fill([4, 6, 8], '*', 1, 2);\n     * // => [4, '*', 8]\n     */\n    function fill(array, value, start, end) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n        start = 0;\n        end = length;\n      }\n      return baseFill(array, value, start, end);\n    }\n\n    /**\n     * This method is like `_.find` except that it returns the index of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to search.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.findIndex(users, function(chr) {\n     *   return chr.user == 'barney';\n     * });\n     * // => 0\n     *\n     * // using the `_.matches` callback shorthand\n     * _.findIndex(users, { 'user': 'fred', 'active': false });\n     * // => 1\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.findIndex(users, 'active', false);\n     * // => 0\n     *\n     * // using the `_.property` callback shorthand\n     * _.findIndex(users, 'active');\n     * // => 2\n     */\n    var findIndex = createFindIndex();\n\n    /**\n     * This method is like `_.findIndex` except that it iterates over elements\n     * of `collection` from right to left.\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to search.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.findLastIndex(users, function(chr) {\n     *   return chr.user == 'pebbles';\n     * });\n     * // => 2\n     *\n     * // using the `_.matches` callback shorthand\n     * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n     * // => 0\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.findLastIndex(users, 'active', false);\n     * // => 2\n     *\n     * // using the `_.property` callback shorthand\n     * _.findLastIndex(users, 'active');\n     * // => 0\n     */\n    var findLastIndex = createFindIndex(true);\n\n    /**\n     * Gets the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @alias head\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the first element of `array`.\n     * @example\n     *\n     * _.first([1, 2, 3]);\n     * // => 1\n     *\n     * _.first([]);\n     * // => undefined\n     */\n    function first(array) {\n      return array ? array[0] : undefined;\n    }\n\n    /**\n     * Flattens a nested array. If `isDeep` is `true` the array is recursively\n     * flattened, otherwise it is only flattened a single level.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @param {boolean} [isDeep] Specify a deep flatten.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flatten([1, [2, 3, [4]]]);\n     * // => [1, 2, 3, [4]]\n     *\n     * // using `isDeep`\n     * _.flatten([1, [2, 3, [4]]], true);\n     * // => [1, 2, 3, 4]\n     */\n    function flatten(array, isDeep, guard) {\n      var length = array ? array.length : 0;\n      if (guard && isIterateeCall(array, isDeep, guard)) {\n        isDeep = false;\n      }\n      return length ? baseFlatten(array, isDeep) : [];\n    }\n\n    /**\n     * Recursively flattens a nested array.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to recursively flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flattenDeep([1, [2, 3, [4]]]);\n     * // => [1, 2, 3, 4]\n     */\n    function flattenDeep(array) {\n      var length = array ? array.length : 0;\n      return length ? baseFlatten(array, true) : [];\n    }\n\n    /**\n     * Gets the index at which the first occurrence of `value` is found in `array`\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons. If `fromIndex` is negative, it is used as the offset\n     * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`\n     * performs a faster binary search.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to search.\n     * @param {*} value The value to search for.\n     * @param {boolean|number} [fromIndex=0] The index to search from or `true`\n     *  to perform a binary search on a sorted array.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.indexOf([1, 2, 1, 2], 2);\n     * // => 1\n     *\n     * // using `fromIndex`\n     * _.indexOf([1, 2, 1, 2], 2, 2);\n     * // => 3\n     *\n     * // performing a binary search\n     * _.indexOf([1, 1, 2, 2], 2, true);\n     * // => 2\n     */\n    function indexOf(array, value, fromIndex) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return -1;\n      }\n      if (typeof fromIndex == 'number') {\n        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;\n      } else if (fromIndex) {\n        var index = binaryIndex(array, value);\n        if (index < length &&\n            (value === value ? (value === array[index]) : (array[index] !== array[index]))) {\n          return index;\n        }\n        return -1;\n      }\n      return baseIndexOf(array, value, fromIndex || 0);\n    }\n\n    /**\n     * Gets all but the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.initial([1, 2, 3]);\n     * // => [1, 2]\n     */\n    function initial(array) {\n      return dropRight(array, 1);\n    }\n\n    /**\n     * Creates an array of unique values that are included in all of the provided\n     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of shared values.\n     * @example\n     * _.intersection([1, 2], [4, 2], [2, 1]);\n     * // => [2]\n     */\n    var intersection = restParam(function(arrays) {\n      var othLength = arrays.length,\n          othIndex = othLength,\n          caches = Array(length),\n          indexOf = getIndexOf(),\n          isCommon = indexOf == baseIndexOf,\n          result = [];\n\n      while (othIndex--) {\n        var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];\n        caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;\n      }\n      var array = arrays[0],\n          index = -1,\n          length = array ? array.length : 0,\n          seen = caches[0];\n\n      outer:\n      while (++index < length) {\n        value = array[index];\n        if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {\n          var othIndex = othLength;\n          while (--othIndex) {\n            var cache = caches[othIndex];\n            if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {\n              continue outer;\n            }\n          }\n          if (seen) {\n            seen.push(value);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    });\n\n    /**\n     * Gets the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the last element of `array`.\n     * @example\n     *\n     * _.last([1, 2, 3]);\n     * // => 3\n     */\n    function last(array) {\n      var length = array ? array.length : 0;\n      return length ? array[length - 1] : undefined;\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it iterates over elements of\n     * `array` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to search.\n     * @param {*} value The value to search for.\n     * @param {boolean|number} [fromIndex=array.length-1] The index to search from\n     *  or `true` to perform a binary search on a sorted array.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.lastIndexOf([1, 2, 1, 2], 2);\n     * // => 3\n     *\n     * // using `fromIndex`\n     * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n     * // => 1\n     *\n     * // performing a binary search\n     * _.lastIndexOf([1, 1, 2, 2], 2, true);\n     * // => 3\n     */\n    function lastIndexOf(array, value, fromIndex) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return -1;\n      }\n      var index = length;\n      if (typeof fromIndex == 'number') {\n        index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;\n      } else if (fromIndex) {\n        index = binaryIndex(array, value, true) - 1;\n        var other = array[index];\n        if (value === value ? (value === other) : (other !== other)) {\n          return index;\n        }\n        return -1;\n      }\n      if (value !== value) {\n        return indexOfNaN(array, index, true);\n      }\n      while (index--) {\n        if (array[index] === value) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * Removes all provided values from `array` using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.without`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...*} [values] The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3, 1, 2, 3];\n     *\n     * _.pull(array, 2, 3);\n     * console.log(array);\n     * // => [1, 1]\n     */\n    function pull() {\n      var args = arguments,\n          array = args[0];\n\n      if (!(array && array.length)) {\n        return array;\n      }\n      var index = 0,\n          indexOf = getIndexOf(),\n          length = args.length;\n\n      while (++index < length) {\n        var fromIndex = 0,\n            value = args[index];\n\n        while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {\n          splice.call(array, fromIndex, 1);\n        }\n      }\n      return array;\n    }\n\n    /**\n     * Removes elements from `array` corresponding to the given indexes and returns\n     * an array of the removed elements. Indexes may be specified as an array of\n     * indexes or as individual arguments.\n     *\n     * **Note:** Unlike `_.at`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...(number|number[])} [indexes] The indexes of elements to remove,\n     *  specified as individual indexes or arrays of indexes.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = [5, 10, 15, 20];\n     * var evens = _.pullAt(array, 1, 3);\n     *\n     * console.log(array);\n     * // => [5, 15]\n     *\n     * console.log(evens);\n     * // => [10, 20]\n     */\n    var pullAt = restParam(function(array, indexes) {\n      indexes = baseFlatten(indexes);\n\n      var result = baseAt(array, indexes);\n      basePullAt(array, indexes.sort(baseCompareAscending));\n      return result;\n    });\n\n    /**\n     * Removes all elements from `array` that `predicate` returns truthy for\n     * and returns an array of the removed elements. The predicate is bound to\n     * `thisArg` and invoked with three arguments: (value, index, array).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * **Note:** Unlike `_.filter`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = [1, 2, 3, 4];\n     * var evens = _.remove(array, function(n) {\n     *   return n % 2 == 0;\n     * });\n     *\n     * console.log(array);\n     * // => [1, 3]\n     *\n     * console.log(evens);\n     * // => [2, 4]\n     */\n    function remove(array, predicate, thisArg) {\n      var result = [];\n      if (!(array && array.length)) {\n        return result;\n      }\n      var index = -1,\n          indexes = [],\n          length = array.length;\n\n      predicate = getCallback(predicate, thisArg, 3);\n      while (++index < length) {\n        var value = array[index];\n        if (predicate(value, index, array)) {\n          result.push(value);\n          indexes.push(index);\n        }\n      }\n      basePullAt(array, indexes);\n      return result;\n    }\n\n    /**\n     * Gets all but the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @alias tail\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.rest([1, 2, 3]);\n     * // => [2, 3]\n     */\n    function rest(array) {\n      return drop(array, 1);\n    }\n\n    /**\n     * Creates a slice of `array` from `start` up to, but not including, `end`.\n     *\n     * **Note:** This method is used instead of `Array#slice` to support node\n     * lists in IE < 9 and to ensure dense arrays are returned.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function slice(array, start, end) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n        start = 0;\n        end = length;\n      }\n      return baseSlice(array, start, end);\n    }\n\n    /**\n     * Uses a binary search to determine the lowest index at which `value` should\n     * be inserted into `array` in order to maintain its sort order. If an iteratee\n     * function is provided it is invoked for `value` and each element of `array`\n     * to compute their sort ranking. The iteratee is bound to `thisArg` and\n     * invoked with one argument; (value).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedIndex([30, 50], 40);\n     * // => 1\n     *\n     * _.sortedIndex([4, 4, 5, 5], 5);\n     * // => 2\n     *\n     * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };\n     *\n     * // using an iteratee function\n     * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) {\n     *   return this.data[word];\n     * }, dict);\n     * // => 1\n     *\n     * // using the `_.property` callback shorthand\n     * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');\n     * // => 1\n     */\n    var sortedIndex = createSortedIndex();\n\n    /**\n     * This method is like `_.sortedIndex` except that it returns the highest\n     * index at which `value` should be inserted into `array` in order to\n     * maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedLastIndex([4, 4, 5, 5], 5);\n     * // => 4\n     */\n    var sortedLastIndex = createSortedIndex(true);\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.take([1, 2, 3]);\n     * // => [1]\n     *\n     * _.take([1, 2, 3], 2);\n     * // => [1, 2]\n     *\n     * _.take([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.take([1, 2, 3], 0);\n     * // => []\n     */\n    function take(array, n, guard) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (guard ? isIterateeCall(array, n, guard) : n == null) {\n        n = 1;\n      }\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the end.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.takeRight([1, 2, 3]);\n     * // => [3]\n     *\n     * _.takeRight([1, 2, 3], 2);\n     * // => [2, 3]\n     *\n     * _.takeRight([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.takeRight([1, 2, 3], 0);\n     * // => []\n     */\n    function takeRight(array, n, guard) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (guard ? isIterateeCall(array, n, guard) : n == null) {\n        n = 1;\n      }\n      n = length - (+n || 0);\n      return baseSlice(array, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the end. Elements are\n     * taken until `predicate` returns falsey. The predicate is bound to `thisArg`\n     * and invoked with three arguments: (value, index, array).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.takeRightWhile([1, 2, 3], function(n) {\n     *   return n > 1;\n     * });\n     * // => [2, 3]\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');\n     * // => ['pebbles']\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.pluck(_.takeRightWhile(users, 'active', false), 'user');\n     * // => ['fred', 'pebbles']\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.takeRightWhile(users, 'active'), 'user');\n     * // => []\n     */\n    function takeRightWhile(array, predicate, thisArg) {\n      return (array && array.length)\n        ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the beginning. Elements\n     * are taken until `predicate` returns falsey. The predicate is bound to\n     * `thisArg` and invoked with three arguments: (value, index, array).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.takeWhile([1, 2, 3], function(n) {\n     *   return n < 3;\n     * });\n     * // => [1, 2]\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false},\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user');\n     * // => ['barney']\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.pluck(_.takeWhile(users, 'active', false), 'user');\n     * // => ['barney', 'fred']\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.takeWhile(users, 'active'), 'user');\n     * // => []\n     */\n    function takeWhile(array, predicate, thisArg) {\n      return (array && array.length)\n        ? baseWhile(array, getCallback(predicate, thisArg, 3))\n        : [];\n    }\n\n    /**\n     * Creates an array of unique values, in order, from all of the provided arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.union([1, 2], [4, 2], [2, 1]);\n     * // => [1, 2, 4]\n     */\n    var union = restParam(function(arrays) {\n      return baseUniq(baseFlatten(arrays, false, true));\n    });\n\n    /**\n     * Creates a duplicate-free version of an array, using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons, in which only the first occurence of each element\n     * is kept. Providing `true` for `isSorted` performs a faster search algorithm\n     * for sorted arrays. If an iteratee function is provided it is invoked for\n     * each element in the array to generate the criterion by which uniqueness\n     * is computed. The `iteratee` is bound to `thisArg` and invoked with three\n     * arguments: (value, index, array).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @alias unique\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {boolean} [isSorted] Specify the array is sorted.\n     * @param {Function|Object|string} [iteratee] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array} Returns the new duplicate-value-free array.\n     * @example\n     *\n     * _.uniq([2, 1, 2]);\n     * // => [2, 1]\n     *\n     * // using `isSorted`\n     * _.uniq([1, 1, 2], true);\n     * // => [1, 2]\n     *\n     * // using an iteratee function\n     * _.uniq([1, 2.5, 1.5, 2], function(n) {\n     *   return this.floor(n);\n     * }, Math);\n     * // => [1, 2.5]\n     *\n     * // using the `_.property` callback shorthand\n     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    function uniq(array, isSorted, iteratee, thisArg) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      if (isSorted != null && typeof isSorted != 'boolean') {\n        thisArg = iteratee;\n        iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;\n        isSorted = false;\n      }\n      var callback = getCallback();\n      if (!(iteratee == null && callback === baseCallback)) {\n        iteratee = callback(iteratee, thisArg, 3);\n      }\n      return (isSorted && getIndexOf() == baseIndexOf)\n        ? sortedUniq(array, iteratee)\n        : baseUniq(array, iteratee);\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts an array of grouped\n     * elements and creates an array regrouping the elements to their pre-zip\n     * configuration.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);\n     * // => [['fred', 30, true], ['barney', 40, false]]\n     *\n     * _.unzip(zipped);\n     * // => [['fred', 'barney'], [30, 40], [true, false]]\n     */\n    function unzip(array) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var index = -1,\n          length = 0;\n\n      array = arrayFilter(array, function(group) {\n        if (isArrayLike(group)) {\n          length = nativeMax(group.length, length);\n          return true;\n        }\n      });\n      var result = Array(length);\n      while (++index < length) {\n        result[index] = arrayMap(array, baseProperty(index));\n      }\n      return result;\n    }\n\n    /**\n     * This method is like `_.unzip` except that it accepts an iteratee to specify\n     * how regrouped values should be combined. The `iteratee` is bound to `thisArg`\n     * and invoked with four arguments: (accumulator, value, index, group).\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @param {Function} [iteratee] The function to combine regrouped values.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n     * // => [[1, 10, 100], [2, 20, 200]]\n     *\n     * _.unzipWith(zipped, _.add);\n     * // => [3, 30, 300]\n     */\n    function unzipWith(array, iteratee, thisArg) {\n      var length = array ? array.length : 0;\n      if (!length) {\n        return [];\n      }\n      var result = unzip(array);\n      if (iteratee == null) {\n        return result;\n      }\n      iteratee = bindCallback(iteratee, thisArg, 4);\n      return arrayMap(result, function(group) {\n        return arrayReduce(group, iteratee, undefined, true);\n      });\n    }\n\n    /**\n     * Creates an array excluding all provided values using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {Array} array The array to filter.\n     * @param {...*} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.without([1, 2, 1, 3], 1, 2);\n     * // => [3]\n     */\n    var without = restParam(function(array, values) {\n      return isArrayLike(array)\n        ? baseDifference(array, values)\n        : [];\n    });\n\n    /**\n     * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n     * of the provided arrays.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of values.\n     * @example\n     *\n     * _.xor([1, 2], [4, 2]);\n     * // => [1, 4]\n     */\n    function xor() {\n      var index = -1,\n          length = arguments.length;\n\n      while (++index < length) {\n        var array = arguments[index];\n        if (isArrayLike(array)) {\n          var result = result\n            ? arrayPush(baseDifference(result, array), baseDifference(array, result))\n            : array;\n        }\n      }\n      return result ? baseUniq(result) : [];\n    }\n\n    /**\n     * Creates an array of grouped elements, the first of which contains the first\n     * elements of the given arrays, the second of which contains the second elements\n     * of the given arrays, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zip(['fred', 'barney'], [30, 40], [true, false]);\n     * // => [['fred', 30, true], ['barney', 40, false]]\n     */\n    var zip = restParam(unzip);\n\n    /**\n     * The inverse of `_.pairs`; this method returns an object composed from arrays\n     * of property names and values. Provide either a single two dimensional array,\n     * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names\n     * and one of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @alias object\n     * @category Array\n     * @param {Array} props The property names.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObject([['fred', 30], ['barney', 40]]);\n     * // => { 'fred': 30, 'barney': 40 }\n     *\n     * _.zipObject(['fred', 'barney'], [30, 40]);\n     * // => { 'fred': 30, 'barney': 40 }\n     */\n    function zipObject(props, values) {\n      var index = -1,\n          length = props ? props.length : 0,\n          result = {};\n\n      if (length && !values && !isArray(props[0])) {\n        values = [];\n      }\n      while (++index < length) {\n        var key = props[index];\n        if (values) {\n          result[key] = values[index];\n        } else if (key) {\n          result[key[0]] = key[1];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts an iteratee to specify\n     * how grouped values should be combined. The `iteratee` is bound to `thisArg`\n     * and invoked with four arguments: (accumulator, value, index, group).\n     *\n     * @static\n     * @memberOf _\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @param {Function} [iteratee] The function to combine grouped values.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zipWith([1, 2], [10, 20], [100, 200], _.add);\n     * // => [111, 222]\n     */\n    var zipWith = restParam(function(arrays) {\n      var length = arrays.length,\n          iteratee = length > 2 ? arrays[length - 2] : undefined,\n          thisArg = length > 1 ? arrays[length - 1] : undefined;\n\n      if (length > 2 && typeof iteratee == 'function') {\n        length -= 2;\n      } else {\n        iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;\n        thisArg = undefined;\n      }\n      arrays.length = length;\n      return unzipWith(arrays, iteratee, thisArg);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` object that wraps `value` with explicit method\n     * chaining enabled.\n     *\n     * @static\n     * @memberOf _\n     * @category Chain\n     * @param {*} value The value to wrap.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36 },\n     *   { 'user': 'fred',    'age': 40 },\n     *   { 'user': 'pebbles', 'age': 1 }\n     * ];\n     *\n     * var youngest = _.chain(users)\n     *   .sortBy('age')\n     *   .map(function(chr) {\n     *     return chr.user + ' is ' + chr.age;\n     *   })\n     *   .first()\n     *   .value();\n     * // => 'pebbles is 1'\n     */\n    function chain(value) {\n      var result = lodash(value);\n      result.__chain__ = true;\n      return result;\n    }\n\n    /**\n     * This method invokes `interceptor` and returns `value`. The interceptor is\n     * bound to `thisArg` and invoked with one argument; (value). The purpose of\n     * this method is to \"tap into\" a method chain in order to perform operations\n     * on intermediate results within the chain.\n     *\n     * @static\n     * @memberOf _\n     * @category Chain\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @param {*} [thisArg] The `this` binding of `interceptor`.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * _([1, 2, 3])\n     *  .tap(function(array) {\n     *    array.pop();\n     *  })\n     *  .reverse()\n     *  .value();\n     * // => [2, 1]\n     */\n    function tap(value, interceptor, thisArg) {\n      interceptor.call(thisArg, value);\n      return value;\n    }\n\n    /**\n     * This method is like `_.tap` except that it returns the result of `interceptor`.\n     *\n     * @static\n     * @memberOf _\n     * @category Chain\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @param {*} [thisArg] The `this` binding of `interceptor`.\n     * @returns {*} Returns the result of `interceptor`.\n     * @example\n     *\n     * _('  abc  ')\n     *  .chain()\n     *  .trim()\n     *  .thru(function(value) {\n     *    return [value];\n     *  })\n     *  .value();\n     * // => ['abc']\n     */\n    function thru(value, interceptor, thisArg) {\n      return interceptor.call(thisArg, value);\n    }\n\n    /**\n     * Enables explicit method chaining on the wrapper object.\n     *\n     * @name chain\n     * @memberOf _\n     * @category Chain\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * // without explicit chaining\n     * _(users).first();\n     * // => { 'user': 'barney', 'age': 36 }\n     *\n     * // with explicit chaining\n     * _(users).chain()\n     *   .first()\n     *   .pick('user')\n     *   .value();\n     * // => { 'user': 'barney' }\n     */\n    function wrapperChain() {\n      return chain(this);\n    }\n\n    /**\n     * Executes the chained sequence and returns the wrapped result.\n     *\n     * @name commit\n     * @memberOf _\n     * @category Chain\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2];\n     * var wrapped = _(array).push(3);\n     *\n     * console.log(array);\n     * // => [1, 2]\n     *\n     * wrapped = wrapped.commit();\n     * console.log(array);\n     * // => [1, 2, 3]\n     *\n     * wrapped.last();\n     * // => 3\n     *\n     * console.log(array);\n     * // => [1, 2, 3]\n     */\n    function wrapperCommit() {\n      return new LodashWrapper(this.value(), this.__chain__);\n    }\n\n    /**\n     * Creates a new array joining a wrapped array with any additional arrays\n     * and/or values.\n     *\n     * @name concat\n     * @memberOf _\n     * @category Chain\n     * @param {...*} [values] The values to concatenate.\n     * @returns {Array} Returns the new concatenated array.\n     * @example\n     *\n     * var array = [1];\n     * var wrapped = _(array).concat(2, [3], [[4]]);\n     *\n     * console.log(wrapped.value());\n     * // => [1, 2, 3, [4]]\n     *\n     * console.log(array);\n     * // => [1]\n     */\n    var wrapperConcat = restParam(function(values) {\n      values = baseFlatten(values);\n      return this.thru(function(array) {\n        return arrayConcat(isArray(array) ? array : [toObject(array)], values);\n      });\n    });\n\n    /**\n     * Creates a clone of the chained sequence planting `value` as the wrapped value.\n     *\n     * @name plant\n     * @memberOf _\n     * @category Chain\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2];\n     * var wrapped = _(array).map(function(value) {\n     *   return Math.pow(value, 2);\n     * });\n     *\n     * var other = [3, 4];\n     * var otherWrapped = wrapped.plant(other);\n     *\n     * otherWrapped.value();\n     * // => [9, 16]\n     *\n     * wrapped.value();\n     * // => [1, 4]\n     */\n    function wrapperPlant(value) {\n      var result,\n          parent = this;\n\n      while (parent instanceof baseLodash) {\n        var clone = wrapperClone(parent);\n        if (result) {\n          previous.__wrapped__ = clone;\n        } else {\n          result = clone;\n        }\n        var previous = clone;\n        parent = parent.__wrapped__;\n      }\n      previous.__wrapped__ = value;\n      return result;\n    }\n\n    /**\n     * Reverses the wrapped array so the first element becomes the last, the\n     * second element becomes the second to last, and so on.\n     *\n     * **Note:** This method mutates the wrapped array.\n     *\n     * @name reverse\n     * @memberOf _\n     * @category Chain\n     * @returns {Object} Returns the new reversed `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _(array).reverse().value()\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function wrapperReverse() {\n      var value = this.__wrapped__;\n\n      var interceptor = function(value) {\n        return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse();\n      };\n      if (value instanceof LazyWrapper) {\n        var wrapped = value;\n        if (this.__actions__.length) {\n          wrapped = new LazyWrapper(this);\n        }\n        wrapped = wrapped.reverse();\n        wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });\n        return new LodashWrapper(wrapped, this.__chain__);\n      }\n      return this.thru(interceptor);\n    }\n\n    /**\n     * Produces the result of coercing the unwrapped value to a string.\n     *\n     * @name toString\n     * @memberOf _\n     * @category Chain\n     * @returns {string} Returns the coerced string value.\n     * @example\n     *\n     * _([1, 2, 3]).toString();\n     * // => '1,2,3'\n     */\n    function wrapperToString() {\n      return (this.value() + '');\n    }\n\n    /**\n     * Executes the chained sequence to extract the unwrapped value.\n     *\n     * @name value\n     * @memberOf _\n     * @alias run, toJSON, valueOf\n     * @category Chain\n     * @returns {*} Returns the resolved unwrapped value.\n     * @example\n     *\n     * _([1, 2, 3]).value();\n     * // => [1, 2, 3]\n     */\n    function wrapperValue() {\n      return baseWrapperValue(this.__wrapped__, this.__actions__);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of elements corresponding to the given keys, or indexes,\n     * of `collection`. Keys may be specified as individual arguments or as arrays\n     * of keys.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {...(number|number[]|string|string[])} [props] The property names\n     *  or indexes of elements to pick, specified individually or in arrays.\n     * @returns {Array} Returns the new array of picked elements.\n     * @example\n     *\n     * _.at(['a', 'b', 'c'], [0, 2]);\n     * // => ['a', 'c']\n     *\n     * _.at(['barney', 'fred', 'pebbles'], 0, 2);\n     * // => ['barney', 'pebbles']\n     */\n    var at = restParam(function(collection, props) {\n      return baseAt(collection, baseFlatten(props));\n    });\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` through `iteratee`. The corresponding value\n     * of each key is the number of times the key was returned by `iteratee`.\n     * The `iteratee` is bound to `thisArg` and invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.countBy([4.3, 6.1, 6.4], function(n) {\n     *   return Math.floor(n);\n     * });\n     * // => { '4': 1, '6': 2 }\n     *\n     * _.countBy([4.3, 6.1, 6.4], function(n) {\n     *   return this.floor(n);\n     * }, Math);\n     * // => { '4': 1, '6': 2 }\n     *\n     * _.countBy(['one', 'two', 'three'], 'length');\n     * // => { '3': 2, '5': 1 }\n     */\n    var countBy = createAggregator(function(result, value, key) {\n      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);\n    });\n\n    /**\n     * Checks if `predicate` returns truthy for **all** elements of `collection`.\n     * The predicate is bound to `thisArg` and invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @alias all\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.every([true, 1, null, 'yes'], Boolean);\n     * // => false\n     *\n     * var users = [\n     *   { 'user': 'barney', 'active': false },\n     *   { 'user': 'fred',   'active': false }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.every(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.every(users, 'active', false);\n     * // => true\n     *\n     * // using the `_.property` callback shorthand\n     * _.every(users, 'active');\n     * // => false\n     */\n    function every(collection, predicate, thisArg) {\n      var func = isArray(collection) ? arrayEvery : baseEvery;\n      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {\n        predicate = undefined;\n      }\n      if (typeof predicate != 'function' || thisArg !== undefined) {\n        predicate = getCallback(predicate, thisArg, 3);\n      }\n      return func(collection, predicate);\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning an array of all elements\n     * `predicate` returns truthy for. The predicate is bound to `thisArg` and\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @alias select\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the new filtered array.\n     * @example\n     *\n     * _.filter([4, 5, 6], function(n) {\n     *   return n % 2 == 0;\n     * });\n     * // => [4, 6]\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');\n     * // => ['barney']\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.pluck(_.filter(users, 'active', false), 'user');\n     * // => ['fred']\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.filter(users, 'active'), 'user');\n     * // => ['barney']\n     */\n    function filter(collection, predicate, thisArg) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      predicate = getCallback(predicate, thisArg, 3);\n      return func(collection, predicate);\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning the first element\n     * `predicate` returns truthy for. The predicate is bound to `thisArg` and\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @alias detect\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to search.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': true },\n     *   { 'user': 'fred',    'age': 40, 'active': false },\n     *   { 'user': 'pebbles', 'age': 1,  'active': true }\n     * ];\n     *\n     * _.result(_.find(users, function(chr) {\n     *   return chr.age < 40;\n     * }), 'user');\n     * // => 'barney'\n     *\n     * // using the `_.matches` callback shorthand\n     * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');\n     * // => 'pebbles'\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.result(_.find(users, 'active', false), 'user');\n     * // => 'fred'\n     *\n     * // using the `_.property` callback shorthand\n     * _.result(_.find(users, 'active'), 'user');\n     * // => 'barney'\n     */\n    var find = createFind(baseEach);\n\n    /**\n     * This method is like `_.find` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to search.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * _.findLast([1, 2, 3, 4], function(n) {\n     *   return n % 2 == 1;\n     * });\n     * // => 3\n     */\n    var findLast = createFind(baseEachRight, true);\n\n    /**\n     * Performs a deep comparison between each element in `collection` and the\n     * source object, returning the first element that has equivalent property\n     * values.\n     *\n     * **Note:** This method supports comparing arrays, booleans, `Date` objects,\n     * numbers, `Object` objects, regexes, and strings. Objects are compared by\n     * their own, not inherited, enumerable properties. For comparing a single\n     * own or inherited property value see `_.matchesProperty`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to search.\n     * @param {Object} source The object of property values to match.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user');\n     * // => 'barney'\n     *\n     * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user');\n     * // => 'fred'\n     */\n    function findWhere(collection, source) {\n      return find(collection, baseMatches(source));\n    }\n\n    /**\n     * Iterates over elements of `collection` invoking `iteratee` for each element.\n     * The `iteratee` is bound to `thisArg` and invoked with three arguments:\n     * (value, index|key, collection). Iteratee functions may exit iteration early\n     * by explicitly returning `false`.\n     *\n     * **Note:** As with other \"Collections\" methods, objects with a \"length\" property\n     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`\n     * may be used for object iteration.\n     *\n     * @static\n     * @memberOf _\n     * @alias each\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array|Object|string} Returns `collection`.\n     * @example\n     *\n     * _([1, 2]).forEach(function(n) {\n     *   console.log(n);\n     * }).value();\n     * // => logs each value from left to right and returns the array\n     *\n     * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {\n     *   console.log(n, key);\n     * });\n     * // => logs each value-key pair and returns the object (iteration order is not guaranteed)\n     */\n    var forEach = createForEach(arrayEach, baseEach);\n\n    /**\n     * This method is like `_.forEach` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @alias eachRight\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array|Object|string} Returns `collection`.\n     * @example\n     *\n     * _([1, 2]).forEachRight(function(n) {\n     *   console.log(n);\n     * }).value();\n     * // => logs each value from right to left and returns the array\n     */\n    var forEachRight = createForEach(arrayEachRight, baseEachRight);\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` through `iteratee`. The corresponding value\n     * of each key is an array of the elements responsible for generating the key.\n     * The `iteratee` is bound to `thisArg` and invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.groupBy([4.2, 6.1, 6.4], function(n) {\n     *   return Math.floor(n);\n     * });\n     * // => { '4': [4.2], '6': [6.1, 6.4] }\n     *\n     * _.groupBy([4.2, 6.1, 6.4], function(n) {\n     *   return this.floor(n);\n     * }, Math);\n     * // => { '4': [4.2], '6': [6.1, 6.4] }\n     *\n     * // using the `_.property` callback shorthand\n     * _.groupBy(['one', 'two', 'three'], 'length');\n     * // => { '3': ['one', 'two'], '5': ['three'] }\n     */\n    var groupBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        result[key].push(value);\n      } else {\n        result[key] = [value];\n      }\n    });\n\n    /**\n     * Checks if `value` is in `collection` using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n     * for equality comparisons. If `fromIndex` is negative, it is used as the offset\n     * from the end of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @alias contains, include\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to search.\n     * @param {*} target The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.\n     * @returns {boolean} Returns `true` if a matching element is found, else `false`.\n     * @example\n     *\n     * _.includes([1, 2, 3], 1);\n     * // => true\n     *\n     * _.includes([1, 2, 3], 1, 2);\n     * // => false\n     *\n     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');\n     * // => true\n     *\n     * _.includes('pebbles', 'eb');\n     * // => true\n     */\n    function includes(collection, target, fromIndex, guard) {\n      var length = collection ? getLength(collection) : 0;\n      if (!isLength(length)) {\n        collection = values(collection);\n        length = collection.length;\n      }\n      if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {\n        fromIndex = 0;\n      } else {\n        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);\n      }\n      return (typeof collection == 'string' || !isArray(collection) && isString(collection))\n        ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)\n        : (!!length && getIndexOf(collection, target, fromIndex) > -1);\n    }\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` through `iteratee`. The corresponding value\n     * of each key is the last element responsible for generating the key. The\n     * iteratee function is bound to `thisArg` and invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * var keyData = [\n     *   { 'dir': 'left', 'code': 97 },\n     *   { 'dir': 'right', 'code': 100 }\n     * ];\n     *\n     * _.indexBy(keyData, 'dir');\n     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n     *\n     * _.indexBy(keyData, function(object) {\n     *   return String.fromCharCode(object.code);\n     * });\n     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n     *\n     * _.indexBy(keyData, function(object) {\n     *   return this.fromCharCode(object.code);\n     * }, String);\n     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n     */\n    var indexBy = createAggregator(function(result, value, key) {\n      result[key] = value;\n    });\n\n    /**\n     * Invokes the method at `path` of each element in `collection`, returning\n     * an array of the results of each invoked method. Any additional arguments\n     * are provided to each invoked method. If `methodName` is a function it is\n     * invoked for, and `this` bound to, each element in `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Array|Function|string} path The path of the method to invoke or\n     *  the function invoked per iteration.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');\n     * // => [[1, 5, 7], [1, 2, 3]]\n     *\n     * _.invoke([123, 456], String.prototype.split, '');\n     * // => [['1', '2', '3'], ['4', '5', '6']]\n     */\n    var invoke = restParam(function(collection, path, args) {\n      var index = -1,\n          isFunc = typeof path == 'function',\n          isProp = isKey(path),\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value) {\n        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);\n        result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);\n      });\n      return result;\n    });\n\n    /**\n     * Creates an array of values by running each element in `collection` through\n     * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n     *\n     * The guarded methods are:\n     * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,\n     * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,\n     * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,\n     * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,\n     * `sum`, `uniq`, and `words`\n     *\n     * @static\n     * @memberOf _\n     * @alias collect\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array} Returns the new mapped array.\n     * @example\n     *\n     * function timesThree(n) {\n     *   return n * 3;\n     * }\n     *\n     * _.map([1, 2], timesThree);\n     * // => [3, 6]\n     *\n     * _.map({ 'a': 1, 'b': 2 }, timesThree);\n     * // => [3, 6] (iteration order is not guaranteed)\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * // using the `_.property` callback shorthand\n     * _.map(users, 'user');\n     * // => ['barney', 'fred']\n     */\n    function map(collection, iteratee, thisArg) {\n      var func = isArray(collection) ? arrayMap : baseMap;\n      iteratee = getCallback(iteratee, thisArg, 3);\n      return func(collection, iteratee);\n    }\n\n    /**\n     * Creates an array of elements split into two groups, the first of which\n     * contains elements `predicate` returns truthy for, while the second of which\n     * contains elements `predicate` returns falsey for. The predicate is bound\n     * to `thisArg` and invoked with three arguments: (value, index|key, collection).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the array of grouped elements.\n     * @example\n     *\n     * _.partition([1, 2, 3], function(n) {\n     *   return n % 2;\n     * });\n     * // => [[1, 3], [2]]\n     *\n     * _.partition([1.2, 2.3, 3.4], function(n) {\n     *   return this.floor(n) % 2;\n     * }, Math);\n     * // => [[1.2, 3.4], [2.3]]\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': false },\n     *   { 'user': 'fred',    'age': 40, 'active': true },\n     *   { 'user': 'pebbles', 'age': 1,  'active': false }\n     * ];\n     *\n     * var mapper = function(array) {\n     *   return _.pluck(array, 'user');\n     * };\n     *\n     * // using the `_.matches` callback shorthand\n     * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper);\n     * // => [['pebbles'], ['barney', 'fred']]\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.map(_.partition(users, 'active', false), mapper);\n     * // => [['barney', 'pebbles'], ['fred']]\n     *\n     * // using the `_.property` callback shorthand\n     * _.map(_.partition(users, 'active'), mapper);\n     * // => [['fred'], ['barney', 'pebbles']]\n     */\n    var partition = createAggregator(function(result, value, key) {\n      result[key ? 0 : 1].push(value);\n    }, function() { return [[], []]; });\n\n    /**\n     * Gets the property value of `path` from all elements in `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Array|string} path The path of the property to pluck.\n     * @returns {Array} Returns the property values.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * _.pluck(users, 'user');\n     * // => ['barney', 'fred']\n     *\n     * var userIndex = _.indexBy(users, 'user');\n     * _.pluck(userIndex, 'age');\n     * // => [36, 40] (iteration order is not guaranteed)\n     */\n    function pluck(collection, path) {\n      return map(collection, property(path));\n    }\n\n    /**\n     * Reduces `collection` to a value which is the accumulated result of running\n     * each element in `collection` through `iteratee`, where each successive\n     * invocation is supplied the return value of the previous. If `accumulator`\n     * is not provided the first element of `collection` is used as the initial\n     * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:\n     * (accumulator, value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.reduce`, `_.reduceRight`, and `_.transform`.\n     *\n     * The guarded methods are:\n     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,\n     * and `sortByOrder`\n     *\n     * @static\n     * @memberOf _\n     * @alias foldl, inject\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {*} Returns the accumulated value.\n     * @example\n     *\n     * _.reduce([1, 2], function(total, n) {\n     *   return total + n;\n     * });\n     * // => 3\n     *\n     * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {\n     *   result[key] = n * 3;\n     *   return result;\n     * }, {});\n     * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)\n     */\n    var reduce = createReduce(arrayReduce, baseEach);\n\n    /**\n     * This method is like `_.reduce` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @alias foldr\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {*} Returns the accumulated value.\n     * @example\n     *\n     * var array = [[0, 1], [2, 3], [4, 5]];\n     *\n     * _.reduceRight(array, function(flattened, other) {\n     *   return flattened.concat(other);\n     * }, []);\n     * // => [4, 5, 2, 3, 0, 1]\n     */\n    var reduceRight = createReduce(arrayReduceRight, baseEachRight);\n\n    /**\n     * The opposite of `_.filter`; this method returns the elements of `collection`\n     * that `predicate` does **not** return truthy for.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Array} Returns the new filtered array.\n     * @example\n     *\n     * _.reject([1, 2, 3, 4], function(n) {\n     *   return n % 2 == 0;\n     * });\n     * // => [1, 3]\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': true }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user');\n     * // => ['barney']\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.pluck(_.reject(users, 'active', false), 'user');\n     * // => ['fred']\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.reject(users, 'active'), 'user');\n     * // => ['barney']\n     */\n    function reject(collection, predicate, thisArg) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      predicate = getCallback(predicate, thisArg, 3);\n      return func(collection, function(value, index, collection) {\n        return !predicate(value, index, collection);\n      });\n    }\n\n    /**\n     * Gets a random element or `n` random elements from a collection.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to sample.\n     * @param {number} [n] The number of elements to sample.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {*} Returns the random sample(s).\n     * @example\n     *\n     * _.sample([1, 2, 3, 4]);\n     * // => 2\n     *\n     * _.sample([1, 2, 3, 4], 2);\n     * // => [3, 1]\n     */\n    function sample(collection, n, guard) {\n      if (guard ? isIterateeCall(collection, n, guard) : n == null) {\n        collection = toIterable(collection);\n        var length = collection.length;\n        return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;\n      }\n      var index = -1,\n          result = toArray(collection),\n          length = result.length,\n          lastIndex = length - 1;\n\n      n = nativeMin(n < 0 ? 0 : (+n || 0), length);\n      while (++index < n) {\n        var rand = baseRandom(index, lastIndex),\n            value = result[rand];\n\n        result[rand] = result[index];\n        result[index] = value;\n      }\n      result.length = n;\n      return result;\n    }\n\n    /**\n     * Creates an array of shuffled values, using a version of the\n     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     * @example\n     *\n     * _.shuffle([1, 2, 3, 4]);\n     * // => [4, 1, 3, 2]\n     */\n    function shuffle(collection) {\n      return sample(collection, POSITIVE_INFINITY);\n    }\n\n    /**\n     * Gets the size of `collection` by returning its length for array-like\n     * values or the number of own enumerable properties for objects.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @returns {number} Returns the size of `collection`.\n     * @example\n     *\n     * _.size([1, 2, 3]);\n     * // => 3\n     *\n     * _.size({ 'a': 1, 'b': 2 });\n     * // => 2\n     *\n     * _.size('pebbles');\n     * // => 7\n     */\n    function size(collection) {\n      var length = collection ? getLength(collection) : 0;\n      return isLength(length) ? length : keys(collection).length;\n    }\n\n    /**\n     * Checks if `predicate` returns truthy for **any** element of `collection`.\n     * The function returns as soon as it finds a passing value and does not iterate\n     * over the entire collection. The predicate is bound to `thisArg` and invoked\n     * with three arguments: (value, index|key, collection).\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @alias any\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.some([null, 0, 'yes', false], Boolean);\n     * // => true\n     *\n     * var users = [\n     *   { 'user': 'barney', 'active': true },\n     *   { 'user': 'fred',   'active': false }\n     * ];\n     *\n     * // using the `_.matches` callback shorthand\n     * _.some(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.some(users, 'active', false);\n     * // => true\n     *\n     * // using the `_.property` callback shorthand\n     * _.some(users, 'active');\n     * // => true\n     */\n    function some(collection, predicate, thisArg) {\n      var func = isArray(collection) ? arraySome : baseSome;\n      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {\n        predicate = undefined;\n      }\n      if (typeof predicate != 'function' || thisArg !== undefined) {\n        predicate = getCallback(predicate, thisArg, 3);\n      }\n      return func(collection, predicate);\n    }\n\n    /**\n     * Creates an array of elements, sorted in ascending order by the results of\n     * running each element in a collection through `iteratee`. This method performs\n     * a stable sort, that is, it preserves the original sort order of equal elements.\n     * The `iteratee` is bound to `thisArg` and invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * _.sortBy([1, 2, 3], function(n) {\n     *   return Math.sin(n);\n     * });\n     * // => [3, 1, 2]\n     *\n     * _.sortBy([1, 2, 3], function(n) {\n     *   return this.sin(n);\n     * }, Math);\n     * // => [3, 1, 2]\n     *\n     * var users = [\n     *   { 'user': 'fred' },\n     *   { 'user': 'pebbles' },\n     *   { 'user': 'barney' }\n     * ];\n     *\n     * // using the `_.property` callback shorthand\n     * _.pluck(_.sortBy(users, 'user'), 'user');\n     * // => ['barney', 'fred', 'pebbles']\n     */\n    function sortBy(collection, iteratee, thisArg) {\n      if (collection == null) {\n        return [];\n      }\n      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {\n        iteratee = undefined;\n      }\n      var index = -1;\n      iteratee = getCallback(iteratee, thisArg, 3);\n\n      var result = baseMap(collection, function(value, key, collection) {\n        return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value };\n      });\n      return baseSortBy(result, compareAscending);\n    }\n\n    /**\n     * This method is like `_.sortBy` except that it can sort by multiple iteratees\n     * or property names.\n     *\n     * If a property name is provided for an iteratee the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If an object is provided for an iteratee the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees\n     *  The iteratees to sort by, specified as individual values or arrays of values.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 42 },\n     *   { 'user': 'barney', 'age': 34 }\n     * ];\n     *\n     * _.map(_.sortByAll(users, ['user', 'age']), _.values);\n     * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]\n     *\n     * _.map(_.sortByAll(users, 'user', function(chr) {\n     *   return Math.floor(chr.age / 10);\n     * }), _.values);\n     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]\n     */\n    var sortByAll = restParam(function(collection, iteratees) {\n      if (collection == null) {\n        return [];\n      }\n      var guard = iteratees[2];\n      if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {\n        iteratees.length = 1;\n      }\n      return baseSortByOrder(collection, baseFlatten(iteratees), []);\n    });\n\n    /**\n     * This method is like `_.sortByAll` except that it allows specifying the\n     * sort orders of the iteratees to sort by. If `orders` is unspecified, all\n     * values are sorted in ascending order. Otherwise, a value is sorted in\n     * ascending order if its corresponding order is \"asc\", and descending if \"desc\".\n     *\n     * If a property name is provided for an iteratee the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If an object is provided for an iteratee the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n     * @param {boolean[]} [orders] The sort orders of `iteratees`.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 34 },\n     *   { 'user': 'fred',   'age': 42 },\n     *   { 'user': 'barney', 'age': 36 }\n     * ];\n     *\n     * // sort by `user` in ascending order and by `age` in descending order\n     * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);\n     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]\n     */\n    function sortByOrder(collection, iteratees, orders, guard) {\n      if (collection == null) {\n        return [];\n      }\n      if (guard && isIterateeCall(iteratees, orders, guard)) {\n        orders = undefined;\n      }\n      if (!isArray(iteratees)) {\n        iteratees = iteratees == null ? [] : [iteratees];\n      }\n      if (!isArray(orders)) {\n        orders = orders == null ? [] : [orders];\n      }\n      return baseSortByOrder(collection, iteratees, orders);\n    }\n\n    /**\n     * Performs a deep comparison between each element in `collection` and the\n     * source object, returning an array of all elements that have equivalent\n     * property values.\n     *\n     * **Note:** This method supports comparing arrays, booleans, `Date` objects,\n     * numbers, `Object` objects, regexes, and strings. Objects are compared by\n     * their own, not inherited, enumerable properties. For comparing a single\n     * own or inherited property value see `_.matchesProperty`.\n     *\n     * @static\n     * @memberOf _\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to search.\n     * @param {Object} source The object of property values to match.\n     * @returns {Array} Returns the new filtered array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] },\n     *   { 'user': 'fred',   'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] }\n     * ];\n     *\n     * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user');\n     * // => ['barney']\n     *\n     * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user');\n     * // => ['fred']\n     */\n    function where(collection, source) {\n      return filter(collection, baseMatches(source));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Gets the number of milliseconds that have elapsed since the Unix epoch\n     * (1 January 1970 00:00:00 UTC).\n     *\n     * @static\n     * @memberOf _\n     * @category Date\n     * @example\n     *\n     * _.defer(function(stamp) {\n     *   console.log(_.now() - stamp);\n     * }, _.now());\n     * // => logs the number of milliseconds it took for the deferred function to be invoked\n     */\n    var now = nativeNow || function() {\n      return new Date().getTime();\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The opposite of `_.before`; this method creates a function that invokes\n     * `func` once it is called `n` or more times.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {number} n The number of calls before `func` is invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var saves = ['profile', 'settings'];\n     *\n     * var done = _.after(saves.length, function() {\n     *   console.log('done saving!');\n     * });\n     *\n     * _.forEach(saves, function(type) {\n     *   asyncSave({ 'type': type, 'complete': done });\n     * });\n     * // => logs 'done saving!' after the two async saves have completed\n     */\n    function after(n, func) {\n      if (typeof func != 'function') {\n        if (typeof n == 'function') {\n          var temp = n;\n          n = func;\n          func = temp;\n        } else {\n          throw new TypeError(FUNC_ERROR_TEXT);\n        }\n      }\n      n = nativeIsFinite(n = +n) ? n : 0;\n      return function() {\n        if (--n < 1) {\n          return func.apply(this, arguments);\n        }\n      };\n    }\n\n    /**\n     * Creates a function that accepts up to `n` arguments ignoring any\n     * additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @param {number} [n=func.length] The arity cap.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n     * // => [6, 8, 10]\n     */\n    function ary(func, n, guard) {\n      if (guard && isIterateeCall(func, n, guard)) {\n        n = undefined;\n      }\n      n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);\n      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);\n    }\n\n    /**\n     * Creates a function that invokes `func`, with the `this` binding and arguments\n     * of the created function, while it is called less than `n` times. Subsequent\n     * calls to the created function return the result of the last `func` invocation.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {number} n The number of calls at which `func` is no longer invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * jQuery('#add').on('click', _.before(5, addContactToList));\n     * // => allows adding up to 4 contacts to the list\n     */\n    function before(n, func) {\n      var result;\n      if (typeof func != 'function') {\n        if (typeof n == 'function') {\n          var temp = n;\n          n = func;\n          func = temp;\n        } else {\n          throw new TypeError(FUNC_ERROR_TEXT);\n        }\n      }\n      return function() {\n        if (--n > 0) {\n          result = func.apply(this, arguments);\n        }\n        if (n <= 1) {\n          func = undefined;\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of `thisArg`\n     * and prepends any additional `_.bind` arguments to those provided to the\n     * bound function.\n     *\n     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** Unlike native `Function#bind` this method does not set the \"length\"\n     * property of bound functions.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to bind.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * var greet = function(greeting, punctuation) {\n     *   return greeting + ' ' + this.user + punctuation;\n     * };\n     *\n     * var object = { 'user': 'fred' };\n     *\n     * var bound = _.bind(greet, object, 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * // using placeholders\n     * var bound = _.bind(greet, object, _, '!');\n     * bound('hi');\n     * // => 'hi fred!'\n     */\n    var bind = restParam(function(func, thisArg, partials) {\n      var bitmask = BIND_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, bind.placeholder);\n        bitmask |= PARTIAL_FLAG;\n      }\n      return createWrapper(func, bitmask, thisArg, partials, holders);\n    });\n\n    /**\n     * Binds methods of an object to the object itself, overwriting the existing\n     * method. Method names may be specified as individual arguments or as arrays\n     * of method names. If no method names are provided all enumerable function\n     * properties, own and inherited, of `object` are bound.\n     *\n     * **Note:** This method does not set the \"length\" property of bound functions.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Object} object The object to bind and assign the bound methods to.\n     * @param {...(string|string[])} [methodNames] The object method names to bind,\n     *  specified as individual method names or arrays of method names.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var view = {\n     *   'label': 'docs',\n     *   'onClick': function() {\n     *     console.log('clicked ' + this.label);\n     *   }\n     * };\n     *\n     * _.bindAll(view);\n     * jQuery('#docs').on('click', view.onClick);\n     * // => logs 'clicked docs' when the element is clicked\n     */\n    var bindAll = restParam(function(object, methodNames) {\n      methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);\n\n      var index = -1,\n          length = methodNames.length;\n\n      while (++index < length) {\n        var key = methodNames[index];\n        object[key] = createWrapper(object[key], BIND_FLAG, object);\n      }\n      return object;\n    });\n\n    /**\n     * Creates a function that invokes the method at `object[key]` and prepends\n     * any additional `_.bindKey` arguments to those provided to the bound function.\n     *\n     * This method differs from `_.bind` by allowing bound functions to reference\n     * methods that may be redefined or don't yet exist.\n     * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n     * for more details.\n     *\n     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Object} object The object the method belongs to.\n     * @param {string} key The key of the method.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * var object = {\n     *   'user': 'fred',\n     *   'greet': function(greeting, punctuation) {\n     *     return greeting + ' ' + this.user + punctuation;\n     *   }\n     * };\n     *\n     * var bound = _.bindKey(object, 'greet', 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * object.greet = function(greeting, punctuation) {\n     *   return greeting + 'ya ' + this.user + punctuation;\n     * };\n     *\n     * bound('!');\n     * // => 'hiya fred!'\n     *\n     * // using placeholders\n     * var bound = _.bindKey(object, 'greet', _, '!');\n     * bound('hi');\n     * // => 'hiya fred!'\n     */\n    var bindKey = restParam(function(object, key, partials) {\n      var bitmask = BIND_FLAG | BIND_KEY_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, bindKey.placeholder);\n        bitmask |= PARTIAL_FLAG;\n      }\n      return createWrapper(key, bitmask, object, partials, holders);\n    });\n\n    /**\n     * Creates a function that accepts one or more arguments of `func` that when\n     * called either invokes `func` returning its result, if all `func` arguments\n     * have been provided, or returns a function that accepts one or more of the\n     * remaining `func` arguments, and so on. The arity of `func` may be specified\n     * if `func.length` is not sufficient.\n     *\n     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method does not set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curry(abc);\n     *\n     * curried(1)(2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // using placeholders\n     * curried(1)(_, 3)(2);\n     * // => [1, 2, 3]\n     */\n    var curry = createCurry(CURRY_FLAG);\n\n    /**\n     * This method is like `_.curry` except that arguments are applied to `func`\n     * in the manner of `_.partialRight` instead of `_.partial`.\n     *\n     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method does not set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curryRight(abc);\n     *\n     * curried(3)(2)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(2, 3)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // using placeholders\n     * curried(3)(1, _)(2);\n     * // => [1, 2, 3]\n     */\n    var curryRight = createCurry(CURRY_RIGHT_FLAG);\n\n    /**\n     * Creates a debounced function that delays invoking `func` until after `wait`\n     * milliseconds have elapsed since the last time the debounced function was\n     * invoked. The debounced function comes with a `cancel` method to cancel\n     * delayed invocations. Provide an options object to indicate that `func`\n     * should be invoked on the leading and/or trailing edge of the `wait` timeout.\n     * Subsequent calls to the debounced function return the result of the last\n     * `func` invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n     * on the trailing edge of the timeout only if the the debounced function is\n     * invoked more than once during the `wait` timeout.\n     *\n     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)\n     * for details over the differences between `_.debounce` and `_.throttle`.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to debounce.\n     * @param {number} [wait=0] The number of milliseconds to delay.\n     * @param {Object} [options] The options object.\n     * @param {boolean} [options.leading=false] Specify invoking on the leading\n     *  edge of the timeout.\n     * @param {number} [options.maxWait] The maximum time `func` is allowed to be\n     *  delayed before it is invoked.\n     * @param {boolean} [options.trailing=true] Specify invoking on the trailing\n     *  edge of the timeout.\n     * @returns {Function} Returns the new debounced function.\n     * @example\n     *\n     * // avoid costly calculations while the window size is in flux\n     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n     *\n     * // invoke `sendMail` when the click event is fired, debouncing subsequent calls\n     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {\n     *   'leading': true,\n     *   'trailing': false\n     * }));\n     *\n     * // ensure `batchLog` is invoked once after 1 second of debounced calls\n     * var source = new EventSource('/stream');\n     * jQuery(source).on('message', _.debounce(batchLog, 250, {\n     *   'maxWait': 1000\n     * }));\n     *\n     * // cancel a debounced call\n     * var todoChanges = _.debounce(batchLog, 1000);\n     * Object.observe(models.todo, todoChanges);\n     *\n     * Object.observe(models, function(changes) {\n     *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {\n     *     todoChanges.cancel();\n     *   }\n     * }, ['delete']);\n     *\n     * // ...at some point `models.todo` is changed\n     * models.todo.completed = true;\n     *\n     * // ...before 1 second has passed `models.todo` is deleted\n     * // which cancels the debounced `todoChanges` call\n     * delete models.todo;\n     */\n    function debounce(func, wait, options) {\n      var args,\n          maxTimeoutId,\n          result,\n          stamp,\n          thisArg,\n          timeoutId,\n          trailingCall,\n          lastCalled = 0,\n          maxWait = false,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      wait = wait < 0 ? 0 : (+wait || 0);\n      if (options === true) {\n        var leading = true;\n        trailing = false;\n      } else if (isObject(options)) {\n        leading = !!options.leading;\n        maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n\n      function cancel() {\n        if (timeoutId) {\n          clearTimeout(timeoutId);\n        }\n        if (maxTimeoutId) {\n          clearTimeout(maxTimeoutId);\n        }\n        lastCalled = 0;\n        maxTimeoutId = timeoutId = trailingCall = undefined;\n      }\n\n      function complete(isCalled, id) {\n        if (id) {\n          clearTimeout(id);\n        }\n        maxTimeoutId = timeoutId = trailingCall = undefined;\n        if (isCalled) {\n          lastCalled = now();\n          result = func.apply(thisArg, args);\n          if (!timeoutId && !maxTimeoutId) {\n            args = thisArg = undefined;\n          }\n        }\n      }\n\n      function delayed() {\n        var remaining = wait - (now() - stamp);\n        if (remaining <= 0 || remaining > wait) {\n          complete(trailingCall, maxTimeoutId);\n        } else {\n          timeoutId = setTimeout(delayed, remaining);\n        }\n      }\n\n      function maxDelayed() {\n        complete(trailing, timeoutId);\n      }\n\n      function debounced() {\n        args = arguments;\n        stamp = now();\n        thisArg = this;\n        trailingCall = trailing && (timeoutId || !leading);\n\n        if (maxWait === false) {\n          var leadingCall = leading && !timeoutId;\n        } else {\n          if (!maxTimeoutId && !leading) {\n            lastCalled = stamp;\n          }\n          var remaining = maxWait - (stamp - lastCalled),\n              isCalled = remaining <= 0 || remaining > maxWait;\n\n          if (isCalled) {\n            if (maxTimeoutId) {\n              maxTimeoutId = clearTimeout(maxTimeoutId);\n            }\n            lastCalled = stamp;\n            result = func.apply(thisArg, args);\n          }\n          else if (!maxTimeoutId) {\n            maxTimeoutId = setTimeout(maxDelayed, remaining);\n          }\n        }\n        if (isCalled && timeoutId) {\n          timeoutId = clearTimeout(timeoutId);\n        }\n        else if (!timeoutId && wait !== maxWait) {\n          timeoutId = setTimeout(delayed, wait);\n        }\n        if (leadingCall) {\n          isCalled = true;\n          result = func.apply(thisArg, args);\n        }\n        if (isCalled && !timeoutId && !maxTimeoutId) {\n          args = thisArg = undefined;\n        }\n        return result;\n      }\n      debounced.cancel = cancel;\n      return debounced;\n    }\n\n    /**\n     * Defers invoking the `func` until the current call stack has cleared. Any\n     * additional arguments are provided to `func` when it is invoked.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to defer.\n     * @param {...*} [args] The arguments to invoke the function with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.defer(function(text) {\n     *   console.log(text);\n     * }, 'deferred');\n     * // logs 'deferred' after one or more milliseconds\n     */\n    var defer = restParam(function(func, args) {\n      return baseDelay(func, 1, args);\n    });\n\n    /**\n     * Invokes `func` after `wait` milliseconds. Any additional arguments are\n     * provided to `func` when it is invoked.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {...*} [args] The arguments to invoke the function with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.delay(function(text) {\n     *   console.log(text);\n     * }, 1000, 'later');\n     * // => logs 'later' after one second\n     */\n    var delay = restParam(function(func, wait, args) {\n      return baseDelay(func, wait, args);\n    });\n\n    /**\n     * Creates a function that returns the result of invoking the provided\n     * functions with the `this` binding of the created function, where each\n     * successive invocation is supplied the return value of the previous.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {...Function} [funcs] Functions to invoke.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flow(_.add, square);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flow = createFlow();\n\n    /**\n     * This method is like `_.flow` except that it creates a function that\n     * invokes the provided functions from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @alias backflow, compose\n     * @category Function\n     * @param {...Function} [funcs] Functions to invoke.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flowRight(square, _.add);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flowRight = createFlow(true);\n\n    /**\n     * Creates a function that memoizes the result of `func`. If `resolver` is\n     * provided it determines the cache key for storing the result based on the\n     * arguments provided to the memoized function. By default, the first argument\n     * provided to the memoized function is coerced to a string and used as the\n     * cache key. The `func` is invoked with the `this` binding of the memoized\n     * function.\n     *\n     * **Note:** The cache is exposed as the `cache` property on the memoized\n     * function. Its creation may be customized by replacing the `_.memoize.Cache`\n     * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)\n     * method interface of `get`, `has`, and `set`.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to have its output memoized.\n     * @param {Function} [resolver] The function to resolve the cache key.\n     * @returns {Function} Returns the new memoizing function.\n     * @example\n     *\n     * var upperCase = _.memoize(function(string) {\n     *   return string.toUpperCase();\n     * });\n     *\n     * upperCase('fred');\n     * // => 'FRED'\n     *\n     * // modifying the result cache\n     * upperCase.cache.set('fred', 'BARNEY');\n     * upperCase('fred');\n     * // => 'BARNEY'\n     *\n     * // replacing `_.memoize.Cache`\n     * var object = { 'user': 'fred' };\n     * var other = { 'user': 'barney' };\n     * var identity = _.memoize(_.identity);\n     *\n     * identity(object);\n     * // => { 'user': 'fred' }\n     * identity(other);\n     * // => { 'user': 'fred' }\n     *\n     * _.memoize.Cache = WeakMap;\n     * var identity = _.memoize(_.identity);\n     *\n     * identity(object);\n     * // => { 'user': 'fred' }\n     * identity(other);\n     * // => { 'user': 'barney' }\n     */\n    function memoize(func, resolver) {\n      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var memoized = function() {\n        var args = arguments,\n            key = resolver ? resolver.apply(this, args) : args[0],\n            cache = memoized.cache;\n\n        if (cache.has(key)) {\n          return cache.get(key);\n        }\n        var result = func.apply(this, args);\n        memoized.cache = cache.set(key, result);\n        return result;\n      };\n      memoized.cache = new memoize.Cache;\n      return memoized;\n    }\n\n    /**\n     * Creates a function that runs each argument through a corresponding\n     * transform function.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to wrap.\n     * @param {...(Function|Function[])} [transforms] The functions to transform\n     * arguments, specified as individual functions or arrays of functions.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function doubled(n) {\n     *   return n * 2;\n     * }\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var modded = _.modArgs(function(x, y) {\n     *   return [x, y];\n     * }, square, doubled);\n     *\n     * modded(1, 2);\n     * // => [1, 4]\n     *\n     * modded(5, 10);\n     * // => [25, 20]\n     */\n    var modArgs = restParam(function(func, transforms) {\n      transforms = baseFlatten(transforms);\n      if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var length = transforms.length;\n      return restParam(function(args) {\n        var index = nativeMin(args.length, length);\n        while (index--) {\n          args[index] = transforms[index](args[index]);\n        }\n        return func.apply(this, args);\n      });\n    });\n\n    /**\n     * Creates a function that negates the result of the predicate `func`. The\n     * `func` predicate is invoked with the `this` binding and arguments of the\n     * created function.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} predicate The predicate to negate.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function isEven(n) {\n     *   return n % 2 == 0;\n     * }\n     *\n     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n     * // => [1, 3, 5]\n     */\n    function negate(predicate) {\n      if (typeof predicate != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return function() {\n        return !predicate.apply(this, arguments);\n      };\n    }\n\n    /**\n     * Creates a function that is restricted to invoking `func` once. Repeat calls\n     * to the function return the value of the first call. The `func` is invoked\n     * with the `this` binding and arguments of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var initialize = _.once(createApplication);\n     * initialize();\n     * initialize();\n     * // `initialize` invokes `createApplication` once\n     */\n    function once(func) {\n      return before(2, func);\n    }\n\n    /**\n     * Creates a function that invokes `func` with `partial` arguments prepended\n     * to those provided to the new function. This method is like `_.bind` except\n     * it does **not** alter the `this` binding.\n     *\n     * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method does not set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * var greet = function(greeting, name) {\n     *   return greeting + ' ' + name;\n     * };\n     *\n     * var sayHelloTo = _.partial(greet, 'hello');\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     *\n     * // using placeholders\n     * var greetFred = _.partial(greet, _, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     */\n    var partial = createPartial(PARTIAL_FLAG);\n\n    /**\n     * This method is like `_.partial` except that partially applied arguments\n     * are appended to those provided to the new function.\n     *\n     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method does not set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * var greet = function(greeting, name) {\n     *   return greeting + ' ' + name;\n     * };\n     *\n     * var greetFred = _.partialRight(greet, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     *\n     * // using placeholders\n     * var sayHelloTo = _.partialRight(greet, 'hello', _);\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     */\n    var partialRight = createPartial(PARTIAL_RIGHT_FLAG);\n\n    /**\n     * Creates a function that invokes `func` with arguments arranged according\n     * to the specified indexes where the argument value at the first index is\n     * provided as the first argument, the argument value at the second index is\n     * provided as the second argument, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to rearrange arguments for.\n     * @param {...(number|number[])} indexes The arranged argument indexes,\n     *  specified as individual indexes or arrays of indexes.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var rearged = _.rearg(function(a, b, c) {\n     *   return [a, b, c];\n     * }, 2, 0, 1);\n     *\n     * rearged('b', 'c', 'a')\n     * // => ['a', 'b', 'c']\n     *\n     * var map = _.rearg(_.map, [1, 0]);\n     * map(function(n) {\n     *   return n * 3;\n     * }, [1, 2, 3]);\n     * // => [3, 6, 9]\n     */\n    var rearg = restParam(function(func, indexes) {\n      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));\n    });\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * created function and arguments from `start` and beyond provided as an array.\n     *\n     * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.restParam(function(what, names) {\n     *   return what + ' ' + _.initial(names).join(', ') +\n     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n     * });\n     *\n     * say('hello', 'fred', 'barney', 'pebbles');\n     * // => 'hello fred, barney, & pebbles'\n     */\n    function restParam(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);\n      return function() {\n        var args = arguments,\n            index = -1,\n            length = nativeMax(args.length - start, 0),\n            rest = Array(length);\n\n        while (++index < length) {\n          rest[index] = args[start + index];\n        }\n        switch (start) {\n          case 0: return func.call(this, rest);\n          case 1: return func.call(this, args[0], rest);\n          case 2: return func.call(this, args[0], args[1], rest);\n        }\n        var otherArgs = Array(start + 1);\n        index = -1;\n        while (++index < start) {\n          otherArgs[index] = args[index];\n        }\n        otherArgs[start] = rest;\n        return func.apply(this, otherArgs);\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the created\n     * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).\n     *\n     * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator).\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to spread arguments over.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.spread(function(who, what) {\n     *   return who + ' says ' + what;\n     * });\n     *\n     * say(['fred', 'hello']);\n     * // => 'fred says hello'\n     *\n     * // with a Promise\n     * var numbers = Promise.all([\n     *   Promise.resolve(40),\n     *   Promise.resolve(36)\n     * ]);\n     *\n     * numbers.then(_.spread(function(x, y) {\n     *   return x + y;\n     * }));\n     * // => a Promise of 76\n     */\n    function spread(func) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return function(array) {\n        return func.apply(this, array);\n      };\n    }\n\n    /**\n     * Creates a throttled function that only invokes `func` at most once per\n     * every `wait` milliseconds. The throttled function comes with a `cancel`\n     * method to cancel delayed invocations. Provide an options object to indicate\n     * that `func` should be invoked on the leading and/or trailing edge of the\n     * `wait` timeout. Subsequent calls to the throttled function return the\n     * result of the last `func` call.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n     * on the trailing edge of the timeout only if the the throttled function is\n     * invoked more than once during the `wait` timeout.\n     *\n     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)\n     * for details over the differences between `_.throttle` and `_.debounce`.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to throttle.\n     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n     * @param {Object} [options] The options object.\n     * @param {boolean} [options.leading=true] Specify invoking on the leading\n     *  edge of the timeout.\n     * @param {boolean} [options.trailing=true] Specify invoking on the trailing\n     *  edge of the timeout.\n     * @returns {Function} Returns the new throttled function.\n     * @example\n     *\n     * // avoid excessively updating the position while scrolling\n     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n     *\n     * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes\n     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {\n     *   'trailing': false\n     * }));\n     *\n     * // cancel a trailing throttled call\n     * jQuery(window).on('popstate', throttled.cancel);\n     */\n    function throttle(func, wait, options) {\n      var leading = true,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      if (options === false) {\n        leading = false;\n      } else if (isObject(options)) {\n        leading = 'leading' in options ? !!options.leading : leading;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n      return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });\n    }\n\n    /**\n     * Creates a function that provides `value` to the wrapper function as its\n     * first argument. Any additional arguments provided to the function are\n     * appended to those provided to the wrapper function. The wrapper is invoked\n     * with the `this` binding of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @category Function\n     * @param {*} value The value to wrap.\n     * @param {Function} wrapper The wrapper function.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var p = _.wrap(_.escape, function(func, text) {\n     *   return '<p>' + func(text) + '</p>';\n     * });\n     *\n     * p('fred, barney, & pebbles');\n     * // => '<p>fred, barney, &amp; pebbles</p>'\n     */\n    function wrap(value, wrapper) {\n      wrapper = wrapper == null ? identity : wrapper;\n      return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,\n     * otherwise they are assigned by reference. If `customizer` is provided it is\n     * invoked to produce the cloned values. If `customizer` returns `undefined`\n     * cloning is handled by the method instead. The `customizer` is bound to\n     * `thisArg` and invoked with two argument; (value [, index|key, object]).\n     *\n     * **Note:** This method is loosely based on the\n     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).\n     * The enumerable properties of `arguments` objects and objects created by\n     * constructors other than `Object` are cloned to plain `Object` objects. An\n     * empty object is returned for uncloneable values such as functions, DOM nodes,\n     * Maps, Sets, and WeakMaps.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @param {Function} [customizer] The function to customize cloning values.\n     * @param {*} [thisArg] The `this` binding of `customizer`.\n     * @returns {*} Returns the cloned value.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * var shallow = _.clone(users);\n     * shallow[0] === users[0];\n     * // => true\n     *\n     * var deep = _.clone(users, true);\n     * deep[0] === users[0];\n     * // => false\n     *\n     * // using a customizer callback\n     * var el = _.clone(document.body, function(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(false);\n     *   }\n     * });\n     *\n     * el === document.body\n     * // => false\n     * el.nodeName\n     * // => BODY\n     * el.childNodes.length;\n     * // => 0\n     */\n    function clone(value, isDeep, customizer, thisArg) {\n      if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {\n        isDeep = false;\n      }\n      else if (typeof isDeep == 'function') {\n        thisArg = customizer;\n        customizer = isDeep;\n        isDeep = false;\n      }\n      return typeof customizer == 'function'\n        ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1))\n        : baseClone(value, isDeep);\n    }\n\n    /**\n     * Creates a deep clone of `value`. If `customizer` is provided it is invoked\n     * to produce the cloned values. If `customizer` returns `undefined` cloning\n     * is handled by the method instead. The `customizer` is bound to `thisArg`\n     * and invoked with two argument; (value [, index|key, object]).\n     *\n     * **Note:** This method is loosely based on the\n     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).\n     * The enumerable properties of `arguments` objects and objects created by\n     * constructors other than `Object` are cloned to plain `Object` objects. An\n     * empty object is returned for uncloneable values such as functions, DOM nodes,\n     * Maps, Sets, and WeakMaps.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to deep clone.\n     * @param {Function} [customizer] The function to customize cloning values.\n     * @param {*} [thisArg] The `this` binding of `customizer`.\n     * @returns {*} Returns the deep cloned value.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * var deep = _.cloneDeep(users);\n     * deep[0] === users[0];\n     * // => false\n     *\n     * // using a customizer callback\n     * var el = _.cloneDeep(document.body, function(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(true);\n     *   }\n     * });\n     *\n     * el === document.body\n     * // => false\n     * el.nodeName\n     * // => BODY\n     * el.childNodes.length;\n     * // => 20\n     */\n    function cloneDeep(value, customizer, thisArg) {\n      return typeof customizer == 'function'\n        ? baseClone(value, true, bindCallback(customizer, thisArg, 1))\n        : baseClone(value, true);\n    }\n\n    /**\n     * Checks if `value` is greater than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.\n     * @example\n     *\n     * _.gt(3, 1);\n     * // => true\n     *\n     * _.gt(3, 3);\n     * // => false\n     *\n     * _.gt(1, 3);\n     * // => false\n     */\n    function gt(value, other) {\n      return value > other;\n    }\n\n    /**\n     * Checks if `value` is greater than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.\n     * @example\n     *\n     * _.gte(3, 1);\n     * // => true\n     *\n     * _.gte(3, 3);\n     * // => true\n     *\n     * _.gte(1, 3);\n     * // => false\n     */\n    function gte(value, other) {\n      return value >= other;\n    }\n\n    /**\n     * Checks if `value` is classified as an `arguments` object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isArguments(function() { return arguments; }());\n     * // => true\n     *\n     * _.isArguments([1, 2, 3]);\n     * // => false\n     */\n    function isArguments(value) {\n      return isObjectLike(value) && isArrayLike(value) &&\n        hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');\n    }\n\n    /**\n     * Checks if `value` is classified as an `Array` object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isArray([1, 2, 3]);\n     * // => true\n     *\n     * _.isArray(function() { return arguments; }());\n     * // => false\n     */\n    var isArray = nativeIsArray || function(value) {\n      return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n    };\n\n    /**\n     * Checks if `value` is classified as a boolean primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isBoolean(false);\n     * // => true\n     *\n     * _.isBoolean(null);\n     * // => false\n     */\n    function isBoolean(value) {\n      return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Date` object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isDate(new Date);\n     * // => true\n     *\n     * _.isDate('Mon April 23 2012');\n     * // => false\n     */\n    function isDate(value) {\n      return isObjectLike(value) && objToString.call(value) == dateTag;\n    }\n\n    /**\n     * Checks if `value` is a DOM element.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n     * @example\n     *\n     * _.isElement(document.body);\n     * // => true\n     *\n     * _.isElement('<body>');\n     * // => false\n     */\n    function isElement(value) {\n      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);\n    }\n\n    /**\n     * Checks if `value` is empty. A value is considered empty unless it is an\n     * `arguments` object, array, string, or jQuery-like collection with a length\n     * greater than `0` or an object with own enumerable properties.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {Array|Object|string} value The value to inspect.\n     * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n     * @example\n     *\n     * _.isEmpty(null);\n     * // => true\n     *\n     * _.isEmpty(true);\n     * // => true\n     *\n     * _.isEmpty(1);\n     * // => true\n     *\n     * _.isEmpty([1, 2, 3]);\n     * // => false\n     *\n     * _.isEmpty({ 'a': 1 });\n     * // => false\n     */\n    function isEmpty(value) {\n      if (value == null) {\n        return true;\n      }\n      if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||\n          (isObjectLike(value) && isFunction(value.splice)))) {\n        return !value.length;\n      }\n      return !keys(value).length;\n    }\n\n    /**\n     * Performs a deep comparison between two values to determine if they are\n     * equivalent. If `customizer` is provided it is invoked to compare values.\n     * If `customizer` returns `undefined` comparisons are handled by the method\n     * instead. The `customizer` is bound to `thisArg` and invoked with three\n     * arguments: (value, other [, index|key]).\n     *\n     * **Note:** This method supports comparing arrays, booleans, `Date` objects,\n     * numbers, `Object` objects, regexes, and strings. Objects are compared by\n     * their own, not inherited, enumerable properties. Functions and DOM nodes\n     * are **not** supported. Provide a customizer function to extend support\n     * for comparing other values.\n     *\n     * @static\n     * @memberOf _\n     * @alias eq\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {Function} [customizer] The function to customize value comparisons.\n     * @param {*} [thisArg] The `this` binding of `customizer`.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'user': 'fred' };\n     * var other = { 'user': 'fred' };\n     *\n     * object == other;\n     * // => false\n     *\n     * _.isEqual(object, other);\n     * // => true\n     *\n     * // using a customizer callback\n     * var array = ['hello', 'goodbye'];\n     * var other = ['hi', 'goodbye'];\n     *\n     * _.isEqual(array, other, function(value, other) {\n     *   if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {\n     *     return true;\n     *   }\n     * });\n     * // => true\n     */\n    function isEqual(value, other, customizer, thisArg) {\n      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;\n      var result = customizer ? customizer(value, other) : undefined;\n      return  result === undefined ? baseIsEqual(value, other, customizer) : !!result;\n    }\n\n    /**\n     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n     * `SyntaxError`, `TypeError`, or `URIError` object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n     * @example\n     *\n     * _.isError(new Error);\n     * // => true\n     *\n     * _.isError(Error);\n     * // => false\n     */\n    function isError(value) {\n      return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;\n    }\n\n    /**\n     * Checks if `value` is a finite primitive number.\n     *\n     * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n     * @example\n     *\n     * _.isFinite(10);\n     * // => true\n     *\n     * _.isFinite('10');\n     * // => false\n     *\n     * _.isFinite(true);\n     * // => false\n     *\n     * _.isFinite(Object(10));\n     * // => false\n     *\n     * _.isFinite(Infinity);\n     * // => false\n     */\n    function isFinite(value) {\n      return typeof value == 'number' && nativeIsFinite(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Function` object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isFunction(_);\n     * // => true\n     *\n     * _.isFunction(/abc/);\n     * // => false\n     */\n    function isFunction(value) {\n      // The use of `Object#toString` avoids issues with the `typeof` operator\n      // in older versions of Chrome and Safari which return 'function' for regexes\n      // and Safari 8 equivalents which return 'object' for typed array constructors.\n      return isObject(value) && objToString.call(value) == funcTag;\n    }\n\n    /**\n     * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n     * @example\n     *\n     * _.isObject({});\n     * // => true\n     *\n     * _.isObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isObject(1);\n     * // => false\n     */\n    function isObject(value) {\n      // Avoid a V8 JIT bug in Chrome 19-20.\n      // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n      var type = typeof value;\n      return !!value && (type == 'object' || type == 'function');\n    }\n\n    /**\n     * Performs a deep comparison between `object` and `source` to determine if\n     * `object` contains equivalent property values. If `customizer` is provided\n     * it is invoked to compare values. If `customizer` returns `undefined`\n     * comparisons are handled by the method instead. The `customizer` is bound\n     * to `thisArg` and invoked with three arguments: (value, other, index|key).\n     *\n     * **Note:** This method supports comparing properties of arrays, booleans,\n     * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions\n     * and DOM nodes are **not** supported. Provide a customizer function to extend\n     * support for comparing other values.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Function} [customizer] The function to customize value comparisons.\n     * @param {*} [thisArg] The `this` binding of `customizer`.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * var object = { 'user': 'fred', 'age': 40 };\n     *\n     * _.isMatch(object, { 'age': 40 });\n     * // => true\n     *\n     * _.isMatch(object, { 'age': 36 });\n     * // => false\n     *\n     * // using a customizer callback\n     * var object = { 'greeting': 'hello' };\n     * var source = { 'greeting': 'hi' };\n     *\n     * _.isMatch(object, source, function(value, other) {\n     *   return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined;\n     * });\n     * // => true\n     */\n    function isMatch(object, source, customizer, thisArg) {\n      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;\n      return baseIsMatch(object, getMatchData(source), customizer);\n    }\n\n    /**\n     * Checks if `value` is `NaN`.\n     *\n     * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)\n     * which returns `true` for `undefined` and other non-numeric values.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n     * @example\n     *\n     * _.isNaN(NaN);\n     * // => true\n     *\n     * _.isNaN(new Number(NaN));\n     * // => true\n     *\n     * isNaN(undefined);\n     * // => true\n     *\n     * _.isNaN(undefined);\n     * // => false\n     */\n    function isNaN(value) {\n      // An `NaN` primitive is the only value that is not equal to itself.\n      // Perform the `toStringTag` check first to avoid errors with some host objects in IE.\n      return isNumber(value) && value != +value;\n    }\n\n    /**\n     * Checks if `value` is a native function.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n     * @example\n     *\n     * _.isNative(Array.prototype.push);\n     * // => true\n     *\n     * _.isNative(_);\n     * // => false\n     */\n    function isNative(value) {\n      if (value == null) {\n        return false;\n      }\n      if (isFunction(value)) {\n        return reIsNative.test(fnToString.call(value));\n      }\n      return isObjectLike(value) && reIsHostCtor.test(value);\n    }\n\n    /**\n     * Checks if `value` is `null`.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n     * @example\n     *\n     * _.isNull(null);\n     * // => true\n     *\n     * _.isNull(void 0);\n     * // => false\n     */\n    function isNull(value) {\n      return value === null;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Number` primitive or object.\n     *\n     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified\n     * as numbers, use the `_.isFinite` method.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isNumber(8.4);\n     * // => true\n     *\n     * _.isNumber(NaN);\n     * // => true\n     *\n     * _.isNumber('8.4');\n     * // => false\n     */\n    function isNumber(value) {\n      return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);\n    }\n\n    /**\n     * Checks if `value` is a plain object, that is, an object created by the\n     * `Object` constructor or one with a `[[Prototype]]` of `null`.\n     *\n     * **Note:** This method assumes objects created by the `Object` constructor\n     * have no inherited enumerable properties.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * _.isPlainObject(new Foo);\n     * // => false\n     *\n     * _.isPlainObject([1, 2, 3]);\n     * // => false\n     *\n     * _.isPlainObject({ 'x': 0, 'y': 0 });\n     * // => true\n     *\n     * _.isPlainObject(Object.create(null));\n     * // => true\n     */\n    function isPlainObject(value) {\n      var Ctor;\n\n      // Exit early for non `Object` objects.\n      if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||\n          (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {\n        return false;\n      }\n      // IE < 9 iterates inherited properties before own properties. If the first\n      // iterated property is an object's own property then there are no inherited\n      // enumerable properties.\n      var result;\n      // In most environments an object's own properties are iterated before\n      // its inherited properties. If the last iterated property is an object's\n      // own property then there are no inherited enumerable properties.\n      baseForIn(value, function(subValue, key) {\n        result = key;\n      });\n      return result === undefined || hasOwnProperty.call(value, result);\n    }\n\n    /**\n     * Checks if `value` is classified as a `RegExp` object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isRegExp(/abc/);\n     * // => true\n     *\n     * _.isRegExp('/abc/');\n     * // => false\n     */\n    function isRegExp(value) {\n      return isObject(value) && objToString.call(value) == regexpTag;\n    }\n\n    /**\n     * Checks if `value` is classified as a `String` primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isString('abc');\n     * // => true\n     *\n     * _.isString(1);\n     * // => false\n     */\n    function isString(value) {\n      return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a typed array.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n     * @example\n     *\n     * _.isTypedArray(new Uint8Array);\n     * // => true\n     *\n     * _.isTypedArray([]);\n     * // => false\n     */\n    function isTypedArray(value) {\n      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];\n    }\n\n    /**\n     * Checks if `value` is `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n     * @example\n     *\n     * _.isUndefined(void 0);\n     * // => true\n     *\n     * _.isUndefined(null);\n     * // => false\n     */\n    function isUndefined(value) {\n      return value === undefined;\n    }\n\n    /**\n     * Checks if `value` is less than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.\n     * @example\n     *\n     * _.lt(1, 3);\n     * // => true\n     *\n     * _.lt(3, 3);\n     * // => false\n     *\n     * _.lt(3, 1);\n     * // => false\n     */\n    function lt(value, other) {\n      return value < other;\n    }\n\n    /**\n     * Checks if `value` is less than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.\n     * @example\n     *\n     * _.lte(1, 3);\n     * // => true\n     *\n     * _.lte(3, 3);\n     * // => true\n     *\n     * _.lte(3, 1);\n     * // => false\n     */\n    function lte(value, other) {\n      return value <= other;\n    }\n\n    /**\n     * Converts `value` to an array.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the converted array.\n     * @example\n     *\n     * (function() {\n     *   return _.toArray(arguments).slice(1);\n     * }(1, 2, 3));\n     * // => [2, 3]\n     */\n    function toArray(value) {\n      var length = value ? getLength(value) : 0;\n      if (!isLength(length)) {\n        return values(value);\n      }\n      if (!length) {\n        return [];\n      }\n      return arrayCopy(value);\n    }\n\n    /**\n     * Converts `value` to a plain object flattening inherited enumerable\n     * properties of `value` to own properties of the plain object.\n     *\n     * @static\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Object} Returns the converted plain object.\n     * @example\n     *\n     * function Foo() {\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.assign({ 'a': 1 }, new Foo);\n     * // => { 'a': 1, 'b': 2 }\n     *\n     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n     * // => { 'a': 1, 'b': 2, 'c': 3 }\n     */\n    function toPlainObject(value) {\n      return baseCopy(value, keysIn(value));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Recursively merges own enumerable properties of the source object(s), that\n     * don't resolve to `undefined` into the destination object. Subsequent sources\n     * overwrite property assignments of previous sources. If `customizer` is\n     * provided it is invoked to produce the merged values of the destination and\n     * source properties. If `customizer` returns `undefined` merging is handled\n     * by the method instead. The `customizer` is bound to `thisArg` and invoked\n     * with five arguments: (objectValue, sourceValue, key, object, source).\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @param {*} [thisArg] The `this` binding of `customizer`.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var users = {\n     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]\n     * };\n     *\n     * var ages = {\n     *   'data': [{ 'age': 36 }, { 'age': 40 }]\n     * };\n     *\n     * _.merge(users, ages);\n     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }\n     *\n     * // using a customizer callback\n     * var object = {\n     *   'fruits': ['apple'],\n     *   'vegetables': ['beet']\n     * };\n     *\n     * var other = {\n     *   'fruits': ['banana'],\n     *   'vegetables': ['carrot']\n     * };\n     *\n     * _.merge(object, other, function(a, b) {\n     *   if (_.isArray(a)) {\n     *     return a.concat(b);\n     *   }\n     * });\n     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }\n     */\n    var merge = createAssigner(baseMerge);\n\n    /**\n     * Assigns own enumerable properties of source object(s) to the destination\n     * object. Subsequent sources overwrite property assignments of previous sources.\n     * If `customizer` is provided it is invoked to produce the assigned values.\n     * The `customizer` is bound to `thisArg` and invoked with five arguments:\n     * (objectValue, sourceValue, key, object, source).\n     *\n     * **Note:** This method mutates `object` and is based on\n     * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).\n     *\n     * @static\n     * @memberOf _\n     * @alias extend\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @param {*} [thisArg] The `this` binding of `customizer`.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });\n     * // => { 'user': 'fred', 'age': 40 }\n     *\n     * // using a customizer callback\n     * var defaults = _.partialRight(_.assign, function(value, other) {\n     *   return _.isUndefined(value) ? other : value;\n     * });\n     *\n     * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });\n     * // => { 'user': 'barney', 'age': 36 }\n     */\n    var assign = createAssigner(function(object, source, customizer) {\n      return customizer\n        ? assignWith(object, source, customizer)\n        : baseAssign(object, source);\n    });\n\n    /**\n     * Creates an object that inherits from the given `prototype` object. If a\n     * `properties` object is provided its own enumerable properties are assigned\n     * to the created object.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} prototype The object to inherit from.\n     * @param {Object} [properties] The properties to assign to the object.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * function Shape() {\n     *   this.x = 0;\n     *   this.y = 0;\n     * }\n     *\n     * function Circle() {\n     *   Shape.call(this);\n     * }\n     *\n     * Circle.prototype = _.create(Shape.prototype, {\n     *   'constructor': Circle\n     * });\n     *\n     * var circle = new Circle;\n     * circle instanceof Circle;\n     * // => true\n     *\n     * circle instanceof Shape;\n     * // => true\n     */\n    function create(prototype, properties, guard) {\n      var result = baseCreate(prototype);\n      if (guard && isIterateeCall(prototype, properties, guard)) {\n        properties = undefined;\n      }\n      return properties ? baseAssign(result, properties) : result;\n    }\n\n    /**\n     * Assigns own enumerable properties of source object(s) to the destination\n     * object for all destination properties that resolve to `undefined`. Once a\n     * property is set, additional values of the same property are ignored.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });\n     * // => { 'user': 'barney', 'age': 36 }\n     */\n    var defaults = createDefaults(assign, assignDefaults);\n\n    /**\n     * This method is like `_.defaults` except that it recursively assigns\n     * default properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });\n     * // => { 'user': { 'name': 'barney', 'age': 36 } }\n     *\n     */\n    var defaultsDeep = createDefaults(merge, mergeDefaults);\n\n    /**\n     * This method is like `_.find` except that it returns the key of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to search.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findKey(users, function(chr) {\n     *   return chr.age < 40;\n     * });\n     * // => 'barney' (iteration order is not guaranteed)\n     *\n     * // using the `_.matches` callback shorthand\n     * _.findKey(users, { 'age': 1, 'active': true });\n     * // => 'pebbles'\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.findKey(users, 'active', false);\n     * // => 'fred'\n     *\n     * // using the `_.property` callback shorthand\n     * _.findKey(users, 'active');\n     * // => 'barney'\n     */\n    var findKey = createFindKey(baseForOwn);\n\n    /**\n     * This method is like `_.findKey` except that it iterates over elements of\n     * a collection in the opposite order.\n     *\n     * If a property name is provided for `predicate` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `predicate` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to search.\n     * @param {Function|Object|string} [predicate=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findLastKey(users, function(chr) {\n     *   return chr.age < 40;\n     * });\n     * // => returns `pebbles` assuming `_.findKey` returns `barney`\n     *\n     * // using the `_.matches` callback shorthand\n     * _.findLastKey(users, { 'age': 36, 'active': true });\n     * // => 'barney'\n     *\n     * // using the `_.matchesProperty` callback shorthand\n     * _.findLastKey(users, 'active', false);\n     * // => 'fred'\n     *\n     * // using the `_.property` callback shorthand\n     * _.findLastKey(users, 'active');\n     * // => 'pebbles'\n     */\n    var findLastKey = createFindKey(baseForOwnRight);\n\n    /**\n     * Iterates over own and inherited enumerable properties of an object invoking\n     * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked\n     * with three arguments: (value, key, object). Iteratee functions may exit\n     * iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forIn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)\n     */\n    var forIn = createForIn(baseFor);\n\n    /**\n     * This method is like `_.forIn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forInRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'\n     */\n    var forInRight = createForIn(baseForRight);\n\n    /**\n     * Iterates over own enumerable properties of an object invoking `iteratee`\n     * for each property. The `iteratee` is bound to `thisArg` and invoked with\n     * three arguments: (value, key, object). Iteratee functions may exit iteration\n     * early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => logs 'a' and 'b' (iteration order is not guaranteed)\n     */\n    var forOwn = createForOwn(baseForOwn);\n\n    /**\n     * This method is like `_.forOwn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwnRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'\n     */\n    var forOwnRight = createForOwn(baseForOwnRight);\n\n    /**\n     * Creates an array of function property names from all enumerable properties,\n     * own and inherited, of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @alias methods\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the new array of property names.\n     * @example\n     *\n     * _.functions(_);\n     * // => ['after', 'ary', 'assign', ...]\n     */\n    function functions(object) {\n      return baseFunctions(object, keysIn(object));\n    }\n\n    /**\n     * Gets the property value at `path` of `object`. If the resolved value is\n     * `undefined` the `defaultValue` is used in its place.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.get(object, 'a[0].b.c');\n     * // => 3\n     *\n     * _.get(object, ['a', '0', 'b', 'c']);\n     * // => 3\n     *\n     * _.get(object, 'a.b.c', 'default');\n     * // => 'default'\n     */\n    function get(object, path, defaultValue) {\n      var result = object == null ? undefined : baseGet(object, toPath(path), path + '');\n      return result === undefined ? defaultValue : result;\n    }\n\n    /**\n     * Checks if `path` is a direct property.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` is a direct property, else `false`.\n     * @example\n     *\n     * var object = { 'a': { 'b': { 'c': 3 } } };\n     *\n     * _.has(object, 'a');\n     * // => true\n     *\n     * _.has(object, 'a.b.c');\n     * // => true\n     *\n     * _.has(object, ['a', 'b', 'c']);\n     * // => true\n     */\n    function has(object, path) {\n      if (object == null) {\n        return false;\n      }\n      var result = hasOwnProperty.call(object, path);\n      if (!result && !isKey(path)) {\n        path = toPath(path);\n        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));\n        if (object == null) {\n          return false;\n        }\n        path = last(path);\n        result = hasOwnProperty.call(object, path);\n      }\n      return result || (isLength(object.length) && isIndex(path, object.length) &&\n        (isArray(object) || isArguments(object)));\n    }\n\n    /**\n     * Creates an object composed of the inverted keys and values of `object`.\n     * If `object` contains duplicate values, subsequent values overwrite property\n     * assignments of previous values unless `multiValue` is `true`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @param {boolean} [multiValue] Allow multiple values per key.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invert(object);\n     * // => { '1': 'c', '2': 'b' }\n     *\n     * // with `multiValue`\n     * _.invert(object, true);\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     */\n    function invert(object, multiValue, guard) {\n      if (guard && isIterateeCall(object, multiValue, guard)) {\n        multiValue = undefined;\n      }\n      var index = -1,\n          props = keys(object),\n          length = props.length,\n          result = {};\n\n      while (++index < length) {\n        var key = props[index],\n            value = object[key];\n\n        if (multiValue) {\n          if (hasOwnProperty.call(result, value)) {\n            result[value].push(key);\n          } else {\n            result[value] = [key];\n          }\n        }\n        else {\n          result[value] = key;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array of the own enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects. See the\n     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n     * for more details.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keys(new Foo);\n     * // => ['a', 'b'] (iteration order is not guaranteed)\n     *\n     * _.keys('hi');\n     * // => ['0', '1']\n     */\n    var keys = !nativeKeys ? shimKeys : function(object) {\n      var Ctor = object == null ? undefined : object.constructor;\n      if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n          (typeof object != 'function' && isArrayLike(object))) {\n        return shimKeys(object);\n      }\n      return isObject(object) ? nativeKeys(object) : [];\n    };\n\n    /**\n     * Creates an array of the own and inherited enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keysIn(new Foo);\n     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n     */\n    function keysIn(object) {\n      if (object == null) {\n        return [];\n      }\n      if (!isObject(object)) {\n        object = Object(object);\n      }\n      var length = object.length;\n      length = (length && isLength(length) &&\n        (isArray(object) || isArguments(object)) && length) || 0;\n\n      var Ctor = object.constructor,\n          index = -1,\n          isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n          result = Array(length),\n          skipIndexes = length > 0;\n\n      while (++index < length) {\n        result[index] = (index + '');\n      }\n      for (var key in object) {\n        if (!(skipIndexes && isIndex(key, length)) &&\n            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The opposite of `_.mapValues`; this method creates an object with the\n     * same values as `object` and keys generated by running each own enumerable\n     * property of `object` through `iteratee`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns the new mapped object.\n     * @example\n     *\n     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   return key + value;\n     * });\n     * // => { 'a1': 1, 'b2': 2 }\n     */\n    var mapKeys = createObjectMapper(true);\n\n    /**\n     * Creates an object with the same keys as `object` and values generated by\n     * running each own enumerable property of `object` through `iteratee`. The\n     * iteratee function is bound to `thisArg` and invoked with three arguments:\n     * (value, key, object).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function|Object|string} [iteratee=_.identity] The function invoked\n     *  per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Object} Returns the new mapped object.\n     * @example\n     *\n     * _.mapValues({ 'a': 1, 'b': 2 }, function(n) {\n     *   return n * 3;\n     * });\n     * // => { 'a': 3, 'b': 6 }\n     *\n     * var users = {\n     *   'fred':    { 'user': 'fred',    'age': 40 },\n     *   'pebbles': { 'user': 'pebbles', 'age': 1 }\n     * };\n     *\n     * // using the `_.property` callback shorthand\n     * _.mapValues(users, 'age');\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     */\n    var mapValues = createObjectMapper();\n\n    /**\n     * The opposite of `_.pick`; this method creates an object composed of the\n     * own and inherited enumerable properties of `object` that are not omitted.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function|...(string|string[])} [predicate] The function invoked per\n     *  iteration or property names to omit, specified as individual property\n     *  names or arrays of property names.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'user': 'fred', 'age': 40 };\n     *\n     * _.omit(object, 'age');\n     * // => { 'user': 'fred' }\n     *\n     * _.omit(object, _.isNumber);\n     * // => { 'user': 'fred' }\n     */\n    var omit = restParam(function(object, props) {\n      if (object == null) {\n        return {};\n      }\n      if (typeof props[0] != 'function') {\n        var props = arrayMap(baseFlatten(props), String);\n        return pickByArray(object, baseDifference(keysIn(object), props));\n      }\n      var predicate = bindCallback(props[0], props[1], 3);\n      return pickByCallback(object, function(value, key, object) {\n        return !predicate(value, key, object);\n      });\n    });\n\n    /**\n     * Creates a two dimensional array of the key-value pairs for `object`,\n     * e.g. `[[key1, value1], [key2, value2]]`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the new array of key-value pairs.\n     * @example\n     *\n     * _.pairs({ 'barney': 36, 'fred': 40 });\n     * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)\n     */\n    function pairs(object) {\n      object = toObject(object);\n\n      var index = -1,\n          props = keys(object),\n          length = props.length,\n          result = Array(length);\n\n      while (++index < length) {\n        var key = props[index];\n        result[index] = [key, object[key]];\n      }\n      return result;\n    }\n\n    /**\n     * Creates an object composed of the picked `object` properties. Property\n     * names may be specified as individual arguments or as arrays of property\n     * names. If `predicate` is provided it is invoked for each property of `object`\n     * picking the properties `predicate` returns truthy for. The predicate is\n     * bound to `thisArg` and invoked with three arguments: (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function|...(string|string[])} [predicate] The function invoked per\n     *  iteration or property names to pick, specified as individual property\n     *  names or arrays of property names.\n     * @param {*} [thisArg] The `this` binding of `predicate`.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'user': 'fred', 'age': 40 };\n     *\n     * _.pick(object, 'user');\n     * // => { 'user': 'fred' }\n     *\n     * _.pick(object, _.isString);\n     * // => { 'user': 'fred' }\n     */\n    var pick = restParam(function(object, props) {\n      if (object == null) {\n        return {};\n      }\n      return typeof props[0] == 'function'\n        ? pickByCallback(object, bindCallback(props[0], props[1], 3))\n        : pickByArray(object, baseFlatten(props));\n    });\n\n    /**\n     * This method is like `_.get` except that if the resolved value is a function\n     * it is invoked with the `this` binding of its parent object and its result\n     * is returned.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to resolve.\n     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n     *\n     * _.result(object, 'a[0].b.c1');\n     * // => 3\n     *\n     * _.result(object, 'a[0].b.c2');\n     * // => 4\n     *\n     * _.result(object, 'a.b.c', 'default');\n     * // => 'default'\n     *\n     * _.result(object, 'a.b.c', _.constant('default'));\n     * // => 'default'\n     */\n    function result(object, path, defaultValue) {\n      var result = object == null ? undefined : object[path];\n      if (result === undefined) {\n        if (object != null && !isKey(path, object)) {\n          path = toPath(path);\n          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));\n          result = object == null ? undefined : object[last(path)];\n        }\n        result = result === undefined ? defaultValue : result;\n      }\n      return isFunction(result) ? result.call(object) : result;\n    }\n\n    /**\n     * Sets the property value of `path` on `object`. If a portion of `path`\n     * does not exist it is created.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to augment.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.set(object, 'a[0].b.c', 4);\n     * console.log(object.a[0].b.c);\n     * // => 4\n     *\n     * _.set(object, 'x[0].y.z', 5);\n     * console.log(object.x[0].y.z);\n     * // => 5\n     */\n    function set(object, path, value) {\n      if (object == null) {\n        return object;\n      }\n      var pathKey = (path + '');\n      path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);\n\n      var index = -1,\n          length = path.length,\n          lastIndex = length - 1,\n          nested = object;\n\n      while (nested != null && ++index < length) {\n        var key = path[index];\n        if (isObject(nested)) {\n          if (index == lastIndex) {\n            nested[key] = value;\n          } else if (nested[key] == null) {\n            nested[key] = isIndex(path[index + 1]) ? [] : {};\n          }\n        }\n        nested = nested[key];\n      }\n      return object;\n    }\n\n    /**\n     * An alternative to `_.reduce`; this method transforms `object` to a new\n     * `accumulator` object which is the result of running each of its own enumerable\n     * properties through `iteratee`, with each invocation potentially mutating\n     * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked\n     * with four arguments: (accumulator, value, key, object). Iteratee functions\n     * may exit iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Array|Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The custom accumulator value.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {*} Returns the accumulated value.\n     * @example\n     *\n     * _.transform([2, 3, 4], function(result, n) {\n     *   result.push(n *= n);\n     *   return n % 2 == 0;\n     * });\n     * // => [4, 9]\n     *\n     * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) {\n     *   result[key] = n * 3;\n     * });\n     * // => { 'a': 3, 'b': 6 }\n     */\n    function transform(object, iteratee, accumulator, thisArg) {\n      var isArr = isArray(object) || isTypedArray(object);\n      iteratee = getCallback(iteratee, thisArg, 4);\n\n      if (accumulator == null) {\n        if (isArr || isObject(object)) {\n          var Ctor = object.constructor;\n          if (isArr) {\n            accumulator = isArray(object) ? new Ctor : [];\n          } else {\n            accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);\n          }\n        } else {\n          accumulator = {};\n        }\n      }\n      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {\n        return iteratee(accumulator, value, index, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * Creates an array of the own enumerable property values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.values(new Foo);\n     * // => [1, 2] (iteration order is not guaranteed)\n     *\n     * _.values('hi');\n     * // => ['h', 'i']\n     */\n    function values(object) {\n      return baseValues(object, keys(object));\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable property values\n     * of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.valuesIn(new Foo);\n     * // => [1, 2, 3] (iteration order is not guaranteed)\n     */\n    function valuesIn(object) {\n      return baseValues(object, keysIn(object));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Checks if `n` is between `start` and up to but not including, `end`. If\n     * `end` is not specified it is set to `start` with `start` then set to `0`.\n     *\n     * @static\n     * @memberOf _\n     * @category Number\n     * @param {number} n The number to check.\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `n` is in the range, else `false`.\n     * @example\n     *\n     * _.inRange(3, 2, 4);\n     * // => true\n     *\n     * _.inRange(4, 8);\n     * // => true\n     *\n     * _.inRange(4, 2);\n     * // => false\n     *\n     * _.inRange(2, 2);\n     * // => false\n     *\n     * _.inRange(1.2, 2);\n     * // => true\n     *\n     * _.inRange(5.2, 4);\n     * // => false\n     */\n    function inRange(value, start, end) {\n      start = +start || 0;\n      if (end === undefined) {\n        end = start;\n        start = 0;\n      } else {\n        end = +end || 0;\n      }\n      return value >= nativeMin(start, end) && value < nativeMax(start, end);\n    }\n\n    /**\n     * Produces a random number between `min` and `max` (inclusive). If only one\n     * argument is provided a number between `0` and the given number is returned.\n     * If `floating` is `true`, or either `min` or `max` are floats, a floating-point\n     * number is returned instead of an integer.\n     *\n     * @static\n     * @memberOf _\n     * @category Number\n     * @param {number} [min=0] The minimum possible value.\n     * @param {number} [max=1] The maximum possible value.\n     * @param {boolean} [floating] Specify returning a floating-point number.\n     * @returns {number} Returns the random number.\n     * @example\n     *\n     * _.random(0, 5);\n     * // => an integer between 0 and 5\n     *\n     * _.random(5);\n     * // => also an integer between 0 and 5\n     *\n     * _.random(5, true);\n     * // => a floating-point number between 0 and 5\n     *\n     * _.random(1.2, 5.2);\n     * // => a floating-point number between 1.2 and 5.2\n     */\n    function random(min, max, floating) {\n      if (floating && isIterateeCall(min, max, floating)) {\n        max = floating = undefined;\n      }\n      var noMin = min == null,\n          noMax = max == null;\n\n      if (floating == null) {\n        if (noMax && typeof min == 'boolean') {\n          floating = min;\n          min = 1;\n        }\n        else if (typeof max == 'boolean') {\n          floating = max;\n          noMax = true;\n        }\n      }\n      if (noMin && noMax) {\n        max = 1;\n        noMax = false;\n      }\n      min = +min || 0;\n      if (noMax) {\n        max = min;\n        min = 0;\n      } else {\n        max = +max || 0;\n      }\n      if (floating || min % 1 || max % 1) {\n        var rand = nativeRandom();\n        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);\n      }\n      return baseRandom(min, max);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the camel cased string.\n     * @example\n     *\n     * _.camelCase('Foo Bar');\n     * // => 'fooBar'\n     *\n     * _.camelCase('--foo-bar');\n     * // => 'fooBar'\n     *\n     * _.camelCase('__foo_bar__');\n     * // => 'fooBar'\n     */\n    var camelCase = createCompounder(function(result, word, index) {\n      word = word.toLowerCase();\n      return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);\n    });\n\n    /**\n     * Capitalizes the first character of `string`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to capitalize.\n     * @returns {string} Returns the capitalized string.\n     * @example\n     *\n     * _.capitalize('fred');\n     * // => 'Fred'\n     */\n    function capitalize(string) {\n      string = baseToString(string);\n      return string && (string.charAt(0).toUpperCase() + string.slice(1));\n    }\n\n    /**\n     * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n     * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to deburr.\n     * @returns {string} Returns the deburred string.\n     * @example\n     *\n     * _.deburr('déjà vu');\n     * // => 'deja vu'\n     */\n    function deburr(string) {\n      string = baseToString(string);\n      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');\n    }\n\n    /**\n     * Checks if `string` ends with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to search.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=string.length] The position to search from.\n     * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.\n     * @example\n     *\n     * _.endsWith('abc', 'c');\n     * // => true\n     *\n     * _.endsWith('abc', 'b');\n     * // => false\n     *\n     * _.endsWith('abc', 'b', 2);\n     * // => true\n     */\n    function endsWith(string, target, position) {\n      string = baseToString(string);\n      target = (target + '');\n\n      var length = string.length;\n      position = position === undefined\n        ? length\n        : nativeMin(position < 0 ? 0 : (+position || 0), length);\n\n      position -= target.length;\n      return position >= 0 && string.indexOf(target, position) == position;\n    }\n\n    /**\n     * Converts the characters \"&\", \"<\", \">\", '\"', \"'\", and \"\\`\", in `string` to\n     * their corresponding HTML entities.\n     *\n     * **Note:** No other characters are escaped. To escape additional characters\n     * use a third-party library like [_he_](https://mths.be/he).\n     *\n     * Though the \">\" character is escaped for symmetry, characters like\n     * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n     * unless they're part of a tag or unquoted attribute value.\n     * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n     * (under \"semi-related fun fact\") for more details.\n     *\n     * Backticks are escaped because in Internet Explorer < 9, they can break out\n     * of attribute values or HTML comments. See [#59](https://html5sec.org/#59),\n     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and\n     * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)\n     * for more details.\n     *\n     * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)\n     * to reduce XSS vectors.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escape('fred, barney, & pebbles');\n     * // => 'fred, barney, &amp; pebbles'\n     */\n    function escape(string) {\n      // Reset `lastIndex` because in IE < 9 `String#replace` does not.\n      string = baseToString(string);\n      return (string && reHasUnescapedHtml.test(string))\n        ? string.replace(reUnescapedHtml, escapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Escapes the `RegExp` special characters \"\\\", \"/\", \"^\", \"$\", \".\", \"|\", \"?\",\n     * \"*\", \"+\", \"(\", \")\", \"[\", \"]\", \"{\" and \"}\" in `string`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escapeRegExp('[lodash](https://lodash.com/)');\n     * // => '\\[lodash\\]\\(https:\\/\\/lodash\\.com\\/\\)'\n     */\n    function escapeRegExp(string) {\n      string = baseToString(string);\n      return (string && reHasRegExpChars.test(string))\n        ? string.replace(reRegExpChars, escapeRegExpChar)\n        : (string || '(?:)');\n    }\n\n    /**\n     * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the kebab cased string.\n     * @example\n     *\n     * _.kebabCase('Foo Bar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('fooBar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('__foo_bar__');\n     * // => 'foo-bar'\n     */\n    var kebabCase = createCompounder(function(result, word, index) {\n      return result + (index ? '-' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Pads `string` on the left and right sides if it's shorter than `length`.\n     * Padding characters are truncated if they can't be evenly divided by `length`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.pad('abc', 8);\n     * // => '  abc   '\n     *\n     * _.pad('abc', 8, '_-');\n     * // => '_-abc_-_'\n     *\n     * _.pad('abc', 3);\n     * // => 'abc'\n     */\n    function pad(string, length, chars) {\n      string = baseToString(string);\n      length = +length;\n\n      var strLength = string.length;\n      if (strLength >= length || !nativeIsFinite(length)) {\n        return string;\n      }\n      var mid = (length - strLength) / 2,\n          leftLength = nativeFloor(mid),\n          rightLength = nativeCeil(mid);\n\n      chars = createPadding('', rightLength, chars);\n      return chars.slice(0, leftLength) + string + chars;\n    }\n\n    /**\n     * Pads `string` on the left side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padLeft('abc', 6);\n     * // => '   abc'\n     *\n     * _.padLeft('abc', 6, '_-');\n     * // => '_-_abc'\n     *\n     * _.padLeft('abc', 3);\n     * // => 'abc'\n     */\n    var padLeft = createPadDir();\n\n    /**\n     * Pads `string` on the right side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padRight('abc', 6);\n     * // => 'abc   '\n     *\n     * _.padRight('abc', 6, '_-');\n     * // => 'abc_-_'\n     *\n     * _.padRight('abc', 3);\n     * // => 'abc'\n     */\n    var padRight = createPadDir(true);\n\n    /**\n     * Converts `string` to an integer of the specified radix. If `radix` is\n     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,\n     * in which case a `radix` of `16` is used.\n     *\n     * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)\n     * of `parseInt`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} string The string to convert.\n     * @param {number} [radix] The radix to interpret `value` by.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.parseInt('08');\n     * // => 8\n     *\n     * _.map(['6', '08', '10'], _.parseInt);\n     * // => [6, 8, 10]\n     */\n    function parseInt(string, radix, guard) {\n      // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.\n      // Chrome fails to trim leading <BOM> whitespace characters.\n      // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.\n      if (guard ? isIterateeCall(string, radix, guard) : radix == null) {\n        radix = 0;\n      } else if (radix) {\n        radix = +radix;\n      }\n      string = trim(string);\n      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));\n    }\n\n    /**\n     * Repeats the given string `n` times.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to repeat.\n     * @param {number} [n=0] The number of times to repeat the string.\n     * @returns {string} Returns the repeated string.\n     * @example\n     *\n     * _.repeat('*', 3);\n     * // => '***'\n     *\n     * _.repeat('abc', 2);\n     * // => 'abcabc'\n     *\n     * _.repeat('abc', 0);\n     * // => ''\n     */\n    function repeat(string, n) {\n      var result = '';\n      string = baseToString(string);\n      n = +n;\n      if (n < 1 || !string || !nativeIsFinite(n)) {\n        return result;\n      }\n      // Leverage the exponentiation by squaring algorithm for a faster repeat.\n      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n      do {\n        if (n % 2) {\n          result += string;\n        }\n        n = nativeFloor(n / 2);\n        string += string;\n      } while (n);\n\n      return result;\n    }\n\n    /**\n     * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the snake cased string.\n     * @example\n     *\n     * _.snakeCase('Foo Bar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('fooBar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('--foo-bar');\n     * // => 'foo_bar'\n     */\n    var snakeCase = createCompounder(function(result, word, index) {\n      return result + (index ? '_' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the start cased string.\n     * @example\n     *\n     * _.startCase('--foo-bar');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('fooBar');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('__foo_bar__');\n     * // => 'Foo Bar'\n     */\n    var startCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));\n    });\n\n    /**\n     * Checks if `string` starts with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to search.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=0] The position to search from.\n     * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.\n     * @example\n     *\n     * _.startsWith('abc', 'a');\n     * // => true\n     *\n     * _.startsWith('abc', 'b');\n     * // => false\n     *\n     * _.startsWith('abc', 'b', 1);\n     * // => true\n     */\n    function startsWith(string, target, position) {\n      string = baseToString(string);\n      position = position == null\n        ? 0\n        : nativeMin(position < 0 ? 0 : (+position || 0), string.length);\n\n      return string.lastIndexOf(target, position) == position;\n    }\n\n    /**\n     * Creates a compiled template function that can interpolate data properties\n     * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n     * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n     * properties may be accessed as free variables in the template. If a setting\n     * object is provided it takes precedence over `_.templateSettings` values.\n     *\n     * **Note:** In the development build `_.template` utilizes\n     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n     * for easier debugging.\n     *\n     * For more information on precompiling templates see\n     * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n     *\n     * For more information on Chrome extension sandboxes see\n     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The template string.\n     * @param {Object} [options] The options object.\n     * @param {RegExp} [options.escape] The HTML \"escape\" delimiter.\n     * @param {RegExp} [options.evaluate] The \"evaluate\" delimiter.\n     * @param {Object} [options.imports] An object to import into the template as free variables.\n     * @param {RegExp} [options.interpolate] The \"interpolate\" delimiter.\n     * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.\n     * @param {string} [options.variable] The data object variable name.\n     * @param- {Object} [otherOptions] Enables the legacy `options` param signature.\n     * @returns {Function} Returns the compiled template function.\n     * @example\n     *\n     * // using the \"interpolate\" delimiter to create a compiled template\n     * var compiled = _.template('hello <%= user %>!');\n     * compiled({ 'user': 'fred' });\n     * // => 'hello fred!'\n     *\n     * // using the HTML \"escape\" delimiter to escape data property values\n     * var compiled = _.template('<b><%- value %></b>');\n     * compiled({ 'value': '<script>' });\n     * // => '<b>&lt;script&gt;</b>'\n     *\n     * // using the \"evaluate\" delimiter to execute JavaScript and generate HTML\n     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // using the internal `print` function in \"evaluate\" delimiters\n     * var compiled = _.template('<% print(\"hello \" + user); %>!');\n     * compiled({ 'user': 'barney' });\n     * // => 'hello barney!'\n     *\n     * // using the ES delimiter as an alternative to the default \"interpolate\" delimiter\n     * var compiled = _.template('hello ${ user }!');\n     * compiled({ 'user': 'pebbles' });\n     * // => 'hello pebbles!'\n     *\n     * // using custom template delimiters\n     * _.templateSettings.interpolate = /{{([\\s\\S]+?)}}/g;\n     * var compiled = _.template('hello {{ user }}!');\n     * compiled({ 'user': 'mustache' });\n     * // => 'hello mustache!'\n     *\n     * // using backslashes to treat delimiters as plain text\n     * var compiled = _.template('<%= \"\\\\<%- value %\\\\>\" %>');\n     * compiled({ 'value': 'ignored' });\n     * // => '<%- value %>'\n     *\n     * // using the `imports` option to import `jQuery` as `jq`\n     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';\n     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // using the `sourceURL` option to specify a custom sourceURL for the template\n     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });\n     * compiled(data);\n     * // => find the source of \"greeting.jst\" under the Sources tab or Resources panel of the web inspector\n     *\n     * // using the `variable` option to ensure a with-statement isn't used in the compiled template\n     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });\n     * compiled.source;\n     * // => function(data) {\n     * //   var __t, __p = '';\n     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';\n     * //   return __p;\n     * // }\n     *\n     * // using the `source` property to inline compiled templates for meaningful\n     * // line numbers in error messages and a stack trace\n     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\\\n     *   var JST = {\\\n     *     \"main\": ' + _.template(mainText).source + '\\\n     *   };\\\n     * ');\n     */\n    function template(string, options, otherOptions) {\n      // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)\n      // and Laura Doktorova's doT.js (https://github.com/olado/doT).\n      var settings = lodash.templateSettings;\n\n      if (otherOptions && isIterateeCall(string, options, otherOptions)) {\n        options = otherOptions = undefined;\n      }\n      string = baseToString(string);\n      options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);\n\n      var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),\n          importsKeys = keys(imports),\n          importsValues = baseValues(imports, importsKeys);\n\n      var isEscaping,\n          isEvaluating,\n          index = 0,\n          interpolate = options.interpolate || reNoMatch,\n          source = \"__p += '\";\n\n      // Compile the regexp to match each delimiter.\n      var reDelimiters = RegExp(\n        (options.escape || reNoMatch).source + '|' +\n        interpolate.source + '|' +\n        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +\n        (options.evaluate || reNoMatch).source + '|$'\n      , 'g');\n\n      // Use a sourceURL for easier debugging.\n      var sourceURL = '//# sourceURL=' +\n        ('sourceURL' in options\n          ? options.sourceURL\n          : ('lodash.templateSources[' + (++templateCounter) + ']')\n        ) + '\\n';\n\n      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {\n        interpolateValue || (interpolateValue = esTemplateValue);\n\n        // Escape characters that can't be included in string literals.\n        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);\n\n        // Replace delimiters with snippets.\n        if (escapeValue) {\n          isEscaping = true;\n          source += \"' +\\n__e(\" + escapeValue + \") +\\n'\";\n        }\n        if (evaluateValue) {\n          isEvaluating = true;\n          source += \"';\\n\" + evaluateValue + \";\\n__p += '\";\n        }\n        if (interpolateValue) {\n          source += \"' +\\n((__t = (\" + interpolateValue + \")) == null ? '' : __t) +\\n'\";\n        }\n        index = offset + match.length;\n\n        // The JS engine embedded in Adobe products requires returning the `match`\n        // string in order to produce the correct `offset` value.\n        return match;\n      });\n\n      source += \"';\\n\";\n\n      // If `variable` is not specified wrap a with-statement around the generated\n      // code to add the data object to the top of the scope chain.\n      var variable = options.variable;\n      if (!variable) {\n        source = 'with (obj) {\\n' + source + '\\n}\\n';\n      }\n      // Cleanup code by stripping empty strings.\n      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)\n        .replace(reEmptyStringMiddle, '$1')\n        .replace(reEmptyStringTrailing, '$1;');\n\n      // Frame code as the function body.\n      source = 'function(' + (variable || 'obj') + ') {\\n' +\n        (variable\n          ? ''\n          : 'obj || (obj = {});\\n'\n        ) +\n        \"var __t, __p = ''\" +\n        (isEscaping\n           ? ', __e = _.escape'\n           : ''\n        ) +\n        (isEvaluating\n          ? ', __j = Array.prototype.join;\\n' +\n            \"function print() { __p += __j.call(arguments, '') }\\n\"\n          : ';\\n'\n        ) +\n        source +\n        'return __p\\n}';\n\n      var result = attempt(function() {\n        return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);\n      });\n\n      // Provide the compiled function's source by its `toString` method or\n      // the `source` property as a convenience for inlining compiled templates.\n      result.source = source;\n      if (isError(result)) {\n        throw result;\n      }\n      return result;\n    }\n\n    /**\n     * Removes leading and trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trim('  abc  ');\n     * // => 'abc'\n     *\n     * _.trim('-_-abc-_-', '_-');\n     * // => 'abc'\n     *\n     * _.map(['  foo  ', '  bar  '], _.trim);\n     * // => ['foo', 'bar']\n     */\n    function trim(string, chars, guard) {\n      var value = string;\n      string = baseToString(string);\n      if (!string) {\n        return string;\n      }\n      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {\n        return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);\n      }\n      chars = (chars + '');\n      return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);\n    }\n\n    /**\n     * Removes leading whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimLeft('  abc  ');\n     * // => 'abc  '\n     *\n     * _.trimLeft('-_-abc-_-', '_-');\n     * // => 'abc-_-'\n     */\n    function trimLeft(string, chars, guard) {\n      var value = string;\n      string = baseToString(string);\n      if (!string) {\n        return string;\n      }\n      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {\n        return string.slice(trimmedLeftIndex(string));\n      }\n      return string.slice(charsLeftIndex(string, (chars + '')));\n    }\n\n    /**\n     * Removes trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimRight('  abc  ');\n     * // => '  abc'\n     *\n     * _.trimRight('-_-abc-_-', '_-');\n     * // => '-_-abc'\n     */\n    function trimRight(string, chars, guard) {\n      var value = string;\n      string = baseToString(string);\n      if (!string) {\n        return string;\n      }\n      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {\n        return string.slice(0, trimmedRightIndex(string) + 1);\n      }\n      return string.slice(0, charsRightIndex(string, (chars + '')) + 1);\n    }\n\n    /**\n     * Truncates `string` if it's longer than the given maximum string length.\n     * The last characters of the truncated string are replaced with the omission\n     * string which defaults to \"...\".\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to truncate.\n     * @param {Object|number} [options] The options object or maximum string length.\n     * @param {number} [options.length=30] The maximum string length.\n     * @param {string} [options.omission='...'] The string to indicate text is omitted.\n     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {string} Returns the truncated string.\n     * @example\n     *\n     * _.trunc('hi-diddly-ho there, neighborino');\n     * // => 'hi-diddly-ho there, neighbo...'\n     *\n     * _.trunc('hi-diddly-ho there, neighborino', 24);\n     * // => 'hi-diddly-ho there, n...'\n     *\n     * _.trunc('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': ' '\n     * });\n     * // => 'hi-diddly-ho there,...'\n     *\n     * _.trunc('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': /,? +/\n     * });\n     * // => 'hi-diddly-ho there...'\n     *\n     * _.trunc('hi-diddly-ho there, neighborino', {\n     *   'omission': ' [...]'\n     * });\n     * // => 'hi-diddly-ho there, neig [...]'\n     */\n    function trunc(string, options, guard) {\n      if (guard && isIterateeCall(string, options, guard)) {\n        options = undefined;\n      }\n      var length = DEFAULT_TRUNC_LENGTH,\n          omission = DEFAULT_TRUNC_OMISSION;\n\n      if (options != null) {\n        if (isObject(options)) {\n          var separator = 'separator' in options ? options.separator : separator;\n          length = 'length' in options ? (+options.length || 0) : length;\n          omission = 'omission' in options ? baseToString(options.omission) : omission;\n        } else {\n          length = +options || 0;\n        }\n      }\n      string = baseToString(string);\n      if (length >= string.length) {\n        return string;\n      }\n      var end = length - omission.length;\n      if (end < 1) {\n        return omission;\n      }\n      var result = string.slice(0, end);\n      if (separator == null) {\n        return result + omission;\n      }\n      if (isRegExp(separator)) {\n        if (string.slice(end).search(separator)) {\n          var match,\n              newEnd,\n              substring = string.slice(0, end);\n\n          if (!separator.global) {\n            separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');\n          }\n          separator.lastIndex = 0;\n          while ((match = separator.exec(substring))) {\n            newEnd = match.index;\n          }\n          result = result.slice(0, newEnd == null ? end : newEnd);\n        }\n      } else if (string.indexOf(separator, end) != end) {\n        var index = result.lastIndexOf(separator);\n        if (index > -1) {\n          result = result.slice(0, index);\n        }\n      }\n      return result + omission;\n    }\n\n    /**\n     * The inverse of `_.escape`; this method converts the HTML entities\n     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their\n     * corresponding characters.\n     *\n     * **Note:** No other HTML entities are unescaped. To unescape additional HTML\n     * entities use a third-party library like [_he_](https://mths.be/he).\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to unescape.\n     * @returns {string} Returns the unescaped string.\n     * @example\n     *\n     * _.unescape('fred, barney, &amp; pebbles');\n     * // => 'fred, barney, & pebbles'\n     */\n    function unescape(string) {\n      string = baseToString(string);\n      return (string && reHasEscapedHtml.test(string))\n        ? string.replace(reEscapedHtml, unescapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Splits `string` into an array of its words.\n     *\n     * @static\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {RegExp|string} [pattern] The pattern to match words.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Array} Returns the words of `string`.\n     * @example\n     *\n     * _.words('fred, barney, & pebbles');\n     * // => ['fred', 'barney', 'pebbles']\n     *\n     * _.words('fred, barney, & pebbles', /[^, ]+/g);\n     * // => ['fred', 'barney', '&', 'pebbles']\n     */\n    function words(string, pattern, guard) {\n      if (guard && isIterateeCall(string, pattern, guard)) {\n        pattern = undefined;\n      }\n      string = baseToString(string);\n      return string.match(pattern || reWords) || [];\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Attempts to invoke `func`, returning either the result or the caught error\n     * object. Any additional arguments are provided to `func` when it is invoked.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Function} func The function to attempt.\n     * @returns {*} Returns the `func` result or error object.\n     * @example\n     *\n     * // avoid throwing errors for invalid selectors\n     * var elements = _.attempt(function(selector) {\n     *   return document.querySelectorAll(selector);\n     * }, '>_>');\n     *\n     * if (_.isError(elements)) {\n     *   elements = [];\n     * }\n     */\n    var attempt = restParam(function(func, args) {\n      try {\n        return func.apply(undefined, args);\n      } catch(e) {\n        return isError(e) ? e : new Error(e);\n      }\n    });\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of `thisArg`\n     * and arguments of the created function. If `func` is a property name the\n     * created callback returns the property value for a given element. If `func`\n     * is an object the created callback returns `true` for elements that contain\n     * the equivalent object properties, otherwise it returns `false`.\n     *\n     * @static\n     * @memberOf _\n     * @alias iteratee\n     * @category Utility\n     * @param {*} [func=_.identity] The value to convert to a callback.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n     * @returns {Function} Returns the callback.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * // wrap to create custom callback shorthands\n     * _.callback = _.wrap(_.callback, function(callback, func, thisArg) {\n     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(func);\n     *   if (!match) {\n     *     return callback(func, thisArg);\n     *   }\n     *   return function(object) {\n     *     return match[2] == 'gt'\n     *       ? object[match[1]] > match[3]\n     *       : object[match[1]] < match[3];\n     *   };\n     * });\n     *\n     * _.filter(users, 'age__gt36');\n     * // => [{ 'user': 'fred', 'age': 40 }]\n     */\n    function callback(func, thisArg, guard) {\n      if (guard && isIterateeCall(func, thisArg, guard)) {\n        thisArg = undefined;\n      }\n      return isObjectLike(func)\n        ? matches(func)\n        : baseCallback(func, thisArg);\n    }\n\n    /**\n     * Creates a function that returns `value`.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {*} value The value to return from the new function.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var object = { 'user': 'fred' };\n     * var getter = _.constant(object);\n     *\n     * getter() === object;\n     * // => true\n     */\n    function constant(value) {\n      return function() {\n        return value;\n      };\n    }\n\n    /**\n     * This method returns the first argument provided to it.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {*} value Any value.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * var object = { 'user': 'fred' };\n     *\n     * _.identity(object) === object;\n     * // => true\n     */\n    function identity(value) {\n      return value;\n    }\n\n    /**\n     * Creates a function that performs a deep comparison between a given object\n     * and `source`, returning `true` if the given object has equivalent property\n     * values, else `false`.\n     *\n     * **Note:** This method supports comparing arrays, booleans, `Date` objects,\n     * numbers, `Object` objects, regexes, and strings. Objects are compared by\n     * their own, not inherited, enumerable properties. For comparing a single\n     * own or inherited property value see `_.matchesProperty`.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * _.filter(users, _.matches({ 'age': 40, 'active': false }));\n     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]\n     */\n    function matches(source) {\n      return baseMatches(baseClone(source, true));\n    }\n\n    /**\n     * Creates a function that compares the property value of `path` on a given\n     * object to `value`.\n     *\n     * **Note:** This method supports comparing arrays, booleans, `Date` objects,\n     * numbers, `Object` objects, regexes, and strings. Objects are compared by\n     * their own, not inherited, enumerable properties.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * _.find(users, _.matchesProperty('user', 'fred'));\n     * // => { 'user': 'fred' }\n     */\n    function matchesProperty(path, srcValue) {\n      return baseMatchesProperty(path, baseClone(srcValue, true));\n    }\n\n    /**\n     * Creates a function that invokes the method at `path` on a given object.\n     * Any additional arguments are provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': { 'c': _.constant(2) } } },\n     *   { 'a': { 'b': { 'c': _.constant(1) } } }\n     * ];\n     *\n     * _.map(objects, _.method('a.b.c'));\n     * // => [2, 1]\n     *\n     * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');\n     * // => [1, 2]\n     */\n    var method = restParam(function(path, args) {\n      return function(object) {\n        return invokePath(object, path, args);\n      };\n    });\n\n    /**\n     * The opposite of `_.method`; this method creates a function that invokes\n     * the method at a given path on `object`. Any additional arguments are\n     * provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Object} object The object to query.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var array = _.times(3, _.constant),\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.methodOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));\n     * // => [2, 0]\n     */\n    var methodOf = restParam(function(object, args) {\n      return function(path) {\n        return invokePath(object, path, args);\n      };\n    });\n\n    /**\n     * Adds all own enumerable function properties of a source object to the\n     * destination object. If `object` is a function then methods are added to\n     * its prototype as well.\n     *\n     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to\n     * avoid conflicts caused by modifying the original.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Function|Object} [object=lodash] The destination object.\n     * @param {Object} source The object of functions to add.\n     * @param {Object} [options] The options object.\n     * @param {boolean} [options.chain=true] Specify whether the functions added\n     *  are chainable.\n     * @returns {Function|Object} Returns `object`.\n     * @example\n     *\n     * function vowels(string) {\n     *   return _.filter(string, function(v) {\n     *     return /[aeiou]/i.test(v);\n     *   });\n     * }\n     *\n     * _.mixin({ 'vowels': vowels });\n     * _.vowels('fred');\n     * // => ['e']\n     *\n     * _('fred').vowels().value();\n     * // => ['e']\n     *\n     * _.mixin({ 'vowels': vowels }, { 'chain': false });\n     * _('fred').vowels();\n     * // => ['e']\n     */\n    function mixin(object, source, options) {\n      if (options == null) {\n        var isObj = isObject(source),\n            props = isObj ? keys(source) : undefined,\n            methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;\n\n        if (!(methodNames ? methodNames.length : isObj)) {\n          methodNames = false;\n          options = source;\n          source = object;\n          object = this;\n        }\n      }\n      if (!methodNames) {\n        methodNames = baseFunctions(source, keys(source));\n      }\n      var chain = true,\n          index = -1,\n          isFunc = isFunction(object),\n          length = methodNames.length;\n\n      if (options === false) {\n        chain = false;\n      } else if (isObject(options) && 'chain' in options) {\n        chain = options.chain;\n      }\n      while (++index < length) {\n        var methodName = methodNames[index],\n            func = source[methodName];\n\n        object[methodName] = func;\n        if (isFunc) {\n          object.prototype[methodName] = (function(func) {\n            return function() {\n              var chainAll = this.__chain__;\n              if (chain || chainAll) {\n                var result = object(this.__wrapped__),\n                    actions = result.__actions__ = arrayCopy(this.__actions__);\n\n                actions.push({ 'func': func, 'args': arguments, 'thisArg': object });\n                result.__chain__ = chainAll;\n                return result;\n              }\n              return func.apply(object, arrayPush([this.value()], arguments));\n            };\n          }(func));\n        }\n      }\n      return object;\n    }\n\n    /**\n     * Reverts the `_` variable to its previous value and returns a reference to\n     * the `lodash` function.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @returns {Function} Returns the `lodash` function.\n     * @example\n     *\n     * var lodash = _.noConflict();\n     */\n    function noConflict() {\n      root._ = oldDash;\n      return this;\n    }\n\n    /**\n     * A no-operation function that returns `undefined` regardless of the\n     * arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @example\n     *\n     * var object = { 'user': 'fred' };\n     *\n     * _.noop(object) === undefined;\n     * // => true\n     */\n    function noop() {\n      // No operation performed.\n    }\n\n    /**\n     * Creates a function that returns the property value at `path` on a\n     * given object.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': { 'c': 2 } } },\n     *   { 'a': { 'b': { 'c': 1 } } }\n     * ];\n     *\n     * _.map(objects, _.property('a.b.c'));\n     * // => [2, 1]\n     *\n     * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');\n     * // => [1, 2]\n     */\n    function property(path) {\n      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);\n    }\n\n    /**\n     * The opposite of `_.property`; this method creates a function that returns\n     * the property value at a given path on `object`.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {Object} object The object to query.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var array = [0, 1, 2],\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));\n     * // => [2, 0]\n     */\n    function propertyOf(object) {\n      return function(path) {\n        return baseGet(object, toPath(path), path + '');\n      };\n    }\n\n    /**\n     * Creates an array of numbers (positive and/or negative) progressing from\n     * `start` up to, but not including, `end`. If `end` is not specified it is\n     * set to `start` with `start` then set to `0`. If `end` is less than `start`\n     * a zero-length range is created unless a negative `step` is specified.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the new array of numbers.\n     * @example\n     *\n     * _.range(4);\n     * // => [0, 1, 2, 3]\n     *\n     * _.range(1, 5);\n     * // => [1, 2, 3, 4]\n     *\n     * _.range(0, 20, 5);\n     * // => [0, 5, 10, 15]\n     *\n     * _.range(0, -4, -1);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.range(0);\n     * // => []\n     */\n    function range(start, end, step) {\n      if (step && isIterateeCall(start, end, step)) {\n        end = step = undefined;\n      }\n      start = +start || 0;\n      step = step == null ? 1 : (+step || 0);\n\n      if (end == null) {\n        end = start;\n        start = 0;\n      } else {\n        end = +end || 0;\n      }\n      // Use `Array(length)` so engines like Chakra and V8 avoid slower modes.\n      // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.\n      var index = -1,\n          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n          result = Array(length);\n\n      while (++index < length) {\n        result[index] = start;\n        start += step;\n      }\n      return result;\n    }\n\n    /**\n     * Invokes the iteratee function `n` times, returning an array of the results\n     * of each invocation. The `iteratee` is bound to `thisArg` and invoked with\n     * one argument; (index).\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {number} n The number of times to invoke `iteratee`.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false));\n     * // => [3, 6, 4]\n     *\n     * _.times(3, function(n) {\n     *   mage.castSpell(n);\n     * });\n     * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`\n     *\n     * _.times(3, function(n) {\n     *   this.cast(n);\n     * }, mage);\n     * // => also invokes `mage.castSpell(n)` three times\n     */\n    function times(n, iteratee, thisArg) {\n      n = nativeFloor(n);\n\n      // Exit early to avoid a JSC JIT bug in Safari 8\n      // where `Array(0)` is treated as `Array(1)`.\n      if (n < 1 || !nativeIsFinite(n)) {\n        return [];\n      }\n      var index = -1,\n          result = Array(nativeMin(n, MAX_ARRAY_LENGTH));\n\n      iteratee = bindCallback(iteratee, thisArg, 1);\n      while (++index < n) {\n        if (index < MAX_ARRAY_LENGTH) {\n          result[index] = iteratee(index);\n        } else {\n          iteratee(index);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Generates a unique ID. If `prefix` is provided the ID is appended to it.\n     *\n     * @static\n     * @memberOf _\n     * @category Utility\n     * @param {string} [prefix] The value to prefix the ID with.\n     * @returns {string} Returns the unique ID.\n     * @example\n     *\n     * _.uniqueId('contact_');\n     * // => 'contact_104'\n     *\n     * _.uniqueId();\n     * // => '105'\n     */\n    function uniqueId(prefix) {\n      var id = ++idCounter;\n      return baseToString(prefix) + id;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Adds two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {number} augend The first number to add.\n     * @param {number} addend The second number to add.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * _.add(6, 4);\n     * // => 10\n     */\n    function add(augend, addend) {\n      return (+augend || 0) + (+addend || 0);\n    }\n\n    /**\n     * Calculates `n` rounded up to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {number} n The number to round up.\n     * @param {number} [precision=0] The precision to round up to.\n     * @returns {number} Returns the rounded up number.\n     * @example\n     *\n     * _.ceil(4.006);\n     * // => 5\n     *\n     * _.ceil(6.004, 2);\n     * // => 6.01\n     *\n     * _.ceil(6040, -2);\n     * // => 6100\n     */\n    var ceil = createRound('ceil');\n\n    /**\n     * Calculates `n` rounded down to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {number} n The number to round down.\n     * @param {number} [precision=0] The precision to round down to.\n     * @returns {number} Returns the rounded down number.\n     * @example\n     *\n     * _.floor(4.006);\n     * // => 4\n     *\n     * _.floor(0.046, 2);\n     * // => 0.04\n     *\n     * _.floor(4060, -2);\n     * // => 4000\n     */\n    var floor = createRound('floor');\n\n    /**\n     * Gets the maximum value of `collection`. If `collection` is empty or falsey\n     * `-Infinity` is returned. If an iteratee function is provided it is invoked\n     * for each value in `collection` to generate the criterion by which the value\n     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three\n     * arguments: (value, index, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * _.max([4, 2, 8, 6]);\n     * // => 8\n     *\n     * _.max([]);\n     * // => -Infinity\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * _.max(users, function(chr) {\n     *   return chr.age;\n     * });\n     * // => { 'user': 'fred', 'age': 40 }\n     *\n     * // using the `_.property` callback shorthand\n     * _.max(users, 'age');\n     * // => { 'user': 'fred', 'age': 40 }\n     */\n    var max = createExtremum(gt, NEGATIVE_INFINITY);\n\n    /**\n     * Gets the minimum value of `collection`. If `collection` is empty or falsey\n     * `Infinity` is returned. If an iteratee function is provided it is invoked\n     * for each value in `collection` to generate the criterion by which the value\n     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three\n     * arguments: (value, index, collection).\n     *\n     * If a property name is provided for `iteratee` the created `_.property`\n     * style callback returns the property value of the given element.\n     *\n     * If a value is also provided for `thisArg` the created `_.matchesProperty`\n     * style callback returns `true` for elements that have a matching property\n     * value, else `false`.\n     *\n     * If an object is provided for `iteratee` the created `_.matches` style\n     * callback returns `true` for elements that have the properties of the given\n     * object, else `false`.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * _.min([4, 2, 8, 6]);\n     * // => 2\n     *\n     * _.min([]);\n     * // => Infinity\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * _.min(users, function(chr) {\n     *   return chr.age;\n     * });\n     * // => { 'user': 'barney', 'age': 36 }\n     *\n     * // using the `_.property` callback shorthand\n     * _.min(users, 'age');\n     * // => { 'user': 'barney', 'age': 36 }\n     */\n    var min = createExtremum(lt, POSITIVE_INFINITY);\n\n    /**\n     * Calculates `n` rounded to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {number} n The number to round.\n     * @param {number} [precision=0] The precision to round to.\n     * @returns {number} Returns the rounded number.\n     * @example\n     *\n     * _.round(4.006);\n     * // => 4\n     *\n     * _.round(4.006, 2);\n     * // => 4.01\n     *\n     * _.round(4060, -2);\n     * // => 4100\n     */\n    var round = createRound('round');\n\n    /**\n     * Gets the sum of the values in `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @category Math\n     * @param {Array|Object|string} collection The collection to iterate over.\n     * @param {Function|Object|string} [iteratee] The function invoked per iteration.\n     * @param {*} [thisArg] The `this` binding of `iteratee`.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * _.sum([4, 6]);\n     * // => 10\n     *\n     * _.sum({ 'a': 4, 'b': 6 });\n     * // => 10\n     *\n     * var objects = [\n     *   { 'n': 4 },\n     *   { 'n': 6 }\n     * ];\n     *\n     * _.sum(objects, function(object) {\n     *   return object.n;\n     * });\n     * // => 10\n     *\n     * // using the `_.property` callback shorthand\n     * _.sum(objects, 'n');\n     * // => 10\n     */\n    function sum(collection, iteratee, thisArg) {\n      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {\n        iteratee = undefined;\n      }\n      iteratee = getCallback(iteratee, thisArg, 3);\n      return iteratee.length == 1\n        ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)\n        : baseSum(collection, iteratee);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    // Ensure wrappers are instances of `baseLodash`.\n    lodash.prototype = baseLodash.prototype;\n\n    LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n    LodashWrapper.prototype.constructor = LodashWrapper;\n\n    LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n    LazyWrapper.prototype.constructor = LazyWrapper;\n\n    // Add functions to the `Map` cache.\n    MapCache.prototype['delete'] = mapDelete;\n    MapCache.prototype.get = mapGet;\n    MapCache.prototype.has = mapHas;\n    MapCache.prototype.set = mapSet;\n\n    // Add functions to the `Set` cache.\n    SetCache.prototype.push = cachePush;\n\n    // Assign cache to `_.memoize`.\n    memoize.Cache = MapCache;\n\n    // Add functions that return wrapped values when chaining.\n    lodash.after = after;\n    lodash.ary = ary;\n    lodash.assign = assign;\n    lodash.at = at;\n    lodash.before = before;\n    lodash.bind = bind;\n    lodash.bindAll = bindAll;\n    lodash.bindKey = bindKey;\n    lodash.callback = callback;\n    lodash.chain = chain;\n    lodash.chunk = chunk;\n    lodash.compact = compact;\n    lodash.constant = constant;\n    lodash.countBy = countBy;\n    lodash.create = create;\n    lodash.curry = curry;\n    lodash.curryRight = curryRight;\n    lodash.debounce = debounce;\n    lodash.defaults = defaults;\n    lodash.defaultsDeep = defaultsDeep;\n    lodash.defer = defer;\n    lodash.delay = delay;\n    lodash.difference = difference;\n    lodash.drop = drop;\n    lodash.dropRight = dropRight;\n    lodash.dropRightWhile = dropRightWhile;\n    lodash.dropWhile = dropWhile;\n    lodash.fill = fill;\n    lodash.filter = filter;\n    lodash.flatten = flatten;\n    lodash.flattenDeep = flattenDeep;\n    lodash.flow = flow;\n    lodash.flowRight = flowRight;\n    lodash.forEach = forEach;\n    lodash.forEachRight = forEachRight;\n    lodash.forIn = forIn;\n    lodash.forInRight = forInRight;\n    lodash.forOwn = forOwn;\n    lodash.forOwnRight = forOwnRight;\n    lodash.functions = functions;\n    lodash.groupBy = groupBy;\n    lodash.indexBy = indexBy;\n    lodash.initial = initial;\n    lodash.intersection = intersection;\n    lodash.invert = invert;\n    lodash.invoke = invoke;\n    lodash.keys = keys;\n    lodash.keysIn = keysIn;\n    lodash.map = map;\n    lodash.mapKeys = mapKeys;\n    lodash.mapValues = mapValues;\n    lodash.matches = matches;\n    lodash.matchesProperty = matchesProperty;\n    lodash.memoize = memoize;\n    lodash.merge = merge;\n    lodash.method = method;\n    lodash.methodOf = methodOf;\n    lodash.mixin = mixin;\n    lodash.modArgs = modArgs;\n    lodash.negate = negate;\n    lodash.omit = omit;\n    lodash.once = once;\n    lodash.pairs = pairs;\n    lodash.partial = partial;\n    lodash.partialRight = partialRight;\n    lodash.partition = partition;\n    lodash.pick = pick;\n    lodash.pluck = pluck;\n    lodash.property = property;\n    lodash.propertyOf = propertyOf;\n    lodash.pull = pull;\n    lodash.pullAt = pullAt;\n    lodash.range = range;\n    lodash.rearg = rearg;\n    lodash.reject = reject;\n    lodash.remove = remove;\n    lodash.rest = rest;\n    lodash.restParam = restParam;\n    lodash.set = set;\n    lodash.shuffle = shuffle;\n    lodash.slice = slice;\n    lodash.sortBy = sortBy;\n    lodash.sortByAll = sortByAll;\n    lodash.sortByOrder = sortByOrder;\n    lodash.spread = spread;\n    lodash.take = take;\n    lodash.takeRight = takeRight;\n    lodash.takeRightWhile = takeRightWhile;\n    lodash.takeWhile = takeWhile;\n    lodash.tap = tap;\n    lodash.throttle = throttle;\n    lodash.thru = thru;\n    lodash.times = times;\n    lodash.toArray = toArray;\n    lodash.toPlainObject = toPlainObject;\n    lodash.transform = transform;\n    lodash.union = union;\n    lodash.uniq = uniq;\n    lodash.unzip = unzip;\n    lodash.unzipWith = unzipWith;\n    lodash.values = values;\n    lodash.valuesIn = valuesIn;\n    lodash.where = where;\n    lodash.without = without;\n    lodash.wrap = wrap;\n    lodash.xor = xor;\n    lodash.zip = zip;\n    lodash.zipObject = zipObject;\n    lodash.zipWith = zipWith;\n\n    // Add aliases.\n    lodash.backflow = flowRight;\n    lodash.collect = map;\n    lodash.compose = flowRight;\n    lodash.each = forEach;\n    lodash.eachRight = forEachRight;\n    lodash.extend = assign;\n    lodash.iteratee = callback;\n    lodash.methods = functions;\n    lodash.object = zipObject;\n    lodash.select = filter;\n    lodash.tail = rest;\n    lodash.unique = uniq;\n\n    // Add functions to `lodash.prototype`.\n    mixin(lodash, lodash);\n\n    /*------------------------------------------------------------------------*/\n\n    // Add functions that return unwrapped values when chaining.\n    lodash.add = add;\n    lodash.attempt = attempt;\n    lodash.camelCase = camelCase;\n    lodash.capitalize = capitalize;\n    lodash.ceil = ceil;\n    lodash.clone = clone;\n    lodash.cloneDeep = cloneDeep;\n    lodash.deburr = deburr;\n    lodash.endsWith = endsWith;\n    lodash.escape = escape;\n    lodash.escapeRegExp = escapeRegExp;\n    lodash.every = every;\n    lodash.find = find;\n    lodash.findIndex = findIndex;\n    lodash.findKey = findKey;\n    lodash.findLast = findLast;\n    lodash.findLastIndex = findLastIndex;\n    lodash.findLastKey = findLastKey;\n    lodash.findWhere = findWhere;\n    lodash.first = first;\n    lodash.floor = floor;\n    lodash.get = get;\n    lodash.gt = gt;\n    lodash.gte = gte;\n    lodash.has = has;\n    lodash.identity = identity;\n    lodash.includes = includes;\n    lodash.indexOf = indexOf;\n    lodash.inRange = inRange;\n    lodash.isArguments = isArguments;\n    lodash.isArray = isArray;\n    lodash.isBoolean = isBoolean;\n    lodash.isDate = isDate;\n    lodash.isElement = isElement;\n    lodash.isEmpty = isEmpty;\n    lodash.isEqual = isEqual;\n    lodash.isError = isError;\n    lodash.isFinite = isFinite;\n    lodash.isFunction = isFunction;\n    lodash.isMatch = isMatch;\n    lodash.isNaN = isNaN;\n    lodash.isNative = isNative;\n    lodash.isNull = isNull;\n    lodash.isNumber = isNumber;\n    lodash.isObject = isObject;\n    lodash.isPlainObject = isPlainObject;\n    lodash.isRegExp = isRegExp;\n    lodash.isString = isString;\n    lodash.isTypedArray = isTypedArray;\n    lodash.isUndefined = isUndefined;\n    lodash.kebabCase = kebabCase;\n    lodash.last = last;\n    lodash.lastIndexOf = lastIndexOf;\n    lodash.lt = lt;\n    lodash.lte = lte;\n    lodash.max = max;\n    lodash.min = min;\n    lodash.noConflict = noConflict;\n    lodash.noop = noop;\n    lodash.now = now;\n    lodash.pad = pad;\n    lodash.padLeft = padLeft;\n    lodash.padRight = padRight;\n    lodash.parseInt = parseInt;\n    lodash.random = random;\n    lodash.reduce = reduce;\n    lodash.reduceRight = reduceRight;\n    lodash.repeat = repeat;\n    lodash.result = result;\n    lodash.round = round;\n    lodash.runInContext = runInContext;\n    lodash.size = size;\n    lodash.snakeCase = snakeCase;\n    lodash.some = some;\n    lodash.sortedIndex = sortedIndex;\n    lodash.sortedLastIndex = sortedLastIndex;\n    lodash.startCase = startCase;\n    lodash.startsWith = startsWith;\n    lodash.sum = sum;\n    lodash.template = template;\n    lodash.trim = trim;\n    lodash.trimLeft = trimLeft;\n    lodash.trimRight = trimRight;\n    lodash.trunc = trunc;\n    lodash.unescape = unescape;\n    lodash.uniqueId = uniqueId;\n    lodash.words = words;\n\n    // Add aliases.\n    lodash.all = every;\n    lodash.any = some;\n    lodash.contains = includes;\n    lodash.eq = isEqual;\n    lodash.detect = find;\n    lodash.foldl = reduce;\n    lodash.foldr = reduceRight;\n    lodash.head = first;\n    lodash.include = includes;\n    lodash.inject = reduce;\n\n    mixin(lodash, (function() {\n      var source = {};\n      baseForOwn(lodash, function(func, methodName) {\n        if (!lodash.prototype[methodName]) {\n          source[methodName] = func;\n        }\n      });\n      return source;\n    }()), false);\n\n    /*------------------------------------------------------------------------*/\n\n    // Add functions capable of returning wrapped and unwrapped values when chaining.\n    lodash.sample = sample;\n\n    lodash.prototype.sample = function(n) {\n      if (!this.__chain__ && n == null) {\n        return sample(this.value());\n      }\n      return this.thru(function(value) {\n        return sample(value, n);\n      });\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The semantic version number.\n     *\n     * @static\n     * @memberOf _\n     * @type string\n     */\n    lodash.VERSION = VERSION;\n\n    // Assign default placeholders.\n    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {\n      lodash[methodName].placeholder = lodash;\n    });\n\n    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.\n    arrayEach(['drop', 'take'], function(methodName, index) {\n      LazyWrapper.prototype[methodName] = function(n) {\n        var filtered = this.__filtered__;\n        if (filtered && !index) {\n          return new LazyWrapper(this);\n        }\n        n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);\n\n        var result = this.clone();\n        if (filtered) {\n          result.__takeCount__ = nativeMin(result.__takeCount__, n);\n        } else {\n          result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });\n        }\n        return result;\n      };\n\n      LazyWrapper.prototype[methodName + 'Right'] = function(n) {\n        return this.reverse()[methodName](n).reverse();\n      };\n    });\n\n    // Add `LazyWrapper` methods that accept an `iteratee` value.\n    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {\n      var type = index + 1,\n          isFilter = type != LAZY_MAP_FLAG;\n\n      LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {\n        var result = this.clone();\n        result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type });\n        result.__filtered__ = result.__filtered__ || isFilter;\n        return result;\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.first` and `_.last`.\n    arrayEach(['first', 'last'], function(methodName, index) {\n      var takeName = 'take' + (index ? 'Right' : '');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this[takeName](1).value()[0];\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.initial` and `_.rest`.\n    arrayEach(['initial', 'rest'], function(methodName, index) {\n      var dropName = 'drop' + (index ? '' : 'Right');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.pluck` and `_.where`.\n    arrayEach(['pluck', 'where'], function(methodName, index) {\n      var operationName = index ? 'filter' : 'map',\n          createCallback = index ? baseMatches : property;\n\n      LazyWrapper.prototype[methodName] = function(value) {\n        return this[operationName](createCallback(value));\n      };\n    });\n\n    LazyWrapper.prototype.compact = function() {\n      return this.filter(identity);\n    };\n\n    LazyWrapper.prototype.reject = function(predicate, thisArg) {\n      predicate = getCallback(predicate, thisArg, 1);\n      return this.filter(function(value) {\n        return !predicate(value);\n      });\n    };\n\n    LazyWrapper.prototype.slice = function(start, end) {\n      start = start == null ? 0 : (+start || 0);\n\n      var result = this;\n      if (result.__filtered__ && (start > 0 || end < 0)) {\n        return new LazyWrapper(result);\n      }\n      if (start < 0) {\n        result = result.takeRight(-start);\n      } else if (start) {\n        result = result.drop(start);\n      }\n      if (end !== undefined) {\n        end = (+end || 0);\n        result = end < 0 ? result.dropRight(-end) : result.take(end - start);\n      }\n      return result;\n    };\n\n    LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {\n      return this.reverse().takeWhile(predicate, thisArg).reverse();\n    };\n\n    LazyWrapper.prototype.toArray = function() {\n      return this.take(POSITIVE_INFINITY);\n    };\n\n    // Add `LazyWrapper` methods to `lodash.prototype`.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),\n          retUnwrapped = /^(?:first|last)$/.test(methodName),\n          lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];\n\n      if (!lodashFunc) {\n        return;\n      }\n      lodash.prototype[methodName] = function() {\n        var args = retUnwrapped ? [1] : arguments,\n            chainAll = this.__chain__,\n            value = this.__wrapped__,\n            isHybrid = !!this.__actions__.length,\n            isLazy = value instanceof LazyWrapper,\n            iteratee = args[0],\n            useLazy = isLazy || isArray(value);\n\n        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {\n          // Avoid lazy use if the iteratee has a \"length\" value other than `1`.\n          isLazy = useLazy = false;\n        }\n        var interceptor = function(value) {\n          return (retUnwrapped && chainAll)\n            ? lodashFunc(value, 1)[0]\n            : lodashFunc.apply(undefined, arrayPush([value], args));\n        };\n\n        var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined },\n            onlyLazy = isLazy && !isHybrid;\n\n        if (retUnwrapped && !chainAll) {\n          if (onlyLazy) {\n            value = value.clone();\n            value.__actions__.push(action);\n            return func.call(value);\n          }\n          return lodashFunc.call(undefined, this.value())[0];\n        }\n        if (!retUnwrapped && useLazy) {\n          value = onlyLazy ? value : new LazyWrapper(this);\n          var result = func.apply(value, args);\n          result.__actions__.push(action);\n          return new LodashWrapper(result, chainAll);\n        }\n        return this.thru(interceptor);\n      };\n    });\n\n    // Add `Array` and `String` methods to `lodash.prototype`.\n    arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {\n      var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],\n          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',\n          retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);\n\n      lodash.prototype[methodName] = function() {\n        var args = arguments;\n        if (retUnwrapped && !this.__chain__) {\n          return func.apply(this.value(), args);\n        }\n        return this[chainName](function(value) {\n          return func.apply(value, args);\n        });\n      };\n    });\n\n    // Map minified function names to their real names.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var lodashFunc = lodash[methodName];\n      if (lodashFunc) {\n        var key = lodashFunc.name,\n            names = realNames[key] || (realNames[key] = []);\n\n        names.push({ 'name': methodName, 'func': lodashFunc });\n      }\n    });\n\n    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];\n\n    // Add functions to the lazy wrapper.\n    LazyWrapper.prototype.clone = lazyClone;\n    LazyWrapper.prototype.reverse = lazyReverse;\n    LazyWrapper.prototype.value = lazyValue;\n\n    // Add chaining functions to the `lodash` wrapper.\n    lodash.prototype.chain = wrapperChain;\n    lodash.prototype.commit = wrapperCommit;\n    lodash.prototype.concat = wrapperConcat;\n    lodash.prototype.plant = wrapperPlant;\n    lodash.prototype.reverse = wrapperReverse;\n    lodash.prototype.toString = wrapperToString;\n    lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;\n\n    // Add function aliases to the `lodash` wrapper.\n    lodash.prototype.collect = lodash.prototype.map;\n    lodash.prototype.head = lodash.prototype.first;\n    lodash.prototype.select = lodash.prototype.filter;\n    lodash.prototype.tail = lodash.prototype.rest;\n\n    return lodash;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  // Export lodash.\n  var _ = runInContext();\n\n  // Some AMD build optimizers like r.js check for condition patterns like the following:\n  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {\n    // Expose lodash to the global object when an AMD loader is present to avoid\n    // errors in cases where lodash is loaded by a script tag and not intended\n    // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for\n    // more details.\n    root._ = _;\n\n    // Define as an anonymous module so, through path mapping, it can be\n    // referenced as the \"underscore\" module.\n    define(function() {\n      return _;\n    });\n  }\n  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.\n  else if (freeExports && freeModule) {\n    // Export for Node.js or RingoJS.\n    if (moduleExports) {\n      (freeModule.exports = _)._ = _;\n    }\n    // Export for Rhino with CommonJS support.\n    else {\n      freeExports._ = _;\n    }\n  }\n  else {\n    // Export for a browser or Rhino.\n    root._ = _;\n  }\n}.call(this));\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash/index.js\n ** module id = 382\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/25/15.\n */\n\nexport default class Position {\n\n\tconstructor(pos = {}) {\n\t\tthis._position = Object.assign({}, Position.defaults(), pos);\n\t\t// if consumer specified width or height in the\n\t\t// constructor then set right and bottom....\n\t\tif (!isNaN(parseFloat(pos.width))) {\n\t\t\t// ensure right is set\n\t\t\tthis.width = pos.width;\n\t\t}\n\t\tif (!isNaN(parseFloat(pos.height))) {\n\t\t\t// ensure bottom is set\n\t\t\tthis.height = pos.height;\n\t\t}\n\t}\n\n\tstatic defaults() {\n\t\treturn {\n\t\t\ttop: 0,\n\t\t\tleft: 0,\n\t\t\tbottom: 0,\n\t\t\tright: 0,\n\t\t\twidth: 0,\n\t\t\theight: 0\n\t\t};\n\t}\n\n\tget position() {\n\t\treturn Object.assign({}, this._position);\n\t}\n\n\tget top() {\n\t\treturn this._position.top;\n\t}\n\n\tset top(value) {\n\t\tthis._position.top = parseFloat(value) || 0;\n\t\treturn this;\n\t}\n\n\tget left() {\n\t\treturn this._position.left;\n\t}\n\n\tset left(value) {\n\t\tthis._position.left = parseFloat(value) || 0;\n\t\treturn this;\n\t}\n\n\tget bottom() {\n\t\treturn this._position.bottom;\n\t}\n\n\tset bottom(value) {\n\t\tthis._position.bottom = parseFloat(value) || 0;\n\t\treturn this;\n\t}\n\n\tget right() {\n\t\treturn this._position.right;\n\t}\n\n\tset right(value) {\n\t\tthis._position.right = parseFloat(value) || 0;\n\t\treturn this;\n\t}\n\n\tget width() {\n\t\treturn Math.abs(this.right - this.left);\n\t}\n\n\tset width(width) {\n\t\tconst value = parseFloat(width);\n\t\tif (!isNaN(value)) {\n\t\t\tthis.right = value + this.left;\n\t\t\tthis._position.width = this.width;\n\t\t}\n\t}\n\n\tget height() {\n\t\treturn Math.abs(this.bottom - this.top);\n\t}\n\n\tset height(height) {\n\t\tconst value = parseFloat(height);\n\t\tif (!isNaN(value)) {\n\t\t\tthis.bottom = value + this.top;\n\t\t\tthis._position.height = this.height;\n\t\t}\n\t}\n\n\ttoString() {\n\t\treturn JSON.stringify(this._position);\n\t}\n\n\tvalue() {\n\t\treturn {\n\t\t\ttop: this.top,\n\t\t\tleft: this.left,\n\t\t\tright: this.right,\n\t\t\tbottom: this.bottom,\n\t\t\twidth: this.width,\n\t\t\theight: this.height\n\t\t};\n\t}\n\n\tcenterPoint() {\n\t\treturn {\n\t\t\tx: this.left + (this.width / 2),\n\t\t\ty: this.top + (this.height / 2)\n\t\t};\n\t}\n\n\tmove(left, top) {\n\t\tthis.moveTop(top);\n\t\tthis.moveLeft(left);\n\t}\n\n\tmoveLeft(left) {\n\t\tconst width = this.width;\n\t\tconst value = parseFloat(left);\n\t\tif (!isNaN(value)) {\n\t\t\tthis._position.left = value;\n\t\t\tthis._position.right = value + width;\n\t\t}\n\t}\n\n\tmoveRight(right) {\n\t\tconst width = this.width;\n\t\tconst value = parseFloat(right);\n\t\tif (!isNaN(value)) {\n\t\t\tthis._position.left = value - width;\n\t\t\tthis._position.right = value;\n\t\t}\n\t}\n\n\tmoveTop(top) {\n\t\tconst height = this.height;\n\t\tconst value = parseFloat(top);\n\t\tif (!isNaN(value)) {\n\t\t\tthis._position.top = value;\n\t\t\tthis._position.bottom = value + height;\n\t\t}\n\t}\n\n\tmoveBottom(bottom) {\n\t\tconst height = this.height;\n\t\tconst value = parseFloat(bottom);\n\t\tif (!isNaN(value)) {\n\t\t\tthis._position.top = value - height;\n\t\t\tthis._position.bottom = value;\n\t\t}\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/Position.js\n **/","/**\n * Created by onvelocity on 2/15/16.\n */\nclass IconFactory {\n\n\tstatic getIconForType(type) {\n\t\tconst icon = IconFactory.types[type];\n\t\tif (icon) {\n\t\t\treturn icon;\n\t\t}\n\t\treturn IconFactory.types.common;\n\t}\n\n\tstatic get types() {\n\t\treturn {\n\t\t\t//iconmonstr-3d-view-icon.svg\n\t\t\tvdu: {\n\t\t\t\twidth: 24,\n\t\t\t\ttranslate: '0, 8',\n\t\t\t\td: `M13 19h-2v2h-4v2h10v-2h-4v-2zm9 2h-4v2h4v-2zm-16 0h-4v2h4v-2zm16-10v4h-20v-4h20zm2-2h-24v8h24v-8zm-21\n\t\t\t5l.863-2h1.275l-.863 2h-1.275zm2.066 0l.863-2h1.275l-.863 2h-1.275zm2.067 0l.863-2h1.275l-.864\n\t\t\t2h-1.274zm2.066 0l.863-2h1.274l-.863 2h-1.274zm3.341 0h-1.275l.864-2h1.275l-.864\n\t\t\t2zm7.46 0c-.552 0-1-.448-1-1s.448-1 1-1 1 .448 1 1-.448 1-1 1zm-15.597-6h-2.403l4-7h12l4 7h-2.403l-2.667-5h-9.86l-2.667 5z`\n\t\t\t},\n\t\t\t//iconmonstr-cube-6-icon.svg\n\t\t\tvnfd: {\n\t\t\t\twidth: 350,\n\t\t\t\td: `M256,50L67.166,153v208.246L256,462l188.834-100.754V154.123L256,50z M391.791,164.09l-135.707,72.405\n\tl-135.138-73.712l134.97-73.621L391.791,164.09z M101.5,191.281l137.333,74.902V413.92L101.5,340.66V191.281z M273.166,413.92\n\tV266.302L410.5,193.025V340.66L273.166,413.92z M387.801,322.688c0.117,5.7-4.393,10.394-10.092,10.495\n\tc-5.699,0.133-10.377-4.393-10.494-10.093c-0.102-5.683,4.393-10.394,10.092-10.495\n\tC383.006,312.479,387.701,316.988,387.801,322.688z M341.28,293.904c-5.7,0.117-10.21,4.811-10.093,10.494\n\tc0.102,5.684,4.795,10.209,10.495,10.109c5.7-0.117,10.192-4.828,10.092-10.350C351.657,298.312,346.98,293.787,341.28,293.904z\n\t M304.684,275.111c-5.699,0.117-10.209,4.828-10.092,10.350c0.1,5.683,4.795,10.209,10.494,10.092s10.193-4.812,10.092-10.350\n\tC315.061,279.521,310.383,275.011,304.684,275.111z M134.693,312.596c5.699,0.102,10.192,4.812,10.092,10.495\n\tc-0.117,5.7-4.795,10.226-10.494,10.093c-5.7-0.102-10.21-4.795-10.093-10.495C124.299,316.988,128.993,312.479,134.693,312.596z\n\t M160.226,303.996c-0.101,5.684,4.392,10.395,10.092,10.350c5.7,0.1,10.394-4.426,10.494-10.109\n\tc0.117-5.684-4.392-10.377-10.092-10.494S160.343,298.312,160.226,303.996z M196.821,285.203c-0.101,5.7,4.393,10.395,10.093,10.350\n\tc5.699,0.117,10.394-4.409,10.494-10.092c0.117-5.684-4.393-10.395-10.092-10.350C201.616,275.011,196.939,279.521,196.821,285.203z\n\t M256,186.529c-5.684,0-10.294,4.61-10.294,10.302c0,5.691,4.61,10.301,10.294,10.301s10.293-4.61,10.293-10.301\n\tC266.293,191.139,261.684,186.529,256,186.529z M256,148.331c-5.684,0-10.294,4.61-10.294,10.302s4.61,10.302,10.294,10.302\n\ts10.293-4.61,10.293-10.302S261.684,148.331,256,148.331z M256,113.461c-5.684,0-10.294,4.61-10.294,10.302\n\ts4.61,10.302,10.294,10.302s10.293-4.61,10.293-10.302S261.684,113.461,256,113.461z`},\n\t\t\t//iconmonstr-infinity-4-icon.svg\n\t\t\tvnffgd: {\n\t\t\t\twidth: 350,\n\t\t\t\td: `M462,256c0,54.847-32.119,97.39-80.917,104.472v-43.495c25.012-6.366,39.565-29.506,39.565-60.977\n\tc0-37.181-20.31-62.74-54.185-62.74c-26.559,0-45.165,18.06-64.853,41.478l-26.778-31.987\n\tc25.695-27.415,51.986-52.268,91.631-52.268C423.367,150.482,462,195.846,462,256z M323.75,301.584c0,0-47.416-55.167-74.132-86.61\n\tc-25.273-29.746-53.107-64.491-104.082-64.491C88.634,150.482,50,195.846,50,256s38.634,105.518,95.536,105.518\n\tc39.992,0,66.391-24.098,93.464-52.518l-27.25-31.5c-18.6,21.677-38.439,41.24-66.214,41.24c-33.875,0-54.185-25.56-54.185-62.74\n\tc0-37.181,20.31-62.74,54.185-62.74c31.581,0,52.102,26.093,74.468,51.333c22.629,25.54,74.819,85.916,74.819,85.916L265.396,360.5\n\th87.813V271L323.75,301.584z`},\n\t\t\t//iconmonstr-cube-6-icon.svg\n\t\t\t'constituent-vnfd': {\n\t\t\t\twidth: 350,\n\t\t\t\td: `M256,50L67.166,153v208.246L256,462l188.834-100.754V154.123L256,50z M391.791,164.09l-135.707,72.405\n\tl-135.138-73.712l134.97-73.621L391.791,164.09z M101.5,191.281l137.333,74.902V413.92L101.5,340.66V191.281z M273.166,413.92\n\tV266.302L410.5,193.025V340.66L273.166,413.92z M387.801,322.688c0.117,5.7-4.393,10.394-10.092,10.495\n\tc-5.699,0.133-10.377-4.393-10.494-10.093c-0.102-5.683,4.393-10.394,10.092-10.495\n\tC383.006,312.479,387.701,316.988,387.801,322.688z M341.28,293.904c-5.7,0.117-10.21,4.811-10.093,10.494\n\tc0.102,5.684,4.795,10.209,10.495,10.109c5.7-0.117,10.192-4.828,10.092-10.350C351.657,298.312,346.98,293.787,341.28,293.904z\n\t M304.684,275.111c-5.699,0.117-10.209,4.828-10.092,10.350c0.1,5.683,4.795,10.209,10.494,10.092s10.193-4.812,10.092-10.350\n\tC315.061,279.521,310.383,275.011,304.684,275.111z M134.693,312.596c5.699,0.102,10.192,4.812,10.092,10.495\n\tc-0.117,5.7-4.795,10.226-10.494,10.093c-5.7-0.102-10.21-4.795-10.093-10.495C124.299,316.988,128.993,312.479,134.693,312.596z\n\t M160.226,303.996c-0.101,5.684,4.392,10.395,10.092,10.350c5.7,0.1,10.394-4.426,10.494-10.109\n\tc0.117-5.684-4.392-10.377-10.092-10.494S160.343,298.312,160.226,303.996z M196.821,285.203c-0.101,5.7,4.393,10.395,10.093,10.350\n\tc5.699,0.117,10.394-4.409,10.494-10.092c0.117-5.684-4.393-10.395-10.092-10.350C201.616,275.011,196.939,279.521,196.821,285.203z\n\t M256,186.529c-5.684,0-10.294,4.61-10.294,10.302c0,5.691,4.61,10.301,10.294,10.301s10.293-4.61,10.293-10.301\n\tC266.293,191.139,261.684,186.529,256,186.529z M256,148.331c-5.684,0-10.294,4.61-10.294,10.302s4.61,10.302,10.294,10.302\n\ts10.293-4.61,10.293-10.302S261.684,148.331,256,148.331z M256,113.461c-5.684,0-10.294,4.61-10.294,10.302\n\ts4.61,10.302,10.294,10.302s10.293-4.61,10.293-10.302S261.684,113.461,256,113.461z`},\n\t\t\t//iconmonstr-network-6-icon.svg\n\t\t\tnsd: {\n\t\t\t\twidth: 350,\n\t\t\t\td: `M225.741,122.262c-10.096-4.89-19.027-8.84-27.496-12.287C211.636,74.43,230.974,51,256.001,51\n\tc24.381,0,43.363,22.232,56.707,56.239c-8.562,3.61-17.355,7.632-27.344,12.62C275.138,93.088,263.472,81,256.001,81\n\tC248.31,81,236.177,93.811,225.741,122.262z M256.001,431c-7.471,0-19.135-12.088-29.361-38.86\n\tc-10.084,5.036-18.803,9.016-27.346,12.621C212.64,438.767,231.62,461,256.001,461c25.029,0,44.365-23.43,57.758-58.974\n\tc-8.439-3.436-17.34-7.367-27.496-12.288C275.827,418.19,263.692,431,256.001,431z M174.112,393.154\n\tc-33.35,12.045-83.111,23.78-102.887-5.42c-9.77-14.427-13.416-42.163,24.695-92.376c10.111-13.322,21.816-26.408,33.689-38.419\n\tc26.635-26.545,56.641-52.096,95.738-78.552c-18.822-10.192-39.367-19.936-59.412-27.187c-20.52-7.424-38.586-11.535-52.428-11.535\n\tc-8.842,0-15.404,1.843-17.553,4.93c-2.285,3.281-2.398,13.373,7.744,31.476c1.201-0.132,2.418-0.206,3.652-0.206\n\tc18.225,0,33,14.775,33,33c0,18.227-14.775,33-33,33s-33-14.773-33-33c0-5.902,1.559-11.439,4.273-16.233\n\tc-19.311-33.481-15.328-53.631-7.291-65.177c5.648-8.115,17.551-17.789,42.174-17.789c43.723,0,102.635,28.356,140.564,50.322\n\tc38.51-23.28,99.422-53.988,144.42-53.988c24.723,0,36.639,9.932,42.281,18.264c9.77,14.428,13.416,42.164-24.693,92.377\n\tC362.44,287.316,255.792,363.653,174.112,393.154z M392.185,198.504c26.182-34.497,26.984-52.643,23.75-57.418\n\tc-2.189-3.232-8.545-5.086-17.441-5.086c-33.951,0-85.664,24.93-115.436,41.803c21.982,14.287,42.518,29.346,61.24,44.701\n\tc-7.084,7.058-14.51,13.981-22.102,20.68c-20.783-16.807-43.885-33.264-67.832-48.011c-27.5,17.708-55.186,38.509-80.055,60.672\n\tc18.705,16.243,40.973,33.296,64.725,49.076c-9.086,5.654-18.26,11.073-28.729,16.744c-0.004-0.003-0.006-0.005-0.01-0.007\n\tc-0.078-0.055-0.154-0.109-0.232-0.164c-19.885-13.853-39.51-29.054-57.662-44.965c-49.02,49.168-62.828,84.795-56.336,94.383\n\tc2.189,3.233,8.549,5.088,17.443,5.088c40.871,0,105.748-34.459,144.129-59.173C304.759,286.485,358.495,242.895,392.185,198.504z\n\t M433.524,319.63c2.441-4.605,3.83-9.855,3.83-15.432c0-18.225-14.775-33-33-33s-33,14.775-33,33c0,18.227,14.775,33,33,33\n\tc1.521,0,3.016-0.112,4.48-0.312c9.611,17.505,9.453,27.295,7.209,30.519c-2.148,3.086-8.709,4.929-17.551,4.929\n\tc-27.856,0-66.664-16.141-91.65-28.324c-8.357,5.839-18.73,12.77-28.846,19.122c33.494,17.717,82.752,39.202,120.496,39.202\n\tc24.621,0,36.523-9.674,42.172-17.788C448.683,373.03,452.663,352.955,433.524,319.63z`},\n\t\t\t//iconmonstr-code-fork-icon.svg\n\t\t\tvld: {\n\t\t\t\twidth: 350,\n\t\t\t\td: `M410.5,101.5c0-28.449-23.051-51.5-51.5-51.5s-51.5,23.051-51.5,51.5\n\tc0,22.716,14.786,41.76,35.188,48.617c2.884,73.729-34.702,81.785-85.792,92.547c-29.346,6.186-62.514,13.311-86.73,35.801V149.848\n\tc19.958-7.091,34.333-25.951,34.333-48.348c0-28.449-23.051-51.5-51.5-51.5s-51.5,23.051-51.5,51.5\n\tc0,22.397,14.375,41.257,34.333,48.348v212.304c-19.958,7.091-34.333,25.951-34.333,48.348c0,28.449,23.051,51.5,51.5,51.5\n\ts51.5-23.051,51.5-51.5c0-22.229-14.149-40.988-33.864-48.215c4.635-67.324,44.124-75.656,93.334-86.033\n\tc52.146-10.981,116.287-24.745,112.934-126.638C396.484,142.321,410.5,123.621,410.5,101.5z M122.104,101.5\n\tc0-17.041,13.855-30.896,30.896-30.896s30.896,13.855,30.896,30.896S170.041,132.396,153,132.396S122.104,118.541,122.104,101.5z\n\t M183.896,410.5c0,17.033-13.855,30.896-30.896,30.896s-30.896-13.863-30.896-30.896s13.855-30.896,30.896-30.896\n\tS183.896,393.467,183.896,410.5z M359,132.396c-17.033,0-30.896-13.855-30.896-30.896S341.967,70.604,359,70.604\n\ts30.896,13.855,30.896,30.896S376.033,132.396,359,132.396z`},\n\t\t\tcatalog: ``,\n\t\t\tcommon: ``\n\t\t}\n\t}\n\n}\n\nexport default IconFactory;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/IconFactory.js\n **/","/*global SVGSVGElement, SVGPathElement*/\n/**\n * Created by onvelocity on 2/6/16.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport d3 from 'd3'\nimport UID from './UniqueId'\nimport React from 'react'\nimport PathBuilder from './graph/PathBuilder'\n\nconst SELECTIONS = '::private::selections';\n\n/**\n * SelectionManager provides two features:\n * \t1) given DescriptorModel instances mark them as 'selected'\n * \t2) given DOM elements draw an outline around them\n *\n * Note that the consumer must call addSelection(descriptor) and outlineElement(dom) seperately. This allows for complex\n * selections to be separate from the outline indicator. It also allows for selection sets that do not have a visual\n * outline associated with them.\n */\nclass SelectionManager {\n\n\tstatic get paused() {\n\t\treturn this._paused;\n\t}\n\n\tstatic set paused(v) {\n\t\tthis._paused = v;\n\t}\n\n\tstatic pause() {\n\t\tSelectionManager.paused = true;\n\t\tSelectionManager.removeEventListeners();\n\t}\n\n\tstatic resume() {\n\t\tSelectionManager.paused = false;\n\t\tSelectionManager.addEventListeners(SelectionManager.element);\n\t}\n\n\tstatic select(obj) {\n\t\tconst isSelected = SelectionManager.isSelected(obj);\n\t\tif (!isSelected) {\n\t\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\t\tSelectionManager.addSelection(obj);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tstatic reactPauseResumeMixin() {\n\t\treturn {pauseSelection (disable) {\n\t\t\tif (disable) {\n\t\t\t\treturn {\n\t\t\t\t\tonMouseDownCapture: () => {\n\t\t\t\t\t\tSelectionManager.pause();\n\t\t\t\t\t},\n\t\t\t\t\t// slight delay is to prevent a click from clearing the selection\n\t\t\t\t\tonMouseUp: () => {\n\t\t\t\t\t\tsetTimeout(() => SelectionManager.resume(), 200);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t}};\n\t}\n\n\tstatic addEventListeners(element) {\n\t\tSelectionManager.removeEventListeners();\n\t\tthis.element = element || document.body;\n\t\tthis.element.addEventListener('mousedown', SelectionManager.onMouseDown);\n\t\tthis.element.addEventListener('mousemove', SelectionManager.onMouseMove);\n\t\tthis.element.addEventListener('click', SelectionManager.onClickCaptureUpdateSelection, true);\n\t}\n\n\tstatic removeEventListeners() {\n\t\tif (this.element) {\n\t\t\tthis.element.removeEventListener('click', SelectionManager.onClickCaptureUpdateSelection, true);\n\t\t\tthis.element.removeEventListener('mousedown', SelectionManager.onMouseDown);\n\t\t\tthis.element.removeEventListener('mousemove', SelectionManager.onMouseMove);\n\t\t}\n\t}\n\n\tstatic onClickCaptureUpdateSelection(event) {\n\t\tif (event.defaultPrevented) {\n\t\t\treturn\n\t\t}\n\t\tconst target = SelectionManager.getClosestElementWithUID(event.target);\n\t\tif (SelectionManager.isSelected(target)) {\n\t\t\treturn\n\t\t}\n\t\tif (SelectionManager.getSelections().length) {\n\t\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\t}\n\n\t\tdelete this._mouseDownPosition;\n\n\t}\n\n\tstatic onMouseDown(event) {\n\t\tthis._mouseDownPosition = {\n\t\t\tclientX: event.clientX,\n\t\t\tclientY: event.clientY,\n\t\t\ttimeStamp: event.timeStamp\n\t\t};\n\t}\n\n\tstatic onMouseMove(event) {\n\t\tif (!this._mouseDownPosition) {\n\t\t\treturn;\n\t\t}\n\t\tconst target = SelectionManager.getClosestElementWithUID(event.target);\n\t\tif (!SelectionManager.isSelected(target)) {\n\t\t\treturn\n\t\t}\n\t\tif (this._mouseDownPosition.clientX - event.clientX ||\n\t\t\tthis._mouseDownPosition.clientY - event.clientY) {\n\t\t\tSelectionManager.moveOutline();\n\t\t}\n\t}\n\n\tstatic isSelected(obj) {\n\t\tconst uid = UID.from(obj);\n\t\tif (uid) {\n\t\t\treturn SelectionManager[SELECTIONS].has(uid);\n\t\t}\n\t}\n\n\tstatic getSelections() {\n\t\treturn Array.from(SelectionManager[SELECTIONS]).filter(d => d);\n\t}\n\n\tstatic addSelection(obj) {\n\t\tif (this.paused) {\n\t\t\treturn;\n\t\t}\n\t\tconst uid = UID.from(obj);\n\t\tif (uid) {\n\t\t\tSelectionManager[SELECTIONS].add(uid);\n\t\t}\n\t}\n\n\tstatic updateSelection(container, addOrRemove = true) {\n\t\tif (addOrRemove) {\n\t\t\tSelectionManager.addSelection(container);\n\t\t} else {\n\t\t\tSelectionManager.removeSelection(container);\n\t\t}\n\t}\n\n\tstatic removeSelection(obj) {\n\t\tif (this.paused) {\n\t\t\treturn;\n\t\t}\n\t\tconst uid = UID.from(obj);\n\t\tif (uid) {\n\t\t\tSelectionManager[SELECTIONS].delete(uid);\n\t\t}\n\t}\n\n\tstatic clearSelectionAndRemoveOutline() {\n\t\tif (this.paused) {\n\t\t\treturn;\n\t\t}\n\t\tSelectionManager.removeOutline();\n\t\tconst unselected = SelectionManager.getSelections();\n\t\tif (unselected.length) {\n\t\t\tSelectionManager[SELECTIONS].clear();\n\t\t}\n\t\treturn unselected;\n\t}\n\n\tstatic removeOutline() {\n\t\tif (this.paused) {\n\t\t\treturn;\n\t\t}\n\t\tArray.from(document.querySelectorAll('[data-outline-indicator-outline]')).forEach(n => d3.select(n).remove());\n\t}\n\n\tstatic refreshOutline() {\n\t\tsetTimeout(() => {\n\t\t\tSelectionManager.resume();\n\t\t\tSelectionManager.removeOutline();\n\t\t\tSelectionManager.getSelections().forEach(uid => {\n\t\t\t\tArray.from(this.element.querySelectorAll(`[data-uid=\"${uid}\"]`)).forEach(SelectionManager.outline.bind(this));\n\t\t\t});\n\t\t}, 100);\n\t}\n\n\tstatic moveOutline() {\n\t\tSelectionManager.getSelections().forEach(uid => {\n\t\t\tArray.from(this.element.querySelectorAll(`[data-uid=\"${uid}\"]`)).forEach(SelectionManager.outline.bind(this));\n\t\t});\n\t}\n\n\tstatic outline(dom) {\n\n\t\tif (this.paused) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst elements = Array.isArray(dom) ? dom : [dom];\n\n\t\telements.map(SelectionManager.getClosestElementWithUID).filter(d => d).forEach(element => {\n\n\t\t\tif (element instanceof SVGElement) {\n\t\t\t\tSelectionManager.outlineSvg(element);\n\t\t\t} else {\n\t\t\t\tSelectionManager.outlineDom(element);\n\t\t\t}\n\n\t\t});\n\n\t}\n\n\tstatic outlineSvg(element) {\n\n\t\tconst svg = element.viewportElement;\n\n\t\tconst path = new PathBuilder();\n\n\t\tconst dim = element.getBBox();\n\t\tconst adjustPos = SelectionManager.sumTranslates(element);\n\n\t\tlet w = dim.width + 11;\n\t\tlet h = dim.height + 11;\n\t\tlet top = adjustPos[1] - 8 + dim.y;\n\t\tlet left = adjustPos[0] - 8 + dim.x;\n\n\t\tlet square = path.M(5, 5).L(w, 5).L(w, h).L(5, h).L(5, 5).Z.toString();\n\n\t\tif (element instanceof SVGPathElement) {\n\t\t\tconst t = d3.transform(d3.select(element).attr('transform')).translate;\n\t\t\tsquare = d3.select(element).attr('d');\n\t\t\ttop = t[1];\n\t\t\tleft = t[0];\n\t\t}\n\n\t\tconst data = {\n\t\t\ttop: top,\n\t\t\tleft: left,\n\t\t\tpath: square\n\t\t};\n\n\t\tconst indicator = svg.querySelector(['[data-outline-indicator]']) || svg;\n\n\t\tconst outline = d3.select(indicator).selectAll('[data-outline-indicator-outline]').data([data]);\n\n\t\toutline.enter().append('g').attr({\n\t\t\t'data-outline-indicator-outline': true,\n\t\t}).style({\n\t\t\t'pointer-events': 'none'\n\t\t}).append('path').attr({\n\t\t\tstroke: 'red',\n\t\t\tfill: 'transparent',\n\t\t\t'stroke-width': '1.5px',\n\t\t\t'stroke-linejoin': 'round',\n\t\t\t'stroke-dasharray': '4',\n\t\t\td: d => d.path\n\t\t});\n\n\t\toutline.attr({\n\t\t\ttransform: d => `translate(${d.left}, ${d.top})`\n\t\t});\n\n\t\toutline.exit().remove();\n\n\t}\n\n\tstatic outlineDom(element) {\n\n\t\telement = SelectionManager.getClosestElementWithUID(element);\n\n\t\tconst offsetParent = SelectionManager.offsetParent(element);\n\n\t\tconst dim = element.getBoundingClientRect();\n\t\tconst w = dim.width + 11;\n\t\tconst h = dim.height + 11;\n\n\n\t\tconst path = new PathBuilder();\n\t\tconst square = path.M(5, 5).L(w, 5).L(w, h).L(5, h).L(5, 5).Z.toString();\n\n\t\tlet parentDim;\n\n\t\tparentDim = SelectionManager.offsetDimensions(offsetParent);\n\n\t\tconst top = dim.top - parentDim.top;\n\t\tconst left = dim.left - parentDim.left;\n\t\tconst svg = d3.select(offsetParent).append('svg').attr({\n\t\t\t'data-outline-indicator-outline': true,\n\t\t\twidth: dim.width + 20,\n\t\t\theight: dim.height + 23,\n\t\t\tstyle: `pointer-events: none; position: absolute; z-index: 999; top: ${top - 8}px; left: ${left - 8}px; background: transparent;`\n\n\t\t}).append('g').append('path').attr({\n\n\t\t\tstroke: 'red',\n\t\t\tfill: 'transparent',\n\t\t\t'stroke-width': '1.5px',\n\t\t\t'stroke-linejoin': 'round',\n\t\t\t'stroke-dasharray': '4',\n\t\t\td: square // 'M 4 4 L 30 4 L 30 30 L 4 30 L 4 4 Z'\n\n\t\t});\n\n\t}\n\n\tstatic getClosestElementWithUID(element) {\n\t\tlet target = element;\n\t\twhile (target) {\n\t\t\tif (UID.from(target)) {\n\t\t\t\treturn target;\n\t\t\t}\n\t\t\tif (target === target.parentNode) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget = target.parentNode;\n\t\t}\n\t}\n\n\tstatic offsetParent(target) {\n\t\twhile (target) {\n\t\t\tif ((d3.select(target).attr('data-offset-parent')) || target.nodeName === 'BODY') {\n\t\t\t\treturn target;\n\t\t\t}\n\t\t\ttarget = target.parentNode;\n\t\t}\n\t\treturn document.body;\n\t}\n\n\t/**\n\t * Util for determining the widest child of an offsetParent that is scrolled.\n\t *\n\t * @param element\n\t * @returns {{top: Number, right: Number, bottom: Number, left: Number, height: Number, width: Number}}\n\t */\n\tstatic offsetDimensions (element) {\n\n\t\tconst elementDim = element.getBoundingClientRect();\n\t\tconst dim = {\n\t\t\ttop: elementDim.top,\n\t\t\tright: elementDim.right,\n\t\t\tbottom: elementDim.bottom,\n\t\t\tleft: elementDim.left,\n\t\t\theight: elementDim.height,\n\t\t\twidth: elementDim.width\n\t\t};\n\n\t\tif (element.dataset && element.dataset.offsetWidth) {\n\t\t\tconst widthSelector = element.dataset.offsetWidth;\n\t\t\tconst overrideWidth = Array.from(element.querySelectorAll(widthSelector));\n\t\t\tdim.width = overrideWidth.reduce((width, child) => {\n\t\t\t\tconst dim = child.getBoundingClientRect();\n\t\t\t\treturn Math.max(width, dim.width);\n\t\t\t}, elementDim.width);\n\t\t}\n\n\t\treturn dim;\n\n\t}\n\n\tstatic sumTranslates(element) {\n\t\tlet parent = element;\n\t\tconst result = [0, 0];\n\t\twhile (parent) {\n\t\t\tconst t = d3.transform(d3.select(parent).attr('transform')).translate;\n\t\t\tresult[0] += t[0];\n\t\t\tresult[1] += t[1];\n\t\t\tif (!parent.parentNode || /svg/i.test(parent.nodeName) || parent === parent.parentNode) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tparent = parent.parentNode;\n\t\t}\n\t\treturn result;\n\t}\n\n}\n\n// warn static variable to store all selections across instances\nSelectionManager[SELECTIONS] = SelectionManager[SELECTIONS] || new Set();\n\nexport default SelectionManager;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/SelectionManager.js\n **/","\n/**\n * Created by onvelocity on 2/10/16.\n */\n\nexport default class PathBuilder {\n\n\tconstructor() {\n\t\tthis.path = [];\n\t}\n\n\tstatic archFlags(override) {\n\t\treturn Object.assign({xAxisRotation: 0, largeArcFlag: 0, sweepFlag: 0}, override);\n\t}\n\n\tM(x, y, info = {}) {\n\t\tthis.path.push({x: x, y: y, cmd: 'M', info: info});\n\t\treturn this;\n\t}\n\n\tm(dx, dy, info = {}) {\n\t\tthis.path.push({dx: dx, dy: dy, cmd: 'm', info: info});\n\t\treturn this;\n\t}\n\n\tL(x, y, info = {}) {\n\t\tthis.path.push({x: x, y: y, cmd: 'L', info: info});\n\t\treturn this;\n\t}\n\n\tl(dx, dy, info = {}) {\n\t\tthis.path.push({dx: dx, dy: dy, cmd: 'l', info: info});\n\t\treturn this;\n\t}\n\n\tH(x, info = {}) {\n\t\tthis.path.push({x: x, cmd: 'H', info: info});\n\t\treturn this;\n\t}\n\n\th(dx, info = {}) {\n\t\tthis.path.push({dx: dx, cmd: 'h', info: info});\n\t\treturn this;\n\t}\n\n\tV(y, info = {}) {\n\t\tthis.path.push({y: y, cmd: 'V', info: info});\n\t\treturn this;\n\t}\n\n\tv(dy, info = {}) {\n\t\tthis.path.push({dy: dy, cmd: 'v', info: info});\n\t\treturn this;\n\t}\n\n\tC(x1, y1, x2, y2, x, y, info = {}) {\n\t\tthis.path.push({x1: x1, y1: y1, x2: x2, y2: y2, x: x, y: y, cmd: 'C', info: info});\n\t\treturn this;\n\t}\n\n\tc(dx1, dy1, dx2, dy2, dx, dy, info = {}) {\n\t\tthis.path.push({dx1: dx1, dy1: dy1, dx2: dx2, dy2: dy2, dx: dx, dy: dy, cmd: 'c', info: info});\n\t\treturn this;\n\t}\n\n\tQ(x1, y1, x, y, info = {}) {\n\t\tthis.path.push({x1: x1, y1: y1, x: x, y: y, cmd: 'Q', info: info});\n\t\treturn this;\n\t}\n\n\tq(x1, y1, x, y, info = {}) {\n\t\tthis.path.push({x1: x1, y1: y1, x: x, y: y, cmd: 'q', info: info});\n\t\treturn this;\n\t}\n\n\tT(x, y, info = {}) {\n\t\tthis.path.push({x: x, y: y, cmd: 'T', info: info});\n\t\treturn this;\n\t}\n\n\tA (rx, ry, x, y, info = {xAxisRotation: 0, largeArcFlag: 0, sweepFlag: 0}) {\n\t\tinfo = PathBuilder.archFlags(info);\n\t\tthis.path.push({rx: rx, ry: ry, 'x-axis-rotation': info.xAxisRotation,  'large-arc-flag': info.largeArcFlag, 'sweep-flag': info.sweepFlag, x: x, y: y, cmd: 'A', info: info});\n\t\treturn this;\n\t}\n\n\tS(x2, y2, x, y, info = {}) {\n\t\tthis.path.push({x2: x2, y2: y2, x: x, y: y, cmd: 'S', info: info});\n\t\treturn this;\n\t}\n\n\tH(x, info = {}) {\n\t\tthis.path.push({x: x, info: info});\n\t\treturn this;\n\t}\n\n\th(dx, info = {}) {\n\t\tthis.path.push({dx: dx, info: info});\n\t\treturn this;\n\t}\n\n\tV(y, info = {}) {\n\t\tthis.path.push({y: y, info: info});\n\t\treturn this;\n\t}\n\n\tv(dy, info = {}) {\n\t\tthis.path.push({dy: dy, info: info});\n\t\treturn this;\n\t}\n\n\tget Z() {\n\t\tthis.path.push({cmd: 'Z'});\n\t\treturn this;\n\t}\n\n\tlast() {\n\t\treturn this.path[this.path.length - 1];\n\t}\n\n\tfindPrevious(filter) {\n\t\treturn this.path.splice().reverse().reduce((r, d) => {\n\t\t\tif (r) {\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\tif (filter(d)) {\n\t\t\t\treturn d\n\t\t\t}\n\t\t}, null);\n\t}\n\n\tinsertBeforeLast() {\n\t\tif (this.path.length < 3) {\n\t\t\treturn this;\n\t\t}\n\t\tconst last = this.path.pop();\n\t\tthis.path.splice(this.length - 2, 0, last);\n\t\treturn this;\n\t}\n\n\tconcat(pathBuilder) {\n\t\tthis.path = this.path.filter(d => d.cmd !== 'Z').concat(pathBuilder);\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\treturn this.path.reduce((r, d) => {\n\t\t\treturn r + ' ' + d.cmd + ' ' + Object.keys(d).filter(k => !(k == 'cmd' || k === 'info')).map(k => d[k]).reduce((r, val) => r + ' ' + val, '');\n\t\t}, '').replace(/\\s+/g, ' ').trim();\n\t}\n\n\tget length() {\n\t\treturn this.path.length;\n\t}\n\n\tstatic descriptorPath(borderRadius = 20, height = 55, width = 250) {\n\t\tconst path = new PathBuilder();\n\t\tborderRadius = Math.max(0, borderRadius);\n\t\twidth = Math.max(borderRadius, width) - borderRadius;\n\t\theight = Math.max(borderRadius, height) - (borderRadius);\n\t\tconst iconWidthHeight = 40;\n\t\treturn path.M(0, 0)\n\t\t\t// top\n\t\t\t.L(width, 0).C(width, 0, width + borderRadius, 0, width + borderRadius, borderRadius)\n\t\t\t// right\n\t\t\t.L(width + borderRadius, height).C(width + borderRadius, height, width + borderRadius, height + borderRadius, width, height + borderRadius)\n\t\t\t// bottom\n\t\t\t.L(0, height + borderRadius).C(0, height + borderRadius, 0 - borderRadius, height + borderRadius, 0 - borderRadius, height)\n\t\t\t// left\n\t\t\t.L(0 - borderRadius, 0 + borderRadius).C(0 - borderRadius, 0 + borderRadius, 0 - borderRadius, 0, 0, 0)\n\t\t\t// icon separator\n\t\t\t.L(iconWidthHeight, 0).L(iconWidthHeight, iconWidthHeight + (borderRadius + height - iconWidthHeight))\n\t\t\t// label separator\n\t\t\t//.L(iconWidthHeight, iconWidthHeight).L(0 - borderRadius, iconWidthHeight);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/PathBuilder.js\n **/","/**\n * Created by onvelocity on 1/27/16.\n *\n * This class provides methods to get the metadata about descriptor models.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport utils from './../utils'\nimport DescriptorModelMetaJSON from 'json!./DescriptorModelMeta.json'\nimport DescriptorModelMetaProperty from './DescriptorModelMetaProperty'\n\nconst assign = Object.assign;\n\nconst exportInnerTypesMap = {\n\t'constituent-vnfd': 'nsd.constituent-vnfd',\n\t'vdu': 'vnfd.vdu'\n};\n\nfunction getPathForType(type) {\n\tif (exportInnerTypesMap[type]) {\n\t\treturn exportInnerTypesMap[type];\n\t}\n\treturn type;\n}\n\nconst modelMetaByPropertyNameMap = Object.keys(DescriptorModelMetaJSON).reduce((map, key) => {\n\tfunction mapProperties(parentMap, parentObj) {\n\t\tparentMap[':meta'] = parentObj;\n\t\tconst properties = parentObj && parentObj.properties ? parentObj.properties : [];\n\t\tproperties.forEach(p => {\n\t\t\tparentMap[p.name] = mapProperties({}, assign(p, {':qualified-type': parentObj[':qualified-type'] + '.' + p.name}));\n\t\t\treturn map;\n\t\t}, parentMap);\n\t\treturn parentMap;\n\t}\n\tmap[key] = mapProperties({}, assign(DescriptorModelMetaJSON[key], {':qualified-type': key}));\n\treturn map;\n}, {});\n\n(() => {\n\t// initialize the UI centric properties that CONFD could care less about\n\tutils.assignPathValue(modelMetaByPropertyNameMap, 'nsd.constituent-vnfd.vnf-configuration.config-template.:meta.preserve-line-breaks', true);\n})();\n\nexport default {\n\tcreateModelInstanceForType(typeOrPath) {\n\t\tconst modelMeta = this.getModelMetaForType(typeOrPath);\n\t\treturn DescriptorModelMetaProperty.createModelInstance(modelMeta);\n\t},\n\tgetModelMetaForType(typeOrPath, filterProperties = () => true) {\n\t\t// resolve paths like 'nsd' or 'vnfd.vdu' or 'nsd.constituent-vnfd'\n\t\tconst found = utils.resolvePath(modelMetaByPropertyNameMap, getPathForType(typeOrPath));\n\t\tif (found) {\n\t\t\tconst meta = _.cloneDeep(found[':meta']);\n\t\t\tmeta.properties = meta.properties.filter(filterProperties);\n\t\t\treturn meta;\n\t\t}\n\t\tconsole.warn('no model meta found for type', typeOrPath);\n\t},\n\tgetModelFieldNamesForType(typeOrPath) {\n\t\t// resolve paths like 'nsd' or 'vnfd.vdu' or 'nsd.constituent-vnfd'\n\t\tconst found = utils.resolvePath(modelMetaByPropertyNameMap, getPathForType(typeOrPath));\n\t\tif (found) {\n\t\t\treturn found[':meta'].properties.map(p => p.name);\n\t\t}\n\t\tconsole.warn('no model meta found for type', typeOrPath);\n\t}\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorModelMetaFactory.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n\n'use strict';\n\nimport changeCase from 'change-case';\n\nexport default {\n\taddAuthorizationStub(xhr) {\n\t\txhr.setRequestHeader('Authorization', 'Basic YWRtaW46YWRtaW4=');\n\t},\n\tgetSearchParams(url) {\n\t\tvar a = document.createElement('a');\n\t\ta.href = url;\n\t\tvar params = {};\n\t\tvar items = a.search.replace('?', '').split('&');\n\t\tfor (var i = 0; i < items.length; i++) {\n\t\t\tif (items[i].length > 0) {\n\t\t\t\tvar key_value = items[i].split('=');\n\t\t\t\tparams[key_value[0]] = decodeURIComponent(key_value[1]);\n\t\t\t}\n\t\t}\n\t\treturn params;\n\t},\n\tparseJSONIgnoreErrors(txt) {\n\t\ttry {\n\t\t\treturn JSON.parse(txt);\n\t\t} catch (ignore) {\n\t\t\treturn {};\n\t\t}\n\t},\n\tresolvePath(obj, path) {\n\t\t// supports a.b, a[1] and foo[bar], etc.\n\t\t// where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]\n\t\t// then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;\n\t\tpath = path.split(/[\\.\\[\\]]/).filter(d => d);\n\t\treturn path.reduce((r, p) => {\n\t\t\tif (r) {\n\t\t\t\treturn r[p];\n\t\t\t}\n\t\t}, obj);\n\t},\n\tassignPathValue(obj, path, value) {\n\t\tpath = path.split(/[\\.\\[\\]]/).filter(d => d);\n\t\t// enable look-ahead to determine if type is array or object\n\t\tconst pathCopy = path.slice();\n\t\t// last item in path used to assign value on the resolved object\n\t\tconst name = path.pop();\n\t\tconst resolvedObj = path.reduce((r, p, i) => {\n\t\t\tif (typeof(r[p]) !== 'object') {\n\t\t\t\t// look-ahead to see if next path item is a number\n\t\t\t\tconst isArray = !isNaN(parseInt(pathCopy[i + 1], 10));\n\t\t\t\tr[p] = isArray ? [] : {}\n\t\t\t}\n\t\t\treturn r[p];\n\t\t}, obj);\n\t\tresolvedObj[name] = value;\n\t},\n\tupdatePathValue(obj, path, value) {\n\t\t// todo: replace implementation of assignPathValue with this impl and\n\t\t// remove updatePathValue (only need one function, not both)\n\t\t// same as assignPathValue except removes property if value is undefined\n\t\tpath = path.split(/[\\.\\[\\]]/).filter(d => d);\n\t\tconst isRemove = typeof value === 'undefined';\n\t\t// enable look-ahead to determine if type is array or object\n\t\tconst pathCopy = path.slice();\n\t\t// last item in path used to assign value on the resolved object\n\t\tconst name = path.pop();\n\t\tconst resolvedObj = path.reduce((r, p, i) => {\n\t\t\t// look-ahead to see if next path item is a number\n\t\t\tconst index = parseInt(pathCopy[i + 1], 10);\n\t\t\tconst isArray = !isNaN(index);\n\t\t\tif (typeof(r[p]) !== 'object') {\n\t\t\t\tr[p] = isArray ? [] : {}\n\t\t\t}\n\t\t\tif (isRemove && ((i + 1) === path.length)) {\n\t\t\t\tif (isArray) {\n\t\t\t\t\tr[p] = r[p].filter((d, i) => i !== index);\n\t\t\t\t} else {\n\t\t\t\t\tdelete r[p][name];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn r[p];\n\t\t}, obj);\n\t\tif (!isRemove) {\n\t\t\tresolvedObj[name] = value;\n\t\t}\n\t},\n\tremovePathValue(obj, path) {\n\t\t// note updatePathValue removes value if third argument is undefined\n\t\treturn this.updatePathValue(obj, path);\n\t}\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/utils.js\n **/","exports.dot = exports.dotCase = require('dot-case')\nexports.swap = exports.swapCase = require('swap-case')\nexports.path = exports.pathCase = require('path-case')\nexports.upper = exports.upperCase = require('upper-case')\nexports.lower = exports.lowerCase = require('lower-case')\nexports.camel = exports.camelCase = require('camel-case')\nexports.snake = exports.snakeCase = require('snake-case')\nexports.title = exports.titleCase = require('title-case')\nexports.param = exports.paramCase = require('param-case')\nexports.pascal = exports.pascalCase = require('pascal-case')\nexports.constant = exports.constantCase = require('constant-case')\nexports.sentence = exports.sentenceCase = require('sentence-case')\nexports.isUpper = exports.isUpperCase = require('is-upper-case')\nexports.isLower = exports.isLowerCase = require('is-lower-case')\nexports.ucFirst = exports.upperCaseFirst = require('upper-case-first')\nexports.lcFirst = exports.lowerCaseFirst = require('lower-case-first')\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/change-case.js\n ** module id = 389\n ** module chunks = 0\n **/","var sentenceCase = require('sentence-case');\n\n/**\n * Dot case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (string, locale) {\n  return sentenceCase(string, locale, '.');\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/dot-case/dot-case.js\n ** module id = 390\n ** module chunks = 0\n **/","var lowerCase = require('lower-case')\n\nvar NON_WORD_REGEXP = require('./vendor/non-word-regexp')\nvar CAMEL_CASE_REGEXP = require('./vendor/camel-case-regexp')\nvar TRAILING_DIGIT_REGEXP = require('./vendor/trailing-digit-regexp')\n\n/**\n * Sentence case a string.\n *\n * @param  {String} str\n * @param  {String} locale\n * @param  {String} replacement\n * @return {String}\n */\nmodule.exports = function (str, locale, replacement) {\n  if (str == null) {\n    return ''\n  }\n\n  replacement = replacement || ' '\n\n  function replace (match, index, string) {\n    if (index === 0 || index === (string.length - match.length)) {\n      return ''\n    }\n\n    return replacement\n  }\n\n  str = String(str)\n    // Support camel case (\"camelCase\" -> \"camel Case\").\n    .replace(CAMEL_CASE_REGEXP, '$1 $2')\n    // Support digit groups (\"test2012\" -> \"test 2012\").\n    .replace(TRAILING_DIGIT_REGEXP, '$1 $2')\n    // Remove all non-word characters and replace with a single space.\n    .replace(NON_WORD_REGEXP, replace)\n\n  // Lower case the entire string.\n  return lowerCase(str, locale)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/sentence-case/sentence-case.js\n ** module id = 391\n ** module chunks = 0\n **/","/**\n * Special language-specific overrides.\n *\n * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt\n *\n * @type {Object}\n */\nvar LANGUAGES = {\n  tr: {\n    regexp: /\\u0130|\\u0049|\\u0049\\u0307/g,\n    map: {\n      '\\u0130': '\\u0069',\n      '\\u0049': '\\u0131',\n      '\\u0049\\u0307': '\\u0069'\n    }\n  },\n  az: {\n    regexp: /[\\u0130]/g,\n    map: {\n      '\\u0130': '\\u0069',\n      '\\u0049': '\\u0131',\n      '\\u0049\\u0307': '\\u0069'\n    }\n  },\n  lt: {\n    regexp: /[\\u0049\\u004A\\u012E\\u00CC\\u00CD\\u0128]/g,\n    map: {\n      '\\u0049': '\\u0069\\u0307',\n      '\\u004A': '\\u006A\\u0307',\n      '\\u012E': '\\u012F\\u0307',\n      '\\u00CC': '\\u0069\\u0307\\u0300',\n      '\\u00CD': '\\u0069\\u0307\\u0301',\n      '\\u0128': '\\u0069\\u0307\\u0303'\n    }\n  }\n}\n\n/**\n * Lowercase a string.\n *\n * @param  {String} str\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  var lang = LANGUAGES[locale]\n\n  str = str == null ? '' : String(str)\n\n  if (lang) {\n    str = str.replace(lang.regexp, function (m) { return lang.map[m] })\n  }\n\n  return str.toLowerCase()\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/lower-case/lower-case.js\n ** module id = 392\n ** module chunks = 0\n **/","module.exports = /[^\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u0030-\\u0039\\u00B2\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D66-\\u0D75\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19]+/g\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/sentence-case/vendor/non-word-regexp.js\n ** module id = 393\n ** module chunks = 0\n **/","module.exports = /([\\u0061-\\u007A\\u00B5\\u00DF-\\u00F6\\u00F8-\\u00FF\\u0101\\u0103\\u0105\\u0107\\u0109\\u010B\\u010D\\u010F\\u0111\\u0113\\u0115\\u0117\\u0119\\u011B\\u011D\\u011F\\u0121\\u0123\\u0125\\u0127\\u0129\\u012B\\u012D\\u012F\\u0131\\u0133\\u0135\\u0137\\u0138\\u013A\\u013C\\u013E\\u0140\\u0142\\u0144\\u0146\\u0148\\u0149\\u014B\\u014D\\u014F\\u0151\\u0153\\u0155\\u0157\\u0159\\u015B\\u015D\\u015F\\u0161\\u0163\\u0165\\u0167\\u0169\\u016B\\u016D\\u016F\\u0171\\u0173\\u0175\\u0177\\u017A\\u017C\\u017E-\\u0180\\u0183\\u0185\\u0188\\u018C\\u018D\\u0192\\u0195\\u0199-\\u019B\\u019E\\u01A1\\u01A3\\u01A5\\u01A8\\u01AA\\u01AB\\u01AD\\u01B0\\u01B4\\u01B6\\u01B9\\u01BA\\u01BD-\\u01BF\\u01C6\\u01C9\\u01CC\\u01CE\\u01D0\\u01D2\\u01D4\\u01D6\\u01D8\\u01DA\\u01DC\\u01DD\\u01DF\\u01E1\\u01E3\\u01E5\\u01E7\\u01E9\\u01EB\\u01ED\\u01EF\\u01F0\\u01F3\\u01F5\\u01F9\\u01FB\\u01FD\\u01FF\\u0201\\u0203\\u0205\\u0207\\u0209\\u020B\\u020D\\u020F\\u0211\\u0213\\u0215\\u0217\\u0219\\u021B\\u021D\\u021F\\u0221\\u0223\\u0225\\u0227\\u0229\\u022B\\u022D\\u022F\\u0231\\u0233-\\u0239\\u023C\\u023F\\u0240\\u0242\\u0247\\u0249\\u024B\\u024D\\u024F-\\u0293\\u0295-\\u02AF\\u0371\\u0373\\u0377\\u037B-\\u037D\\u0390\\u03AC-\\u03CE\\u03D0\\u03D1\\u03D5-\\u03D7\\u03D9\\u03DB\\u03DD\\u03DF\\u03E1\\u03E3\\u03E5\\u03E7\\u03E9\\u03EB\\u03ED\\u03EF-\\u03F3\\u03F5\\u03F8\\u03FB\\u03FC\\u0430-\\u045F\\u0461\\u0463\\u0465\\u0467\\u0469\\u046B\\u046D\\u046F\\u0471\\u0473\\u0475\\u0477\\u0479\\u047B\\u047D\\u047F\\u0481\\u048B\\u048D\\u048F\\u0491\\u0493\\u0495\\u0497\\u0499\\u049B\\u049D\\u049F\\u04A1\\u04A3\\u04A5\\u04A7\\u04A9\\u04AB\\u04AD\\u04AF\\u04B1\\u04B3\\u04B5\\u04B7\\u04B9\\u04BB\\u04BD\\u04BF\\u04C2\\u04C4\\u04C6\\u04C8\\u04CA\\u04CC\\u04CE\\u04CF\\u04D1\\u04D3\\u04D5\\u04D7\\u04D9\\u04DB\\u04DD\\u04DF\\u04E1\\u04E3\\u04E5\\u04E7\\u04E9\\u04EB\\u04ED\\u04EF\\u04F1\\u04F3\\u04F5\\u04F7\\u04F9\\u04FB\\u04FD\\u04FF\\u0501\\u0503\\u0505\\u0507\\u0509\\u050B\\u050D\\u050F\\u0511\\u0513\\u0515\\u0517\\u0519\\u051B\\u051D\\u051F\\u0521\\u0523\\u0525\\u0527\\u0561-\\u0587\\u1D00-\\u1D2B\\u1D6B-\\u1D77\\u1D79-\\u1D9A\\u1E01\\u1E03\\u1E05\\u1E07\\u1E09\\u1E0B\\u1E0D\\u1E0F\\u1E11\\u1E13\\u1E15\\u1E17\\u1E19\\u1E1B\\u1E1D\\u1E1F\\u1E21\\u1E23\\u1E25\\u1E27\\u1E29\\u1E2B\\u1E2D\\u1E2F\\u1E31\\u1E33\\u1E35\\u1E37\\u1E39\\u1E3B\\u1E3D\\u1E3F\\u1E41\\u1E43\\u1E45\\u1E47\\u1E49\\u1E4B\\u1E4D\\u1E4F\\u1E51\\u1E53\\u1E55\\u1E57\\u1E59\\u1E5B\\u1E5D\\u1E5F\\u1E61\\u1E63\\u1E65\\u1E67\\u1E69\\u1E6B\\u1E6D\\u1E6F\\u1E71\\u1E73\\u1E75\\u1E77\\u1E79\\u1E7B\\u1E7D\\u1E7F\\u1E81\\u1E83\\u1E85\\u1E87\\u1E89\\u1E8B\\u1E8D\\u1E8F\\u1E91\\u1E93\\u1E95-\\u1E9D\\u1E9F\\u1EA1\\u1EA3\\u1EA5\\u1EA7\\u1EA9\\u1EAB\\u1EAD\\u1EAF\\u1EB1\\u1EB3\\u1EB5\\u1EB7\\u1EB9\\u1EBB\\u1EBD\\u1EBF\\u1EC1\\u1EC3\\u1EC5\\u1EC7\\u1EC9\\u1ECB\\u1ECD\\u1ECF\\u1ED1\\u1ED3\\u1ED5\\u1ED7\\u1ED9\\u1EDB\\u1EDD\\u1EDF\\u1EE1\\u1EE3\\u1EE5\\u1EE7\\u1EE9\\u1EEB\\u1EED\\u1EEF\\u1EF1\\u1EF3\\u1EF5\\u1EF7\\u1EF9\\u1EFB\\u1EFD\\u1EFF-\\u1F07\\u1F10-\\u1F15\\u1F20-\\u1F27\\u1F30-\\u1F37\\u1F40-\\u1F45\\u1F50-\\u1F57\\u1F60-\\u1F67\\u1F70-\\u1F7D\\u1F80-\\u1F87\\u1F90-\\u1F97\\u1FA0-\\u1FA7\\u1FB0-\\u1FB4\\u1FB6\\u1FB7\\u1FBE\\u1FC2-\\u1FC4\\u1FC6\\u1FC7\\u1FD0-\\u1FD3\\u1FD6\\u1FD7\\u1FE0-\\u1FE7\\u1FF2-\\u1FF4\\u1FF6\\u1FF7\\u210A\\u210E\\u210F\\u2113\\u212F\\u2134\\u2139\\u213C\\u213D\\u2146-\\u2149\\u214E\\u2184\\u2C30-\\u2C5E\\u2C61\\u2C65\\u2C66\\u2C68\\u2C6A\\u2C6C\\u2C71\\u2C73\\u2C74\\u2C76-\\u2C7B\\u2C81\\u2C83\\u2C85\\u2C87\\u2C89\\u2C8B\\u2C8D\\u2C8F\\u2C91\\u2C93\\u2C95\\u2C97\\u2C99\\u2C9B\\u2C9D\\u2C9F\\u2CA1\\u2CA3\\u2CA5\\u2CA7\\u2CA9\\u2CAB\\u2CAD\\u2CAF\\u2CB1\\u2CB3\\u2CB5\\u2CB7\\u2CB9\\u2CBB\\u2CBD\\u2CBF\\u2CC1\\u2CC3\\u2CC5\\u2CC7\\u2CC9\\u2CCB\\u2CCD\\u2CCF\\u2CD1\\u2CD3\\u2CD5\\u2CD7\\u2CD9\\u2CDB\\u2CDD\\u2CDF\\u2CE1\\u2CE3\\u2CE4\\u2CEC\\u2CEE\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\uA641\\uA643\\uA645\\uA647\\uA649\\uA64B\\uA64D\\uA64F\\uA651\\uA653\\uA655\\uA657\\uA659\\uA65B\\uA65D\\uA65F\\uA661\\uA663\\uA665\\uA667\\uA669\\uA66B\\uA66D\\uA681\\uA683\\uA685\\uA687\\uA689\\uA68B\\uA68D\\uA68F\\uA691\\uA693\\uA695\\uA697\\uA723\\uA725\\uA727\\uA729\\uA72B\\uA72D\\uA72F-\\uA731\\uA733\\uA735\\uA737\\uA739\\uA73B\\uA73D\\uA73F\\uA741\\uA743\\uA745\\uA747\\uA749\\uA74B\\uA74D\\uA74F\\uA751\\uA753\\uA755\\uA757\\uA759\\uA75B\\uA75D\\uA75F\\uA761\\uA763\\uA765\\uA767\\uA769\\uA76B\\uA76D\\uA76F\\uA771-\\uA778\\uA77A\\uA77C\\uA77F\\uA781\\uA783\\uA785\\uA787\\uA78C\\uA78E\\uA791\\uA793\\uA7A1\\uA7A3\\uA7A5\\uA7A7\\uA7A9\\uA7FA\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFF41-\\uFF5A])([\\u0041-\\u005A\\u00C0-\\u00D6\\u00D8-\\u00DE\\u0100\\u0102\\u0104\\u0106\\u0108\\u010A\\u010C\\u010E\\u0110\\u0112\\u0114\\u0116\\u0118\\u011A\\u011C\\u011E\\u0120\\u0122\\u0124\\u0126\\u0128\\u012A\\u012C\\u012E\\u0130\\u0132\\u0134\\u0136\\u0139\\u013B\\u013D\\u013F\\u0141\\u0143\\u0145\\u0147\\u014A\\u014C\\u014E\\u0150\\u0152\\u0154\\u0156\\u0158\\u015A\\u015C\\u015E\\u0160\\u0162\\u0164\\u0166\\u0168\\u016A\\u016C\\u016E\\u0170\\u0172\\u0174\\u0176\\u0178\\u0179\\u017B\\u017D\\u0181\\u0182\\u0184\\u0186\\u0187\\u0189-\\u018B\\u018E-\\u0191\\u0193\\u0194\\u0196-\\u0198\\u019C\\u019D\\u019F\\u01A0\\u01A2\\u01A4\\u01A6\\u01A7\\u01A9\\u01AC\\u01AE\\u01AF\\u01B1-\\u01B3\\u01B5\\u01B7\\u01B8\\u01BC\\u01C4\\u01C7\\u01CA\\u01CD\\u01CF\\u01D1\\u01D3\\u01D5\\u01D7\\u01D9\\u01DB\\u01DE\\u01E0\\u01E2\\u01E4\\u01E6\\u01E8\\u01EA\\u01EC\\u01EE\\u01F1\\u01F4\\u01F6-\\u01F8\\u01FA\\u01FC\\u01FE\\u0200\\u0202\\u0204\\u0206\\u0208\\u020A\\u020C\\u020E\\u0210\\u0212\\u0214\\u0216\\u0218\\u021A\\u021C\\u021E\\u0220\\u0222\\u0224\\u0226\\u0228\\u022A\\u022C\\u022E\\u0230\\u0232\\u023A\\u023B\\u023D\\u023E\\u0241\\u0243-\\u0246\\u0248\\u024A\\u024C\\u024E\\u0370\\u0372\\u0376\\u0386\\u0388-\\u038A\\u038C\\u038E\\u038F\\u0391-\\u03A1\\u03A3-\\u03AB\\u03CF\\u03D2-\\u03D4\\u03D8\\u03DA\\u03DC\\u03DE\\u03E0\\u03E2\\u03E4\\u03E6\\u03E8\\u03EA\\u03EC\\u03EE\\u03F4\\u03F7\\u03F9\\u03FA\\u03FD-\\u042F\\u0460\\u0462\\u0464\\u0466\\u0468\\u046A\\u046C\\u046E\\u0470\\u0472\\u0474\\u0476\\u0478\\u047A\\u047C\\u047E\\u0480\\u048A\\u048C\\u048E\\u0490\\u0492\\u0494\\u0496\\u0498\\u049A\\u049C\\u049E\\u04A0\\u04A2\\u04A4\\u04A6\\u04A8\\u04AA\\u04AC\\u04AE\\u04B0\\u04B2\\u04B4\\u04B6\\u04B8\\u04BA\\u04BC\\u04BE\\u04C0\\u04C1\\u04C3\\u04C5\\u04C7\\u04C9\\u04CB\\u04CD\\u04D0\\u04D2\\u04D4\\u04D6\\u04D8\\u04DA\\u04DC\\u04DE\\u04E0\\u04E2\\u04E4\\u04E6\\u04E8\\u04EA\\u04EC\\u04EE\\u04F0\\u04F2\\u04F4\\u04F6\\u04F8\\u04FA\\u04FC\\u04FE\\u0500\\u0502\\u0504\\u0506\\u0508\\u050A\\u050C\\u050E\\u0510\\u0512\\u0514\\u0516\\u0518\\u051A\\u051C\\u051E\\u0520\\u0522\\u0524\\u0526\\u0531-\\u0556\\u10A0-\\u10C5\\u10C7\\u10CD\\u1E00\\u1E02\\u1E04\\u1E06\\u1E08\\u1E0A\\u1E0C\\u1E0E\\u1E10\\u1E12\\u1E14\\u1E16\\u1E18\\u1E1A\\u1E1C\\u1E1E\\u1E20\\u1E22\\u1E24\\u1E26\\u1E28\\u1E2A\\u1E2C\\u1E2E\\u1E30\\u1E32\\u1E34\\u1E36\\u1E38\\u1E3A\\u1E3C\\u1E3E\\u1E40\\u1E42\\u1E44\\u1E46\\u1E48\\u1E4A\\u1E4C\\u1E4E\\u1E50\\u1E52\\u1E54\\u1E56\\u1E58\\u1E5A\\u1E5C\\u1E5E\\u1E60\\u1E62\\u1E64\\u1E66\\u1E68\\u1E6A\\u1E6C\\u1E6E\\u1E70\\u1E72\\u1E74\\u1E76\\u1E78\\u1E7A\\u1E7C\\u1E7E\\u1E80\\u1E82\\u1E84\\u1E86\\u1E88\\u1E8A\\u1E8C\\u1E8E\\u1E90\\u1E92\\u1E94\\u1E9E\\u1EA0\\u1EA2\\u1EA4\\u1EA6\\u1EA8\\u1EAA\\u1EAC\\u1EAE\\u1EB0\\u1EB2\\u1EB4\\u1EB6\\u1EB8\\u1EBA\\u1EBC\\u1EBE\\u1EC0\\u1EC2\\u1EC4\\u1EC6\\u1EC8\\u1ECA\\u1ECC\\u1ECE\\u1ED0\\u1ED2\\u1ED4\\u1ED6\\u1ED8\\u1EDA\\u1EDC\\u1EDE\\u1EE0\\u1EE2\\u1EE4\\u1EE6\\u1EE8\\u1EEA\\u1EEC\\u1EEE\\u1EF0\\u1EF2\\u1EF4\\u1EF6\\u1EF8\\u1EFA\\u1EFC\\u1EFE\\u1F08-\\u1F0F\\u1F18-\\u1F1D\\u1F28-\\u1F2F\\u1F38-\\u1F3F\\u1F48-\\u1F4D\\u1F59\\u1F5B\\u1F5D\\u1F5F\\u1F68-\\u1F6F\\u1FB8-\\u1FBB\\u1FC8-\\u1FCB\\u1FD8-\\u1FDB\\u1FE8-\\u1FEC\\u1FF8-\\u1FFB\\u2102\\u2107\\u210B-\\u210D\\u2110-\\u2112\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u2130-\\u2133\\u213E\\u213F\\u2145\\u2183\\u2C00-\\u2C2E\\u2C60\\u2C62-\\u2C64\\u2C67\\u2C69\\u2C6B\\u2C6D-\\u2C70\\u2C72\\u2C75\\u2C7E-\\u2C80\\u2C82\\u2C84\\u2C86\\u2C88\\u2C8A\\u2C8C\\u2C8E\\u2C90\\u2C92\\u2C94\\u2C96\\u2C98\\u2C9A\\u2C9C\\u2C9E\\u2CA0\\u2CA2\\u2CA4\\u2CA6\\u2CA8\\u2CAA\\u2CAC\\u2CAE\\u2CB0\\u2CB2\\u2CB4\\u2CB6\\u2CB8\\u2CBA\\u2CBC\\u2CBE\\u2CC0\\u2CC2\\u2CC4\\u2CC6\\u2CC8\\u2CCA\\u2CCC\\u2CCE\\u2CD0\\u2CD2\\u2CD4\\u2CD6\\u2CD8\\u2CDA\\u2CDC\\u2CDE\\u2CE0\\u2CE2\\u2CEB\\u2CED\\u2CF2\\uA640\\uA642\\uA644\\uA646\\uA648\\uA64A\\uA64C\\uA64E\\uA650\\uA652\\uA654\\uA656\\uA658\\uA65A\\uA65C\\uA65E\\uA660\\uA662\\uA664\\uA666\\uA668\\uA66A\\uA66C\\uA680\\uA682\\uA684\\uA686\\uA688\\uA68A\\uA68C\\uA68E\\uA690\\uA692\\uA694\\uA696\\uA722\\uA724\\uA726\\uA728\\uA72A\\uA72C\\uA72E\\uA732\\uA734\\uA736\\uA738\\uA73A\\uA73C\\uA73E\\uA740\\uA742\\uA744\\uA746\\uA748\\uA74A\\uA74C\\uA74E\\uA750\\uA752\\uA754\\uA756\\uA758\\uA75A\\uA75C\\uA75E\\uA760\\uA762\\uA764\\uA766\\uA768\\uA76A\\uA76C\\uA76E\\uA779\\uA77B\\uA77D\\uA77E\\uA780\\uA782\\uA784\\uA786\\uA78B\\uA78D\\uA790\\uA792\\uA7A0\\uA7A2\\uA7A4\\uA7A6\\uA7A8\\uA7AA\\uFF21-\\uFF3A\\u0030-\\u0039\\u00B2\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D66-\\u0D75\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19])/g\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/sentence-case/vendor/camel-case-regexp.js\n ** module id = 394\n ** module chunks = 0\n **/","module.exports = /([\\u0030-\\u0039\\u00B2\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D66-\\u0D75\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19])([^\\u0030-\\u0039\\u00B2\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D66-\\u0D75\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19])/g\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/sentence-case/vendor/trailing-digit-regexp.js\n ** module id = 395\n ** module chunks = 0\n **/","var upperCase = require('upper-case')\nvar lowerCase = require('lower-case')\n\n/**\n * Swap the case of a string. Manually iterate over every character and check\n * instead of replacing certain characters for better unicode support.\n *\n * @param  {String} str\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  if (str == null) {\n    return ''\n  }\n\n  var result = ''\n\n  for (var i = 0; i < str.length; i++) {\n    var c = str[i]\n    var u = upperCase(c, locale)\n\n    result += u === c ? lowerCase(c, locale) : u\n  }\n\n  return result\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/swap-case/swap-case.js\n ** module id = 396\n ** module chunks = 0\n **/","/**\n * Special language-specific overrides.\n *\n * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt\n *\n * @type {Object}\n */\nvar LANGUAGES = {\n  tr: {\n    regexp: /[\\u0069]/g,\n    map: {\n      '\\u0069': '\\u0130'\n    }\n  },\n  az: {\n    regexp: /[\\u0069]/g,\n    map: {\n      '\\u0069': '\\u0130'\n    }\n  },\n  lt: {\n    regexp: /[\\u0069\\u006A\\u012F]\\u0307|\\u0069\\u0307[\\u0300\\u0301\\u0303]/g,\n    map: {\n      '\\u0069\\u0307': '\\u0049',\n      '\\u006A\\u0307': '\\u004A',\n      '\\u012F\\u0307': '\\u012E',\n      '\\u0069\\u0307\\u0300': '\\u00CC',\n      '\\u0069\\u0307\\u0301': '\\u00CD',\n      '\\u0069\\u0307\\u0303': '\\u0128'\n    }\n  }\n}\n\n/**\n * Upper case a string.\n *\n * @param  {String} str\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  var lang = LANGUAGES[locale]\n\n  str = str == null ? '' : String(str)\n\n  if (lang) {\n    str = str.replace(lang.regexp, function (m) { return lang.map[m] })\n  }\n\n  return str.toUpperCase()\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/upper-case/upper-case.js\n ** module id = 397\n ** module chunks = 0\n **/","var sentenceCase = require('sentence-case');\n\n/**\n * Path case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (string, locale) {\n  return sentenceCase(string, locale, '/');\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/path-case/path-case.js\n ** module id = 398\n ** module chunks = 0\n **/","var upperCase = require('upper-case')\nvar sentenceCase = require('sentence-case')\n\n/**\n * Camel case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (string, locale, mergeNumbers) {\n  var result = sentenceCase(string, locale)\n\n  // Replace periods between numeric entities with an underscore.\n  if (!mergeNumbers) {\n    result = result.replace(/(\\d) (?=\\d)/g, '$1_')\n  }\n\n  // Replace spaces between words with an upper cased character.\n  return result.replace(/ (.)/g, function (m, $1) {\n    return upperCase($1, locale)\n  })\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/camel-case/camel-case.js\n ** module id = 399\n ** module chunks = 0\n **/","var sentenceCase = require('sentence-case');\n\n/**\n * Snake case a string.\n *\n * @param  {String} str\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  return sentenceCase(str, locale, '_');\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/snake-case/snake-case.js\n ** module id = 400\n ** module chunks = 0\n **/","var upperCase = require('upper-case')\nvar sentenceCase = require('sentence-case')\n\n/**\n * Title case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  return sentenceCase(str, locale).replace(/^.| ./g, function (m) {\n    return upperCase(m, locale)\n  })\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/title-case/title-case.js\n ** module id = 401\n ** module chunks = 0\n **/","var sentenceCase = require('sentence-case');\n\n/**\n * Param case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (string, locale) {\n  return sentenceCase(string, locale, '-');\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/param-case/param-case.js\n ** module id = 402\n ** module chunks = 0\n **/","var camelCase = require('camel-case')\nvar upperCaseFirst = require('upper-case-first')\n\n/**\n * Pascal case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (string, locale) {\n  return upperCaseFirst(camelCase(string, locale), locale)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/pascal-case/pascal-case.js\n ** module id = 403\n ** module chunks = 0\n **/","var upperCase = require('upper-case')\n\n/**\n * Upper case the first character of a string.\n *\n * @param  {String} str\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  if (str == null) {\n    return ''\n  }\n\n  str = String(str)\n\n  return upperCase(str.charAt(0), locale) + str.substr(1)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/upper-case-first/upper-case-first.js\n ** module id = 404\n ** module chunks = 0\n **/","var upperCase = require('upper-case')\nvar snakeCase = require('snake-case')\n\n/**\n * Constant case a string.\n *\n * @param  {String} string\n * @param  {String} [locale]\n * @return {String}\n */\nmodule.exports = function (string, locale) {\n  return upperCase(snakeCase(string, locale), locale)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/constant-case/constant-case.js\n ** module id = 405\n ** module chunks = 0\n **/","var upperCase = require('upper-case')\n\n/**\n * Check if a string is upper case.\n *\n * @param  {String}  string\n * @param  {String}  [locale]\n * @return {Boolean}\n */\nmodule.exports = function (string, locale) {\n  return upperCase(string, locale) === string\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/is-upper-case/is-upper-case.js\n ** module id = 406\n ** module chunks = 0\n **/","var lowerCase = require('lower-case')\n\n/**\n * Check if a string is lower case.\n *\n * @param  {String}  string\n * @param  {String}  [locale]\n * @return {Boolean}\n */\nmodule.exports = function (string, locale) {\n  return lowerCase(string, locale) === string\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/is-lower-case/is-lower-case.js\n ** module id = 407\n ** module chunks = 0\n **/","var lowerCase = require('lower-case')\n\n/**\n * Lower case the first character of a string.\n *\n * @param  {String} str\n * @return {String}\n */\nmodule.exports = function (str, locale) {\n  if (str == null) {\n    return ''\n  }\n\n  str = String(str)\n\n  return lowerCase(str.charAt(0), locale) + str.substr(1)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/change-case/~/lower-case-first/lower-case-first.js\n ** module id = 408\n ** module chunks = 0\n **/","module.exports = {\n\t\"nsd\": {\n\t\t\"name\": \"nsd\",\n\t\t\"type\": \"list\",\n\t\t\"cardinality\": \"0..N\",\n\t\t\"properties\": [\n\t\t\t{\n\t\t\t\t\"name\": \"id\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Identifier for the NSD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"NSD name.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"NSD short name.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vendor\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Vendor of the NSD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"description\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Description of the NSD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"version\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Version of the NSD\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"connection-point\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List for external connection points. Each NS has one or more external connection points. As the name implies that external connection points are used for connecting the NS to other NS or to external networks. Each NS exposes these connection points to the orchestrator. The orchestrator can construct network service chains by connecting the connection points between different NS.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Name of the NS connection point.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": \"VPORT\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"name\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vld\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of Virtual Link Descriptors.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Identifier for the VLD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Virtual Link Descriptor (VLD) name.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Short name for VLD for UI\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vendor\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Provider of the VLD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Description of the VLD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"version\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Version of the VLD\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": \"ELAN\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"root-bandwidth\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"For ELAN this is the aggregate bandwidth.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"leaf-bandwidth\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"For ELAN this is the bandwidth of branches.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"A list of references to connection points.\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"member-vnf-index-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Reference to member-vnf within constituent-vnfds\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\"path\": \"../../../nsd:constituent-vnfd/nsd:member-vnf-index\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vnfd-id-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"A reference to a vnfd. This is a leafref to path: ../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"member-vnf-index-ref\"\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"provider-network\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"description\": \"Container for the provider network.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the provider network.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"physical-network\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the phsyical network on which the provider network is built.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"overlay-type\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Type of the overlay network.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"LOCAL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"FLAT\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"VLAN\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"VXLAN\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"GRE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"segmentation_id\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Segmentation ID\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint32\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"id\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"constituent-vnfd\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of VNFDs that are part of this network service.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"member-vnf-index\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Identifier/index for the VNFD. This separate id is required to ensure that multiple VNFs can be part of single NS\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnfd-id-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Identifier for the VNFD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnf-configuration\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"description\": \"Information regarding the VNF configuration is captured here. Note that if the NS contains multiple instances of the same VNF, each instance of the VNF may have different configuration\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"config-type\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Must use this configuration type and fill in only pertaining config-method below\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"none\": null,\n\t\t\t\t\t\t\t\t\t\t\t\"netconf\": null,\n\t\t\t\t\t\t\t\t\t\t\t\"rest\": null,\n\t\t\t\t\t\t\t\t\t\t\t\"script\": null,\n\t\t\t\t\t\t\t\t\t\t\t\"juju\": null\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"config-template\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Configuration template for each VNF\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"config-method\",\n\t\t\t\t\t\t\t\t\"type\": \"choice\",\n\t\t\t\t\t\t\t\t\"description\": \"Defines the configuration method for the VNF.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"netconf\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Use NETCONF for configuring the VNF.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"netconf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"target\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Netconf configuration target\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"running\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"candidate\": null\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"protocol\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Protocol to use for netconf (e.g. ssh)\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"None\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"ssh\": null\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"port\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"rest\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Use REST for configuring the VNF.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"rest\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"port\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"script\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Use custom script for configuring the VNF. This script is executed in the context of Orchestrator.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"script\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"script-type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Script type - currently supported : bash, expect\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"bash\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"expect\": null\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"juju\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Configure the VNF through Juju.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"juju\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"charm\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Juju charm to use with the VNF.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"config-access\",\n\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"mgmt-ip-address\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"union\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv4-address\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv6-address\": null\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"username\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"username for configuration.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"password\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Password for configuration access authentication.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"input-params\",\n\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\"description\": \"Miscelaneous input parameters to be considered while processing the NSD to apply configuration\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"config-priority\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Configuration priority - order of confgiration to be applied to each VNF in this NS, low number gets precedence over high number\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"config-delay\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Wait (seconds) before applying the configuration to VNF\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"config-primitive\",\n\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\"description\": \"List of configuration primitives supported by the configuration agent for this VNF.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Name of the configuration primitive.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"parameter\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"List of parameters to the configuration primitive.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Name of the parameter.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"data-type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Data type associated with the name.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"string\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"integer\": null\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\t\t\"name\"\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\"name\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"initial-config-primitive\",\n\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\"description\": \"Initial set of configuration primitives.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"seq\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Sequence number for the configuration primitive.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Name of the configuration primitive.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"parameter\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"value\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\t\t\"name\"\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\"seq\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"member-vnf-index\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vnf-dependency\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of VNF dependencies.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnf-source-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnf-depends-on-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Reference to VNF that sorce VNF depends.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"vnf-source-ref\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vnffgd\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of VNF Forwarding Graph Descriptors (VNFFGD).\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Identifier for the VNFFGD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"VNFFGD name.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Short name for VNFFGD for UI\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vendor\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Provider of the VNFFGD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Description of the VNFFGD.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"version\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Version of the VNFFGD\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"rsp\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"List of Rendered Service Paths (RSP).\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Identifier for the RSP.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"RSP name.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\"description\": \"A list of references to connection points.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"member-vnf-index-ref\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Reference to member-vnf within constituent-vnfds\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"path\": \"../../../../nsd:constituent-vnfd/nsd:member-vnf-index\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"vnfd-id-ref\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"A reference to a vnfd. This is a leafref to path: ../../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\"member-vnf-index-ref\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"classifier\",\n\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\"description\": \"List of classifier rules.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Identifier for the classifier rule.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Name of the classifier.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"rsp-id-ref\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"A reference to the RSP.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"path\": \"../../nsd:rsp/nsd:id\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"match-attributes\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"List of match attributes.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"ip-proto\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"IP Protocol.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"source-ip-address\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"union\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv4-address\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv6-address\": null\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"destination-ip-address\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"union\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv4-address\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv6-address\": null\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"source-port\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"destination-port\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\"id\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"id\"\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"id\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"config-primitive\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"Network service level configuration primitives.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Name of the configuration primitive.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"user-defined-script\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A user defined script.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnf-primitive-group\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"List of configuration primitives grouped by VNF.\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"member-vnf-index-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Reference to member-vnf within constituent-vnfds\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vnfd-id-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"A reference to a vnfd. This is a leafref to path: ../../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vnfd-name\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the VNFD\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"primitive\",\n\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\"name\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"member-vnf-index-ref\"\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"name\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"http-endpoint\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of http endpoints to be used by monitoring params\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"path\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP path on the management server\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"https\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Pick HTTPS instead of HTTP , Default is false\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"boolean\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"port\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"username\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP basic auth username\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"password\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP basic auth password\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"polling_interval_secs\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP polling interval in seconds\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"method\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of HTTP operation\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"POST\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"PUT\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"GET\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"DELETE\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"OPTIONS\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"PATCH\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 5\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"headers\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"Custom HTTP headers to put on HTTP request\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"key\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"HTTP header key\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"value\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"HTTP header value\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"key\"\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"path\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"monitoring-param\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of monitoring parameters at the NS level\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"http-endpoint-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"../../http-endpoint/path\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"json-query-method\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The method to extract a value from a JSON response NAMEKEY - Use the name as the key for a non-nested value. JSONPATH - Use jsonpath-rw implemenation to extract a value. OBJECTPATH - Use objectpath implemenation to extract a value.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"NAMEKEY\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"JSONPATH\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"OBJECTPATH\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"group-tag\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A simple tag to group monitoring parameters\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The type of the parameter value\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"INT\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"DECIMAL\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"STRING\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-integer\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Current value for an integer parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"int64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-decimal\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Current value for a decimal parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"decimal64\": {\n\t\t\t\t\t\t\t\t\"fraction-digits\": \"4\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-string\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Current value for a string parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"widget-type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of the widget, typically used by the UI.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"HISTOGRAM\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"BAR\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"GAUGE\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"SLIDER\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"COUNTER\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"TEXTBOX\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 5\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"units\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"json-query-params\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"json-path\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"The jsonpath to use to extract value from JSON structure\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"object-path\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"The objectpath to use to extract value from JSON structure\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"numeric-constraints\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"min-value\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Minimum value for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"max-value\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Maxium value for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"text-constraints\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"min-length\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Minimum string length for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"max-length\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Maximum string length for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"id\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"input-parameters\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of input parameters\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"uuid\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"An identifier that uniquely identifies an input parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"xpath\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A an xpath that specfies which element in a descriptor is to be modified.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"uuid\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"input-parameter-xpath\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of xpaths to parameters inside the NSD the can be customized during the instantiation.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"xpath\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"An xpath that specifies the element in a descriptor.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"xpath\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\t\"key\": [\n\t\t\t\"id\"\n\t\t]\n\t},\n\t\"vnfd\": {\n\t\t\"name\": \"vnfd\",\n\t\t\"type\": \"list\",\n\t\t\"cardinality\": \"0..N\",\n\t\t\"properties\": [\n\t\t\t{\n\t\t\t\t\"name\": \"id\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Identifier for the VNFD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"VNFD name.\",\n\t\t\t\t\"cardinality\": \"1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"VNFD short name.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vendor\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Vendor of the VNFD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"description\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Description of the VNFD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"version\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Version of the VNFD\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"mgmt-interface\",\n\t\t\t\t\"type\": \"container\",\n\t\t\t\t\"description\": \"Interface over which the VNF is managed.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"endpoint-type\",\n\t\t\t\t\t\t\"type\": \"choice\",\n\t\t\t\t\t\t\"description\": \"Indicates the type of management endpoint.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"ip\",\n\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\"description\": \"Specifies the static IP address for managing the VNF.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"ip-address\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"union\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv4-address\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"inet:ipv6-address\": null\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vdu-id\",\n\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\"description\": \"Use the default management interface on this VDU.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"vdu-id\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cp\",\n\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\"description\": \"Use the ip address associated with this connection point.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"cp\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"interface-type\",\n\t\t\t\t\t\t\"type\": \"choice\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"netconf\",\n\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"netconf\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"empty\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"port\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"dashboard-params\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"description\": \"Parameters for the VNF dashboard\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"path\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"The HTTP path for the dashboard\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"https\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Pick HTTPS instead of HTTP , Default is false\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"boolean\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"port\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"internal-vld\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of Internal Virtual Link Descriptors (VLD). The internal VLD describes the basic topology of the connectivity (e.g. E-LAN, E-Line, E-Tree) between internal VNF components of the system.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Identifier for the VLD\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Name of the internal VLD\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Short name of the internal VLD\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": \"ELAN\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"root-bandwidth\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"For ELAN this is the aggregate bandwidth.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"leaf-bandwidth\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"For ELAN this is the bandwidth of branches.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"provider-network\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"description\": \"Container for the provider network.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the provider network.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"physical-network\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the phsyical network on which the provider network is built.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"overlay-type\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Type of the overlay network.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"LOCAL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"FLAT\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"VLAN\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"VXLAN\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"GRE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"segmentation_id\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Segmentation ID\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint32\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"id\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"connection-point\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List for external connection points. Each VNF has one or more external connection points. As the name implies that external connection points are used for connecting the VNF to other VNFs or to external networks. Each VNF exposes these connection points to the orchestrator. The orchestrator can construct network services by connecting the connection points between different VNFs. The NFVO will use VLDs and VNFFGs at the network service level to construct network services.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Name of the connection point\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Short name of the connection point\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": \"VPORT\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"name\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vdu\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of Virtual Deployment Units\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Unique id for the VDU\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Unique name for the VDU\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Description of the VDU.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"count\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Number of instances of VDU\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"mgmt-vpci\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"image\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Image name for the software image. If the image name is found within the VNF packaage it will be uploaded to all cloud accounts during onboarding process. Otherwise, the image must be added to the cloud account with the same name as entered here. \",\n\t\t\t\t\t\t\"cardinality\": \"1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"cloud-init\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Content of cloud-init script\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"internal-connection-point\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"List for internal connection points. Each VNFC has zero or more internal connection points. Internal connection points are used for connecting the VNF components internal to the VNF. If a VNF has only one VNFC, it may not have any internal connection points.\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Identifier for the internal connection points\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": \"VPORT\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"internal-vld-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\"path\": \"../../../internal-vld/id\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"id\"\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"internal-interface\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"List of internal interfaces for the VNF\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of internal interface. Note that this name has only local significance to the VDU.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vdu-internal-connection-point-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\"path\": \"../../internal-connection-point/id\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"virtual-interface\",\n\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\"description\": \"Container for the virtual interface properties\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Specifies the type of virtual interface between VM and host. VIRTIO : Use the traditional VIRTIO interface. PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface. SR-IOV : Use SR-IOV interface. OM-MGMT : Used to specify openmano mgmt external-connection type\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"OM-MGMT\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"PCI-PASSTHROUGH\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"SR-IOV\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"VIRTIO\": null\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"vpci\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"bandwidth\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Aggregate bandwidth of the NIC.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"name\"\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"external-interface\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"List of external interfaces for the VNF. The external interfaces enable sending traffic to and from VNF.\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the external interface. Note that this name has only local significance.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Name of the external connection point.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\t\t\"path\": \"../../../connection-point/name\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"virtual-interface\",\n\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\"description\": \"Container for the virtual interface properties\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Specifies the type of virtual interface between VM and host. VIRTIO : Use the traditional VIRTIO interface. PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface. SR-IOV : Use SR-IOV interface. OM-MGMT : Used to specify openmano mgmt external-connection type\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"OM-MGMT\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"PCI-PASSTHROUGH\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"SR-IOV\": null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"VIRTIO\": null\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"vpci\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"bandwidth\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Aggregate bandwidth of the NIC.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"name\"\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vm-flavor\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"vcpu-count\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Number of vcpus for the VM.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint16\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"memory-mb\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Amount of memory in MB.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"storage-gb\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Amount of disk space in GB.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"guest-epa\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"trusted-execution\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"This VM should be allocated from trusted pool\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"boolean\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"mempage-size\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Memory page allocation size. If a VM requires hugepages, it should choose LARGE or SIZE_2MB or SIZE_1GB. If the VM prefers hugepages it should chose PREFER_LARGE. LARGE : Require hugepages (either 2MB or 1GB) SMALL : Doesn't require hugepages SIZE_2MB : Requires 2MB hugepages SIZE_1GB : Requires 1GB hugepages PREFER_LARGE : Application perfers hugepages\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"LARGE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"SMALL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"SIZE_2MB\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"SIZE_1GB\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_LARGE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-pinning-policy\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"CPU pinning policy describes association between virtual CPUs in guest and the physical CPUs in the host. DEDICATED : Virtual CPUs are pinned to physical CPUs SHARED : Multiple VMs may share the same physical CPUs. ANY : Any policy is acceptable for the VM\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"DEDICATED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"SHARED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"ANY\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-thread-pinning-policy\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"CPU thread pinning policy describes how to place the guest CPUs when the host supports hyper threads: AVOID : Avoids placing a guest on a host with threads. SEPARATE: Places vCPUs on separate cores, and avoids placing two vCPUs on two threads of same core. ISOLATE : Places each vCPU on a different core, and places no vCPUs from a different guest on the same core. PREFER : Attempts to place vCPUs on threads of the same core.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"AVOID\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"SEPARATE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"ISOLATE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"pcie-device\",\n\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\"description\": \"List of pcie passthrough devices.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"device-id\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Device identifier.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"count\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Number of devices to attach to the VM.\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\"device-id\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"numa-policy\",\n\t\t\t\t\t\t\t\t\"type\": \"choice\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"numa-unware\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"numa-unware\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"empty\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"numa-aware\",\n\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"numa-node-policy\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"This policy defines numa topology of the guest. Specifically identifies if the guest should be run on a host with one numa node or multiple numa nodes. As an example a guest may want 8 vcpus and 4 GB of memory. But may want the vcpus and memory distributed across multiple numa nodes. The NUMA node 1 may run with 6 vcpus and 3GB, and NUMA node 2 may run with 2 vcpus and 1GB.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"node-cnt\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"The number of numa nodes to expose to the VM.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint16\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"mem-policy\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"This policy specifies how the memory should be allocated in a multi-node scenario. STRICT : The memory must be allocated strictly from the memory attached to the NUMA node. PREFERRED : The memory should be allocated perferentially from the memory attached to the NUMA node\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"STRICT\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"PREFERRED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"node\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"NUMA node identification. Typically it's 0 or 1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"memory-mb\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Memory size expressed in MB for this NUMA node.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"om-numa-type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"choice\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Openmano Numa type selection\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"cores\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"num-cores\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"paired-threads\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"paired-threads\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"num-paired-threads\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"paired-thread-ids\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"List of thread pairs to use in case of paired-thread numa\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..16\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"thread-a\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"thread-b\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"thread-a\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"threads\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"case\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\": \"num-threads\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"id\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vswitch-epa\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"ovs-acceleration\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Specifies Open vSwitch acceleration mode. MANDATORY: OVS acceleration is required PREFERRED: OVS acceleration is preferred\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"MANDATORY\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFERRED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"DISABLED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"ovs-offload\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Specifies Open vSwitch hardware offload mode. MANDATORY: OVS offload is required PREFERRED: OVS offload is preferred\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"MANDATORY\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFERRED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"DISABLED\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"hypervisor-epa\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Specifies the type of hypervisor. KVM: KVM XEN: XEN\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_KVM\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_KVM\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"version\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"host-epa\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"description\": \"Specifies the host level EPA attributes.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-model\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Host CPU model. Examples include: SandyBridge, IvyBridge\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_WESTMERE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_WESTMERE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_SANDYBRIDGE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_SANDYBRIDGE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_IVYBRIDGE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_IVYBRIDGE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 5\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_HASWELL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 6\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_HASWELL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 7\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_BROADWELL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 8\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_BROADWELL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 9\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_NEHALEM\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 10\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_NEHALEM\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 11\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_PENRYN\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 12\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_PENRYN\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 13\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_CONROE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 14\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_CONROE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 15\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_CORE2DUO\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 16\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_CORE2DUO\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 17\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-arch\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Host CPU architecture.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_X86\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_X86\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_X86_64\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_X86_64\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_I686\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_I686\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 5\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_IA64\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 6\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_IA64\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 7\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_ARMV7\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 8\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_ARMV7\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 9\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_ARMV8\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 10\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_ARMV8\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 11\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-vendor\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Host CPU Vendor.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_INTEL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_INTEL\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_AMD\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_AMD\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-socket-count\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Number of sockets on the host.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_ONE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"PREFER_TWO\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_ONE\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"REQUIRE_TWO\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"cpu-core-count\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Number of cores on the host.\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"om-cpu-model-string\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Openmano CPU model string\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"id\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vdu-dependency\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of VDU dependencies.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vdu-source-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"../../vdu/id\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vdu-depends-on-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Reference to the VDU that source VDU depends.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"../../vdu/id\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"vdu-source-ref\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"http-endpoint\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of http endpoints to be used by monitoring params\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"path\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP path on the management server\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"https\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Pick HTTPS instead of HTTP , Default is false\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"boolean\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"port\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"uint16\": {\n\t\t\t\t\t\t\t\t\"range\": \"0..65535\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"username\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP basic auth username\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"password\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP basic auth password\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"polling_interval_secs\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The HTTP polling interval in seconds\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"method\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of HTTP operation\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"POST\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"PUT\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"GET\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"DELETE\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"OPTIONS\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"PATCH\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 5\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"headers\",\n\t\t\t\t\t\t\"type\": \"list\",\n\t\t\t\t\t\t\"description\": \"Custom HTTP headers to put on HTTP request\",\n\t\t\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"key\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"HTTP header key\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"value\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"HTTP header value\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"key\": [\n\t\t\t\t\t\t\t\"key\"\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"path\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"monitoring-param\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"List of monitoring parameters at the NS level\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"http-endpoint-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"../../http-endpoint/path\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"json-query-method\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The method to extract a value from a JSON response NAMEKEY - Use the name as the key for a non-nested value. JSONPATH - Use jsonpath-rw implemenation to extract a value. OBJECTPATH - Use objectpath implemenation to extract a value.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"NAMEKEY\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"JSONPATH\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"OBJECTPATH\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"group-tag\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A simple tag to group monitoring parameters\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"The type of the parameter value\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"INT\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"DECIMAL\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"STRING\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-integer\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Current value for an integer parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"int64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-decimal\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Current value for a decimal parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"decimal64\": {\n\t\t\t\t\t\t\t\t\"fraction-digits\": \"4\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"value-string\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Current value for a string parameter\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"widget-type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of the widget, typically used by the UI.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"HISTOGRAM\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"BAR\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"GAUGE\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"SLIDER\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"COUNTER\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"TEXTBOX\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 5\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"units\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"json-query-params\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"json-path\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"The jsonpath to use to extract value from JSON structure\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"object-path\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"The objectpath to use to extract value from JSON structure\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"numeric-constraints\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"min-value\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Minimum value for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"max-value\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Maxium value for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"text-constraints\",\n\t\t\t\t\t\t\"type\": \"container\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"properties\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"min-length\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Minimum string length for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"name\": \"max-length\",\n\t\t\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\t\t\"description\": \"Maximum string length for the parameter\",\n\t\t\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\t\t\"data-type\": \"uint8\",\n\t\t\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"id\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\t\"key\": [\n\t\t\t\"id\"\n\t\t]\n\t},\n\t\"vld\": {\n\t\t\"name\": \"vld\",\n\t\t\"type\": \"list\",\n\t\t\"cardinality\": \"0..N\",\n\t\t\"properties\": [\n\t\t\t{\n\t\t\t\t\"name\": \"id\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Identifier for the VLD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Virtual Link Descriptor (VLD) name.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"short-name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Short name for VLD for UI\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vendor\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Provider of the VLD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"description\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Description of the VLD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"version\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Version of the VLD\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"type\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": {\n\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\"enum\": \"ELAN\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"root-bandwidth\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"For ELAN this is the aggregate bandwidth.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"leaf-bandwidth\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"For ELAN this is the bandwidth of branches.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\"type\": \"list\",\n\t\t\t\t\"description\": \"A list of references to connection points.\",\n\t\t\t\t\"cardinality\": \"0..N\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnfd-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A reference to a vnfd\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"member-vnf-index-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A reference to the consituent-vnfd id in nsd. Should have been a leafref to: '/nsd:nsd-catalog:/nsd:nsd/constituent-vnfd/member-vnf-index-ref'. Instead using direct leaf to avoid circular reference.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint64\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"vnfd-connection-point-ref\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"A reference to a connection point name in a vnfd\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"leafref\": {\n\t\t\t\t\t\t\t\t\"path\": \"/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id = current()/../vld:vnfd-ref]/vnfd:connection-point/vnfd:name\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"key\": [\n\t\t\t\t\t\"vnfd-ref\",\n\t\t\t\t\t\"member-vnf-index-ref\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"provider-network\",\n\t\t\t\t\"type\": \"container\",\n\t\t\t\t\"description\": \"Container for the provider network.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"properties\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Name of the provider network.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"physical-network\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Name of the phsyical network on which the provider network is built.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"overlay-type\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Type of the overlay network.\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": {\n\t\t\t\t\t\t\t\"enumeration\": {\n\t\t\t\t\t\t\t\t\"enum\": {\n\t\t\t\t\t\t\t\t\t\"LOCAL\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 0\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"FLAT\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 1\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"VLAN\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 2\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"VXLAN\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 3\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"GRE\": {\n\t\t\t\t\t\t\t\t\t\t\"value\": 4\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"segmentation_id\",\n\t\t\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\t\t\"description\": \"Segmentation ID\",\n\t\t\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\t\t\"data-type\": \"uint32\",\n\t\t\t\t\t\t\"properties\": []\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\t\"key\": [\n\t\t\t\"id\"\n\t\t]\n\t},\n\t\"vnffgd\": {\n\t\t\"name\": \"vnffgd\",\n\t\t\"type\": \"list\",\n\t\t\"cardinality\": \"0..N\",\n\t\t\"properties\": [\n\t\t\t{\n\t\t\t\t\"name\": \"name\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"VNF Forwarding Graph Descriptor name.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"id\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Identifier for the VNFFGD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"yang:uuid\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"provider\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Provider of the VNFFGD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"description\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Description of the VNFFGD.\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"name\": \"version\",\n\t\t\t\t\"type\": \"leaf\",\n\t\t\t\t\"description\": \"Version of the VNFFGD\",\n\t\t\t\t\"cardinality\": \"0..1\",\n\t\t\t\t\"data-type\": \"string\",\n\t\t\t\t\"properties\": []\n\t\t\t}\n\t\t],\n\t\t\"key\": [\n\t\t\t\"id\"\n\t\t]\n\t}\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/json-loader!./src/libraries/model/DescriptorModelMeta.json\n ** module id = 409\n ** module chunks = 0\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 1/27/16.\n *\n * This class provides utility methods for interrogating an instance of model meta object.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport guid from './../guid'\nimport changeCase from 'change-case'\nimport InstanceCounter from './../InstanceCounter'\nimport DescriptorModelFields from './DescriptorModelFields'\nimport DescriptorTemplateFactory from './DescriptorTemplateFactory'\n\nexport default {\n\tisLeaf(property = {}) {\n\t\treturn /leaf|choice/.test(property.type);\n\t},\n\tisArray(property = {}) {\n\t\t// give '1' or '0..N' or '0..1' or '0..5' determine if represents an array\n\t\t// '0..1' is not an array\n\t\t// '0..2' is an array\n\t\t// '0..N' is an array\n\t\tconst cardinality = String(property.cardinality).toUpperCase();\n\t\tconst pos = cardinality.lastIndexOf('.') + 1;\n\t\tconst val = cardinality.substr(pos);\n\t\treturn val === 'N' || parseInt(val, 10) > 1;\n\t},\n\tisEnumeration(property = {}) {\n\t\tconst type = property['data-type'] || {};\n\t\treturn type.hasOwnProperty('enumeration');\n\t},\n\tisRequired(property = {}) {\n\t\treturn /^1/.test(property.cardinality);\n\t},\n\tisObject(property = {}) {\n\t\treturn !/^(leaf|leaf-list)$/.test(property.type);\n\t},\n\tisSimpleList(property = {}) {\n\t\treturn _.contains(DescriptorModelFields.simpleList, property.name);\n\t},\n\tdefaultValue(property = {}) {\n\t\tif (property.defaultValue) {\n\t\t\treturn property.defaultValue;\n\t\t}\n\t\tif (this.isObject(property)) {\n\t\t\treturn {};\n\t\t}\n\t\treturn '';\n\t},\n\tgetContainerMethod(property, container, methodName) {\n\t\tconst name = changeCase.camel(methodName + '-' + property.name);\n\t\tif (typeof container[name] === 'function') {\n\t\t\treturn container[name].bind(container);\n\t\t}\n\t},\n\tgetContainerCreateMethod(property, container) {\n\t\tconst name = changeCase.camel('create-' + property.name);\n\t\tif (typeof container[name] === 'function') {\n\t\t\treturn container[name].bind(container);\n\t\t}\n\t},\n\tcontainerHasCreateMethod(container, property = {}) {\n\t\tconst find = changeCase.camel('create-' + property.name);\n\t\treturn typeof container[find] === 'function';\n\t},\n\tgetEnumeration(property = {}, value) {\n\t\tconst enumeration = property['data-type'].enumeration.enum;\n\t\tif (typeof enumeration === 'string') {\n\t\t\treturn [{name: enumeration, value: enumeration, isSelected: String(value) === enumeration}];\n\t\t}\n\t\treturn Object.keys(enumeration).map(enumName => {\n\t\t\tlet enumValue = enumName;\n\t\t\tconst enumObj = enumeration[enumName];\n\t\t\tif (enumObj) {\n\t\t\t\tenumValue = enumObj.value || enumName;\n\t\t\t}\n\t\t\treturn {name: enumName, value: enumValue, isSelected: String(enumValue) === String(value)};\n\t\t});\n\t},\n\tcreateModelInstance(property) {\n\t\tconst defaultValue = this.defaultValue.bind(this);\n\t\tfunction createModel(meta, parentMeta) {\n\t\t\tconst model = {};\n\t\t\tif (meta.type === 'list') {\n\t\t\t\treturn [];\n\t\t\t} else if (meta.type === 'leaf') {\n\t\t\t\tif (meta.name === 'name') {\n\t\t\t\t\treturn changeCase.param(parentMeta.name) + '-' + InstanceCounter.count(parentMeta[':qualified-type']);\n\t\t\t\t}\n\t\t\t\tif (_.isArray(parentMeta.key) && _.contains(parentMeta.key, meta.name)) {\n\t\t\t\t\tif (/uuid/.test(meta['data-type'])) {\n\t\t\t\t\t\treturn guid();\n\t\t\t\t\t}\n\t\t\t\t\tif (meta['data-type'] === 'string') {\n\t\t\t\t\t\tconst prefix = meta.name.replace('id', '');\n\t\t\t\t\t\treturn  (prefix ? changeCase.param(prefix) + '-' : '') + guid(5);\n\t\t\t\t\t}\n\t\t\t\t\tif (/int/.test(meta['data-type'])) {\n\t\t\t\t\t\treturn InstanceCounter.count(meta[':qualified-type']);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn defaultValue(meta);\n\t\t\t} else {\n\t\t\t\tmeta.properties.forEach(p => {\n\t\t\t\t\tmodel[p.name] = createModel(p, meta);\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn model;\n\t\t}\n\t\tif (property) {\n\t\t\tif (property.type === 'leaf') {\n\t\t\t\treturn defaultValue(property);\n\t\t\t}\n\t\t\tif (property.type === 'list') {\n\t\t\t\tproperty.type = 'container';\n\t\t\t}\n\t\t\tconst modelInstance = createModel(property, property);\n\t\t\tmodelInstance.meta = {type: property.name};\n\t\t\tconst modelFragment = DescriptorTemplateFactory.createModelForType(property.name) || {};\n\t\t\tObject.assign(modelInstance, modelFragment);\n\t\t\treturn modelInstance;\n\t\t}\n\t}\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorModelMetaProperty.js\n **/","/**\n * Created by onvelocity on 1/28/16.\n */\n\nfunction getInstanceCount(type, bump = true) {\n\t// keep a global counter\n\tlet count = 0;\n\tconst data = sessionStorage.getItem('instance-counts');\n\tconst counts = JSON.parse(data || '{}');\n\tif (counts.hasOwnProperty(type)) {\n\t\tcount = counts[type];\n\t\tif (bump) {\n\t\t\tcounts[type] = ++count;\n\t\t} else {\n\t\t\treturn count;\n\t\t}\n\t} else {\n\t\tcount = counts[type] = 1;\n\t}\n\tsessionStorage.setItem('instance-counts', JSON.stringify(counts));\n\treturn count;\n}\n\nexport default {\n\n\t/**\n\t * Get instance count for given type without bumping the number.\n\t *\n\t * @param type\n\t * @returns {number}\n\t */\n\tcurrent(type) {\n\t\treturn getInstanceCount(type, false);\n\t},\n\n\t/**\n\t * Get the instance count for the given type - will bump the counter and return the new value.\n\t *\n\t * @param type\n\t * @returns {number}\n\t */\n\tcount(type) {\n\t\treturn getInstanceCount(type);\n\t}\n\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/InstanceCounter.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 1/19/16.\n *\n * The fields used to populate the 'Basic' details editor panel.\n */\nconst common = ['name', 'short-name', 'description', 'vendor', 'version'];\nexport default {\n\tsimpleList: ['constituent-vnfd', 'vnffgd'],\n\tcommon: common.concat(),\n\tnsd: common.concat(['constituent-vnfd', 'vnffgd']),\n\tvld: common.concat([]),\n\tvnfd: common.concat([]),\n\tvdu: common.concat([])\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorModelFields.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 1/27/16.\n *\n * This class creates the initial descriptor model JSON objects.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport DescriptorTemplates from './DescriptorTemplates'\nimport DescriptorModelMetaFactory from './DescriptorModelMetaFactory'\n\nconst keys = Object.keys;\n\nfunction resolveInitHandlers(model) {\n\tfunction init(m) {\n\t\tkeys(m).map(key => {\n\t\t\tconst value = m[key];\n\t\t\tif (_.isFunction(value)) {\n\t\t\t\tm[key] = value(m, key, model);\n\t\t\t}\n\t\t\tif (_.isArray(value)) {\n\t\t\t\tvalue.forEach(v => init(v));\n\t\t\t}\n\t\t\tif (_.isObject(value)) {\n\t\t\t\tinit(value);\n\t\t\t}\n\t\t});\n\t\treturn m;\n\t}\n\treturn init(model);\n}\n\nexport default {\n\tcreateModelForType(type) {\n\t\tconst template = DescriptorTemplates[type];\n\t\tif (template) {\n\t\t\tconst model = _.cloneDeep(template);\n\t\t\treturn resolveInitHandlers(model);\n\t\t}\n\t}\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorTemplateFactory.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/6/15.\n *\n * Model fragments used to construct partially completed models.\n */\n\n'use strict';\n\nimport guid from './../guid'\nimport InstanceCounter from './../InstanceCounter'\n\nexport default {\n\t'vnfd': {\n\t\t'description': 'A simple VNF descriptor w/ one VDU',\n\t\t'version': '0.1.0',\n\t\t'internal-vld': [\n\t\t\t{\n\t\t\t\t'id': () => guid(),\n\t\t\t\t'name': () => 'fabric-' + InstanceCounter.count('vnfd.internal-vld'),\n\t\t\t\t'description': 'Virtual link for internal fabric',\n\t\t\t\t'type': 'ELAN'\n\t\t\t}\n\t\t],\n\t\t'connection-point': [\n\t\t\t{\n\t\t\t\t'name': 'ping-vnfd/cp0',\n\t\t\t\t'type': 'VPORT'\n\t\t\t},\n\t\t\t{\n\t\t\t\t'name': 'ping-vnfd/cp1',\n\t\t\t\t'type': 'VPORT'\n\t\t\t}\n\t\t],\n\t\t'vdu': [\n\t\t\t{\n\t\t\t\t'id': () => guid(),\n\t\t\t\t'name': () => 'vdu-' + InstanceCounter.count('vnfd.vdu'),\n\t\t\t\t'count': 2,\n\t\t\t\t'vm-flavor': {\n\t\t\t\t\t'vcpu-count': 4,\n\t\t\t\t\t'memory-mb': 16384,\n\t\t\t\t\t'storage-gb': 16\n\t\t\t\t},\n\t\t\t\t'guest-epa': {\n\t\t\t\t\t'trusted-execution': true,\n\t\t\t\t\t'mempage-size': 'PREFER_LARGE',\n\t\t\t\t\t'cpu-pinning-policy': 'DEDICATED',\n\t\t\t\t\t'cpu-thread-pinning-policy': 'AVOID',\n\t\t\t\t\t'numa-node-policy': {\n\t\t\t\t\t\t'node-cnt': 2,\n\t\t\t\t\t\t'mem-policy': 'PREFERRED',\n\t\t\t\t\t\t'node': [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'id': 0,\n\t\t\t\t\t\t\t\t'vcpu': [\n\t\t\t\t\t\t\t\t\t'0',\n\t\t\t\t\t\t\t\t\t'1'\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t'memory-mb': 8192\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'id': 1,\n\t\t\t\t\t\t\t\t'vcpu': [\n\t\t\t\t\t\t\t\t\t'2',\n\t\t\t\t\t\t\t\t\t'3'\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t'memory-mb': 8192\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'vswitch-epa': {\n\t\t\t\t\t'ovs-acceleration': 'DISABLED',\n\t\t\t\t\t'ovs-offload': 'DISABLED'\n\t\t\t\t},\n\t\t\t\t'hypervisor-epa': {\n\t\t\t\t\t'type': 'PREFER_KVM'\n\t\t\t\t},\n\t\t\t\t'host-epa': {\n\t\t\t\t\t'cpu-model': 'PREFER_SANDYBRIDGE',\n\t\t\t\t\t'cpu-arch': 'PREFER_X86_64',\n\t\t\t\t\t'cpu-vendor': 'PREFER_INTEL',\n\t\t\t\t\t'cpu-socket-count': 'PREFER_TWO',\n\t\t\t\t\t'cpu-feature': [\n\t\t\t\t\t\t'PREFER_AES',\n\t\t\t\t\t\t'PREFER_CAT'\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t'image': 'rw_openstack.qcow2',\n\t\t\t\t'internal-connection-point': [\n\t\t\t\t\t{\n\t\t\t\t\t\t'id': () => guid(),\n\t\t\t\t\t\t'type': 'VPORT'\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t'id': () => guid(),\n\t\t\t\t\t\t'type': 'VPORT'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t'internal-interface': [\n\t\t\t\t\t{\n\t\t\t\t\t\t'name': 'eth0',\n\t\t\t\t\t\t'vdu-internal-connection-point-ref': (obj, key, model) => {\n\t\t\t\t\t\t\treturn model.vdu[0]['internal-connection-point'][0].id;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'virtual-interface': {\n\t\t\t\t\t\t\t'type': 'VIRTIO'\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t'name': 'eth1',\n\t\t\t\t\t\t'vdu-internal-connection-point-ref': (obj, key, model) => {\n\t\t\t\t\t\t\treturn model.vdu[0]['internal-connection-point'][1].id;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'virtual-interface': {\n\t\t\t\t\t\t\t'type': 'VIRTIO'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t'external-interface': [\n\t\t\t\t\t{\n\t\t\t\t\t\t'name': 'eth0',\n\t\t\t\t\t\t'vnfd-connection-point-ref': 'ping-vnfd/cp0',\n\t\t\t\t\t\t'virtual-interface': {\n\t\t\t\t\t\t\t'type': 'VIRTIO'\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t'name': 'eth1',\n\t\t\t\t\t\t'vnfd-connection-point-ref': 'ping-vnfd/cp1',\n\t\t\t\t\t\t'virtual-interface': {\n\t\t\t\t\t\t\t'type': 'VIRTIO'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t}\n};\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorTemplates.js\n **/","'use strict';\n\nmodule.exports = require('react/lib/ReactDOM');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-dom/index.js\n ** module id = 415\n ** module chunks = 0\n **/","var React = require('react');\nvar PropTypes = React.PropTypes;\n\nvar noop = function() {}\n\nfunction formatButtons(buttons) {\n  if (typeof buttons === 'string')\n    buttons = [buttons];\n  if (buttons) {\n    buttons = buttons.map(function (button) {\n      if (typeof button === 'string')\n        return {\n          name: button\n        };\n      return button;\n    });\n  }\n  return buttons || null;\n}\n\nmodule.exports = React.createClass({\n\n  displayName: 'react-crouton',\n\n  propTypes: {\n    id: PropTypes.number.isRequired,\n    onDismiss: PropTypes.func,\n    hidden: PropTypes.bool,\n    timeout: PropTypes.number,\n    autoMiss: PropTypes.bool,\n    message: PropTypes.oneOfType([\n      PropTypes.string,\n      PropTypes.array\n    ]).isRequired,\n    type: PropTypes.string.isRequired,\n    /**\n     * Buttons can be either `string` or `array`\n     *\n     * Example:\n     *\n     * ```\n     *  <Crouton buttons='close'/>\n     *  or\n     *  <Crouton buttons=[{name: 'close'}, {name: 'retry'}] />\n     *  or\n     *  <Crouton buttons=[{name: 'close', listener: somefunction}] />\n     *  or\n     *  <Crouton buttons=[{name: 'close', className: 'btn close', listener: somefunction}] />\n     * ```\n     */\n    buttons: PropTypes.oneOfType([\n      PropTypes.string,\n      PropTypes.arrayOf(PropTypes.shape({\n        name: PropTypes.string\n      })),\n      PropTypes.arrayOf(PropTypes.shape({\n        name: PropTypes.string,\n        className: PropTypes.string,\n        listener: PropTypes.func\n      }))\n    ])\n  },\n\n  getDefaultProps: function () {\n    return {\n      onDismiss: noop,\n      // 2000 ms\n      timeout: 2000,\n      autoMiss: true\n    };\n  },\n\n  getInitialState: function () {\n    return {\n      hidden: false,\n      ttd: null\n    };\n  },\n\n  dismiss: function () {\n    this.setState({\n      hidden: true\n    });\n    this.props.onDismiss();\n    this.clearTimeout();\n    return this;\n  },\n\n  clearTimeout: function () {\n    if (this.state.ttd) {\n      clearTimeout(this.state.ttd);\n      this.setState({\n        ttd: null\n      });\n    }\n    return this;\n  },\n\n  handleClick: function (event) {\n    this.dismiss();\n    var item = this.state.buttons.filter(function (button) {\n      return button.name.toLowerCase() === event.target.id\n    })[0];\n    if (item && item.listener) {\n      item.listener(event);\n    }\n  },\n\n  componentWillMount: function () {\n    this.changeState(this.props);\n  },\n\n  componentWillUnmount: function () {\n    this.clearTimeout();\n  },\n\n  changeState: function (nextProps) {\n    var buttons = formatButtons(nextProps.buttons);\n\n    var message = nextProps.message\n    if (typeof message === 'string')\n      message = [message];\n    var autoMiss = nextProps.autoMiss ? (buttons ? false : true) : nextProps.autoMiss;\n    if (autoMiss && !nextProps.hidden) {\n      var ttd = setTimeout(this.dismiss, nextProps.timeout || this.props.timeout);\n      // this.dismiss();\n      this.setState({\n        ttd: ttd,\n        hidden: nextProps.hidden,\n        buttons: buttons,\n        message: message,\n        type: nextProps.type\n      });\n    } else {\n      this.setState({\n        hidden: nextProps.hidden,\n        buttons: buttons,\n        message: message,\n        type: nextProps.type\n      });\n    }\n  },\n\n  componentWillReceiveProps: function (nextProps) {\n    this.changeState(nextProps);\n  },\n\n  shouldComponentUpdate: function (nextProps, nextState) {\n    if (nextProps.id === this.props.id) {\n      return !!nextState.hidden;\n    }\n    return true\n  },\n\n  render: function () {\n    return React.createElement('div', {\n        className: 'crouton',\n        hidden: this.state.hidden\n      },\n      React.createElement('div', {\n          className: this.state.type\n        },\n        this.state.message.map(function (msg, i) {\n          return React.createElement('span', {\n            key: i\n          }, msg);\n        }),\n        this.state.buttons ? React.createElement('div', {\n            className: 'buttons'\n          },\n          this.state.buttons.map(function (button, i) {\n            return React.createElement('button', {\n              id: button.name.toLowerCase(),\n              key: i,\n              className: button.className ? button.className : button.name.toLowerCase(),\n              onClick: this.handleClick\n            }, button.name)\n          }, this)\n        ) : null\n      )\n    )\n  }\n})\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-crouton/index.js\n ** module id = 416\n ** module chunks = 0\n **/","/*!\n  Copyright (c) 2015 Jed Watson.\n  Licensed under the MIT License (MIT), see\n  http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = '';\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses += ' ' + arg;\n\t\t\t} else if (Array.isArray(arg)) {\n\t\t\t\tclasses += ' ' + classNames.apply(null, arg);\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses += ' ' + key;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.substr(1);\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/classnames/index.js\n ** module id = 417\n ** module chunks = 0\n **/","'use strict';\n\nexports.__esModule = true;\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar _react = require('react');\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactDom = require('react-dom');\n\nvar _classnames = require('classnames');\n\nvar _classnames2 = _interopRequireDefault(_classnames);\n\nvar _style = require('./style');\n\nvar _style2 = _interopRequireDefault(_style);\n\nvar ReactTooltip = (function (_Component) {\n  _inherits(ReactTooltip, _Component);\n\n  /**\n   * Class method\n   * @see ReactTooltip.hide() && ReactTooltup.rebuild()\n   */\n\n  ReactTooltip.hide = function hide() {\n    window.dispatchEvent(new window.Event('__react_tooltip_hide_event'));\n  };\n\n  ReactTooltip.rebuild = function rebuild() {\n    window.dispatchEvent(new window.Event('__react_tooltip_rebuild_event'));\n  };\n\n  ReactTooltip.prototype.globalHide = function globalHide() {\n    if (this.mount) {\n      this.hideTooltip();\n    }\n  };\n\n  ReactTooltip.prototype.globalRebuild = function globalRebuild() {\n    if (this.mount) {\n      this.unbindListener();\n      this.bindListener();\n    }\n  };\n\n  _createClass(ReactTooltip, null, [{\n    key: 'displayName',\n    value: 'ReactTooltip',\n    enumerable: true\n  }, {\n    key: 'eventHideMark',\n    value: 'hide' + Date.now(),\n    enumerable: true\n  }, {\n    key: 'eventRebuildMark',\n    value: 'rebuild' + Date.now(),\n    enumerable: true\n  }]);\n\n  function ReactTooltip(props) {\n    _classCallCheck(this, ReactTooltip);\n\n    _Component.call(this, props);\n    this._bind('showTooltip', 'updateTooltip', 'hideTooltip', 'checkStatus');\n    this.mount = true;\n    this.state = {\n      show: false,\n      multilineCount: 0,\n      placeholder: '',\n      x: 'NONE',\n      y: 'NONE',\n      place: '',\n      type: '',\n      effect: '',\n      multiline: false,\n      offset: {},\n      extraClass: '',\n      html: false,\n      delayHide: 0,\n      event: props.event || null\n    };\n  }\n\n  /* Bind this with method */\n\n  ReactTooltip.prototype._bind = function _bind() {\n    var _this = this;\n\n    for (var _len = arguments.length, handlers = Array(_len), _key = 0; _key < _len; _key++) {\n      handlers[_key] = arguments[_key];\n    }\n\n    handlers.forEach(function (handler) {\n      return _this[handler] = _this[handler].bind(_this);\n    });\n  };\n\n  ReactTooltip.prototype.componentDidMount = function componentDidMount() {\n    this.bindListener();\n    this.setStyleHeader();\n    /* Add window event listener for hide and rebuild */\n    window.removeEventListener('__react_tooltip_hide_event', this.globalHide);\n    window.addEventListener('__react_tooltip_hide_event', this.globalHide.bind(this), false);\n\n    window.removeEventListener('__react_tooltip_rebuild_event', this.globalRebuild);\n    window.addEventListener('__react_tooltip_rebuild_event', this.globalRebuild.bind(this), false);\n  };\n\n  ReactTooltip.prototype.componentWillUpdate = function componentWillUpdate() {\n    this.unbindListener();\n  };\n\n  ReactTooltip.prototype.componentDidUpdate = function componentDidUpdate() {\n    this.updatePosition();\n    this.bindListener();\n  };\n\n  ReactTooltip.prototype.componentWillUnmount = function componentWillUnmount() {\n    this.unbindListener();\n    this.mount = false;\n    window.removeEventListener('__react_tooltip_hide_event', this.globalHide);\n    window.removeEventListener('__react_tooltip_rebuild_event', this.globalRebuild);\n  };\n\n  ReactTooltip.prototype.bindListener = function bindListener() {\n    var id = this.props.id;\n\n    var targetArray = undefined;\n\n    if (id === undefined) {\n      targetArray = document.querySelectorAll('[data-tip]:not([data-for])');\n    } else {\n      targetArray = document.querySelectorAll('[data-tip][data-for=\"' + id + '\"]');\n    }\n\n    var dataEvent = undefined;\n    for (var i = 0; i < targetArray.length; i++) {\n      targetArray[i].setAttribute('currentItem', 'false');\n      dataEvent = this.state.event || targetArray[i].getAttribute('data-event');\n      if (dataEvent) {\n        targetArray[i].removeEventListener(dataEvent, this.checkStatus);\n        targetArray[i].addEventListener(dataEvent, this.checkStatus, false);\n      } else {\n        targetArray[i].removeEventListener('mouseenter', this.showTooltip);\n        targetArray[i].addEventListener('mouseenter', this.showTooltip, false);\n\n        if (this.state.effect === 'float') {\n          targetArray[i].removeEventListener('mousemove', this.updateTooltip);\n          targetArray[i].addEventListener('mousemove', this.updateTooltip, false);\n        }\n\n        targetArray[i].removeEventListener('mouseleave', this.hideTooltip);\n        targetArray[i].addEventListener('mouseleave', this.hideTooltip, false);\n      }\n    }\n  };\n\n  ReactTooltip.prototype.checkStatus = function checkStatus(e) {\n    if (this.state.show && e.currentTarget.getAttribute('currentItem') === 'true') {\n      this.hideTooltip(e);\n    } else {\n      e.currentTarget.setAttribute('currentItem', 'true');\n      this.showTooltip(e);\n      this.setUntargetItems(e.currentTarget);\n    }\n  };\n\n  ReactTooltip.prototype.setUntargetItems = function setUntargetItems(currentTarget) {\n    var id = this.props.id;\n\n    var targetArray = undefined;\n\n    if (id === undefined) {\n      targetArray = document.querySelectorAll('[data-tip]:not([data-for])');\n    } else {\n      targetArray = document.querySelectorAll('[data-tip][data-for=\"' + id + '\"]');\n    }\n\n    for (var i = 0; i < targetArray.length; i++) {\n      if (currentTarget !== targetArray[i]) {\n        targetArray[i].setAttribute('currentItem', 'false');\n      } else {\n        targetArray[i].setAttribute('currentItem', 'true');\n      }\n    }\n  };\n\n  ReactTooltip.prototype.unbindListener = function unbindListener() {\n    var targetArray = document.querySelectorAll('[data-tip]');\n    var dataEvent = undefined;\n\n    for (var i = 0; i < targetArray.length; i++) {\n      dataEvent = this.state.event || targetArray[i].getAttribute('data-event');\n      if (dataEvent) {\n        targetArray[i].removeEventListener(dataEvent, this.checkStatus);\n      } else {\n        targetArray[i].removeEventListener('mouseenter', this.showTooltip);\n        targetArray[i].removeEventListener('mousemove', this.updateTooltip);\n        targetArray[i].removeEventListener('mouseleave', this.hideTooltip);\n      }\n    }\n  };\n\n  /**\n   * When mouse enter, show update\n   */\n\n  ReactTooltip.prototype.showTooltip = function showTooltip(e) {\n    var originTooltip = e.currentTarget.getAttribute('data-tip');\n    /* Detect multiline */\n    var regexp = /<br\\s*\\/?>/;\n    var multiline = e.currentTarget.getAttribute('data-multiline') ? e.currentTarget.getAttribute('data-multiline') : this.props.multiline ? this.props.multiline : false;\n    var tooltipText = undefined;\n    var multilineCount = 0;\n    if (!multiline || multiline === 'false' || !regexp.test(originTooltip)) {\n      tooltipText = originTooltip;\n    } else {\n      tooltipText = originTooltip.split(regexp).map(function (d, i) {\n        multilineCount += 1;\n        return _react2['default'].createElement(\n          'span',\n          { key: i, className: 'multi-line' },\n          d\n        );\n      });\n    }\n    /* Define extra class */\n    var extraClass = e.currentTarget.getAttribute('data-class') ? e.currentTarget.getAttribute('data-class') : '';\n    extraClass = this.props['class'] ? this.props['class'] + ' ' + extraClass : extraClass;\n    this.setState({\n      placeholder: tooltipText,\n      multilineCount: multilineCount,\n      place: e.currentTarget.getAttribute('data-place') ? e.currentTarget.getAttribute('data-place') : this.props.place ? this.props.place : 'top',\n      type: e.currentTarget.getAttribute('data-type') ? e.currentTarget.getAttribute('data-type') : this.props.type ? this.props.type : 'dark',\n      effect: e.currentTarget.getAttribute('data-effect') ? e.currentTarget.getAttribute('data-effect') : this.props.effect ? this.props.effect : 'float',\n      offset: e.currentTarget.getAttribute('data-offset') ? e.currentTarget.getAttribute('data-offset') : this.props.offset ? this.props.offset : {},\n      html: e.currentTarget.getAttribute('data-html') ? e.currentTarget.getAttribute('data-html') : this.props.html ? this.props.html : false,\n      delayHide: e.currentTarget.getAttribute('data-delay-hide') ? e.currentTarget.getAttribute('data-delay-hide') : this.props.delayHide ? this.props.delayHide : 0,\n      extraClass: extraClass,\n      multiline: multiline\n    });\n    this.updateTooltip(e);\n  };\n\n  /**\n   * When mouse hover, updatetooltip\n   */\n\n  ReactTooltip.prototype.updateTooltip = function updateTooltip(e) {\n    if (this.trim(this.state.placeholder).length > 0) {\n      var place = this.state.place;\n\n      var node = _reactDom.findDOMNode(this);\n      if (this.state.effect === 'float') {\n        // const offsetY = e.clientY\n        this.setState({\n          show: true,\n          x: e.clientX,\n          y: e.clientY\n        });\n      } else if (this.state.effect === 'solid') {\n        var boundingClientRect = e.currentTarget.getBoundingClientRect();\n        var targetTop = boundingClientRect.top;\n        var targetLeft = boundingClientRect.left;\n        var tipWidth = node.clientWidth;\n        var tipHeight = node.clientHeight;\n        var targetWidth = e.currentTarget.clientWidth;\n        var targetHeight = e.currentTarget.clientHeight;\n        var x = undefined;\n        var y = undefined;\n        if (place === 'top') {\n          x = targetLeft - tipWidth / 2 + targetWidth / 2;\n          y = targetTop - tipHeight - 8;\n        } else if (place === 'bottom') {\n          x = targetLeft - tipWidth / 2 + targetWidth / 2;\n          y = targetTop + targetHeight + 8;\n        } else if (place === 'left') {\n          x = targetLeft - tipWidth - 6;\n          y = targetTop + targetHeight / 2 - tipHeight / 2;\n        } else if (place === 'right') {\n          x = targetLeft + targetWidth + 6;\n          y = targetTop + targetHeight / 2 - tipHeight / 2;\n        }\n        this.setState({\n          show: true,\n          x: x,\n          y: y\n        });\n      }\n    }\n  };\n\n  /**\n   * When mouse leave, hide tooltip\n   */\n\n  ReactTooltip.prototype.hideTooltip = function hideTooltip() {\n    var _this2 = this;\n\n    var delayHide = this.state.delayHide;\n\n    setTimeout(function () {\n      _this2.setState({\n        show: false\n      });\n    }, parseInt(delayHide, 10));\n  };\n\n  /**\n   * Execute in componentDidUpdate, used in the render function, move out for server rending\n   */\n\n  ReactTooltip.prototype.updatePosition = function updatePosition() {\n    var node = _reactDom.findDOMNode(this);\n\n    var tipWidth = node.clientWidth;\n    var tipHeight = node.clientHeight;\n    var _state = this.state;\n    var effect = _state.effect;\n    var place = _state.place;\n    var offset = _state.offset;\n\n    var offsetFromEffect = {};\n\n    if (effect === 'float') {\n      offsetFromEffect.top = {\n        x: -(tipWidth / 2),\n        y: -tipHeight\n      };\n      offsetFromEffect.bottom = {\n        x: -(tipWidth / 2),\n        y: 15\n      };\n      offsetFromEffect.left = {\n        x: -(tipWidth + 15),\n        y: -(tipHeight / 2)\n      };\n      offsetFromEffect.right = {\n        x: 10,\n        y: -(tipHeight / 2)\n      };\n    }\n    var xPosition = 0;\n    var yPosition = 0;\n\n    if (Object.prototype.toString.apply(offset) === '[object String]') {\n      offset = JSON.parse(offset.toString().replace(/\\'/g, '\\\"'));\n    }\n    for (var key in offset) {\n      if (key === 'top') {\n        yPosition -= parseInt(offset[key], 10);\n      } else if (key === 'bottom') {\n        yPosition += parseInt(offset[key], 10);\n      } else if (key === 'left') {\n        xPosition -= parseInt(offset[key], 10);\n      } else if (key === 'right') {\n        xPosition += parseInt(offset[key], 10);\n      }\n    }\n    /* When tooltip over the screen */\n    var offsetEffectX = effect === 'solid' ? 0 : place ? offsetFromEffect[place].x : 0;\n    var offsetEffectY = effect === 'solid' ? 0 : place ? offsetFromEffect[place].y : 0;\n    var styleLeft = this.state.x + offsetEffectX + xPosition;\n    var styleTop = this.state.y + offsetEffectY + yPosition;\n    var windoWidth = window.innerWidth;\n    var windowHeight = window.innerHeight;\n\n    /* Solid use this method will get Uncaught RangeError: Maximum call stack size exceeded */\n    if (effect === 'float') {\n      if (styleLeft < 0 && this.state.x + offsetFromEffect['right'].x + xPosition <= windoWidth) {\n        this.setState({\n          place: 'right'\n        });\n        return;\n      } else if (styleLeft + tipWidth > windoWidth && this.state.x + offsetFromEffect['left'].x + xPosition >= 0) {\n        this.setState({\n          place: 'left'\n        });\n        return;\n      } else if (styleTop < 0 && this.state.y + offsetFromEffect['bottom'].y + yPosition + tipHeight < windowHeight) {\n        this.setState({\n          place: 'bottom'\n        });\n        return;\n      } else if (styleTop + tipHeight >= windowHeight && this.state.y + offsetFromEffect['top'].y + yPosition >= 0) {\n        this.setState({\n          place: 'top'\n        });\n        return;\n      }\n    }\n\n    node.style.left = styleLeft + 'px';\n    node.style.top = styleTop + 'px';\n  };\n\n  /**\n   * Set style tag in header\n   * Insert style by this way\n   */\n\n  ReactTooltip.prototype.setStyleHeader = function setStyleHeader() {\n    if (!document.getElementsByTagName('head')[0].querySelector('style[id=\"react-tooltip\"]')) {\n      var tag = document.createElement('style');\n      tag.id = 'react-tooltip';\n      tag.innerHTML = _style2['default'];\n      document.getElementsByTagName('head')[0].appendChild(tag);\n    }\n  };\n\n  ReactTooltip.prototype.render = function render() {\n    var _state2 = this.state;\n    var placeholder = _state2.placeholder;\n    var extraClass = _state2.extraClass;\n    var html = _state2.html;\n\n    var tooltipClass = _classnames2['default']('__react_component_tooltip', { 'show': this.state.show }, { 'place-top': this.state.place === 'top' }, { 'place-bottom': this.state.place === 'bottom' }, { 'place-left': this.state.place === 'left' }, { 'place-right': this.state.place === 'right' }, { 'type-dark': this.state.type === 'dark' }, { 'type-success': this.state.type === 'success' }, { 'type-warning': this.state.type === 'warning' }, { 'type-error': this.state.type === 'error' }, { 'type-info': this.state.type === 'info' }, { 'type-light': this.state.type === 'light' });\n\n    if (html) {\n      return _react2['default'].createElement('div', { className: tooltipClass + ' ' + extraClass, 'data-id': 'tooltip', dangerouslySetInnerHTML: { __html: placeholder } });\n    } else {\n      var content = this.props.children ? this.props.children : placeholder;\n      return _react2['default'].createElement(\n        'div',\n        { className: tooltipClass + ' ' + extraClass, 'data-id': 'tooltip' },\n        content\n      );\n    }\n  };\n\n  ReactTooltip.prototype.trim = function trim(string) {\n    if (Object.prototype.toString.call(string) !== '[object String]') {\n      return string;\n    }\n    var newString = string.split('');\n    var firstCount = 0;\n    var lastCount = 0;\n    for (var i = 0; i < string.length; i++) {\n      if (string[i] !== ' ') {\n        break;\n      }\n      firstCount++;\n    }\n    for (var i = string.length - 1; i >= 0; i--) {\n      if (string[i] !== ' ') {\n        break;\n      }\n      lastCount++;\n    }\n    newString.splice(0, firstCount);\n    newString.splice(-lastCount, lastCount);\n    return newString.join('');\n  };\n\n  return ReactTooltip;\n})(_react.Component);\n\nexports['default'] = ReactTooltip;\n\nReactTooltip.propTypes = {\n  children: _react.PropTypes.any,\n  place: _react.PropTypes.string,\n  type: _react.PropTypes.string,\n  effect: _react.PropTypes.string,\n  offset: _react.PropTypes.object,\n  multiline: _react.PropTypes.bool,\n  'class': _react.PropTypes.string,\n  id: _react.PropTypes.string,\n  html: _react.PropTypes.bool,\n  delayHide: _react.PropTypes.number,\n  event: _react.PropTypes.any\n};\nmodule.exports = exports['default'];\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-tooltip/dist/react-tooltip.js\n ** module id = 418\n ** module chunks = 0\n **/","/*!\n  Copyright (c) 2015 Jed Watson.\n  Licensed under the MIT License (MIT), see\n  http://jedwatson.github.io/classnames\n*/\n\nfunction classNames() {\n\tvar classes = '';\n\tvar arg;\n\n\tfor (var i = 0; i < arguments.length; i++) {\n\t\targ = arguments[i];\n\t\tif (!arg) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ('string' === typeof arg || 'number' === typeof arg) {\n\t\t\tclasses += ' ' + arg;\n\t\t} else if (Object.prototype.toString.call(arg) === '[object Array]') {\n\t\t\tclasses += ' ' + classNames.apply(null, arg);\n\t\t} else if ('object' === typeof arg) {\n\t\t\tfor (var key in arg) {\n\t\t\t\tif (!arg.hasOwnProperty(key) || !arg[key]) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclasses += ' ' + key;\n\t\t\t}\n\t\t}\n\t}\n\treturn classes.substr(1);\n}\n\n// safely export classNames for node / browserify\nif (typeof module !== 'undefined' && module.exports) {\n\tmodule.exports = classNames;\n}\n\n// safely export classNames for RequireJS\nif (typeof define !== 'undefined' && define.amd) {\n\tdefine('classnames', [], function() {\n\t\treturn classNames;\n\t});\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-tooltip/~/classnames/index.js\n ** module id = 419\n ** module chunks = 0\n **/","'use strict';\n\nexports.__esModule = true;\nexports['default'] = '.__react_component_tooltip{border-radius:3px;display:inline-block;font-size:13px;left:-999em;opacity:0;padding:8px 21px;position:fixed;pointer-events:none;transition:opacity 0.3s ease-out , margin-top 0.3s ease-out, margin-left 0.3s ease-out;top:-999em;visibility:hidden;z-index:999}.__react_component_tooltip:after{content:\"\";width:0;height:0;position:absolute}.__react_component_tooltip.show{opacity:0.9;margin-top:0px;margin-left:0px;visibility:visible}.__react_component_tooltip.type-dark{color:#fff;background-color:#222}.__react_component_tooltip.type-dark.place-top:after{border-top:8px solid #222}.__react_component_tooltip.type-dark.place-bottom:after{border-bottom:8px solid #222}.__react_component_tooltip.type-dark.place-left:after{border-left:6px solid #222}.__react_component_tooltip.type-dark.place-right:after{border-right:6px solid #222}.__react_component_tooltip.type-success{color:#fff;background-color:#8DC572}.__react_component_tooltip.type-success.place-top:after{border-top:8px solid #8DC572}.__react_component_tooltip.type-success.place-bottom:after{border-bottom:8px solid #8DC572}.__react_component_tooltip.type-success.place-left:after{border-left:6px solid #8DC572}.__react_component_tooltip.type-success.place-right:after{border-right:6px solid #8DC572}.__react_component_tooltip.type-warning{color:#fff;background-color:#F0AD4E}.__react_component_tooltip.type-warning.place-top:after{border-top:8px solid #F0AD4E}.__react_component_tooltip.type-warning.place-bottom:after{border-bottom:8px solid #F0AD4E}.__react_component_tooltip.type-warning.place-left:after{border-left:6px solid #F0AD4E}.__react_component_tooltip.type-warning.place-right:after{border-right:6px solid #F0AD4E}.__react_component_tooltip.type-error{color:#fff;background-color:#BE6464}.__react_component_tooltip.type-error.place-top:after{border-top:8px solid #BE6464}.__react_component_tooltip.type-error.place-bottom:after{border-bottom:8px solid #BE6464}.__react_component_tooltip.type-error.place-left:after{border-left:6px solid #BE6464}.__react_component_tooltip.type-error.place-right:after{border-right:6px solid #BE6464}.__react_component_tooltip.type-info{color:#fff;background-color:#337AB7}.__react_component_tooltip.type-info.place-top:after{border-top:8px solid #337AB7}.__react_component_tooltip.type-info.place-bottom:after{border-bottom:8px solid #337AB7}.__react_component_tooltip.type-info.place-left:after{border-left:6px solid #337AB7}.__react_component_tooltip.type-info.place-right:after{border-right:6px solid #337AB7}.__react_component_tooltip.type-light{color:#222;background-color:#fff}.__react_component_tooltip.type-light.place-top:after{border-top:8px solid #fff}.__react_component_tooltip.type-light.place-bottom:after{border-bottom:8px solid #fff}.__react_component_tooltip.type-light.place-left:after{border-left:6px solid #fff}.__react_component_tooltip.type-light.place-right:after{border-right:6px solid #fff}.__react_component_tooltip.place-top{margin-top:-10px}.__react_component_tooltip.place-top:after{border-left:10px solid transparent;border-right:10px solid transparent;bottom:-8px;left:50%;margin-left:-10px}.__react_component_tooltip.place-bottom{margin-top:10px}.__react_component_tooltip.place-bottom:after{border-left:10px solid transparent;border-right:10px solid transparent;top:-8px;left:50%;margin-left:-10px}.__react_component_tooltip.place-left{margin-left:-10px}.__react_component_tooltip.place-left:after{border-top:6px solid transparent;border-bottom:6px solid transparent;right:-6px;top:50%;margin-top:-5px}.__react_component_tooltip.place-right{margin-left:10px}.__react_component_tooltip.place-right:after{border-top:6px solid transparent;border-bottom:6px solid transparent;left:-6px;top:50%;margin-top:-5px}.__react_component_tooltip .multi-line{display:block;padding:2px 0px;text-align:center}';\nmodule.exports = exports['default'];\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-tooltip/dist/style.js\n ** module id = 420\n ** module chunks = 0\n **/","module.exports = require('react/lib/ReactComponentWithPureRenderMixin');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-addons-pure-render-mixin/index.js\n ** module id = 421\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ReactComponentWithPureRenderMixin\n */\n\n'use strict';\n\nvar shallowCompare = require('./shallowCompare');\n\n/**\n * If your React component's render function is \"pure\", e.g. it will render the\n * same result given the same props and state, provide this Mixin for a\n * considerable performance boost.\n *\n * Most React components have pure render functions.\n *\n * Example:\n *\n *   var ReactComponentWithPureRenderMixin =\n *     require('ReactComponentWithPureRenderMixin');\n *   React.createClass({\n *     mixins: [ReactComponentWithPureRenderMixin],\n *\n *     render: function() {\n *       return <div className={this.props.className}>foo</div>;\n *     }\n *   });\n *\n * Note: This only checks shallow equality for props and state. If these contain\n * complex data structures this mixin may have false-negatives for deeper\n * differences. Only mixin to components which have simple props and state, or\n * use `forceUpdate()` when you know deep data structures have changed.\n */\nvar ReactComponentWithPureRenderMixin = {\n  shouldComponentUpdate: function (nextProps, nextState) {\n    return shallowCompare(this, nextProps, nextState);\n  }\n};\n\nmodule.exports = ReactComponentWithPureRenderMixin;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/ReactComponentWithPureRenderMixin.js\n ** module id = 422\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n* @providesModule shallowCompare\n*/\n\n'use strict';\n\nvar shallowEqual = require('fbjs/lib/shallowEqual');\n\n/**\n * Does a shallow comparison for props and state.\n * See ReactComponentWithPureRenderMixin\n */\nfunction shallowCompare(instance, nextProps, nextState) {\n  return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);\n}\n\nmodule.exports = shallowCompare;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/shallowCompare.js\n ** module id = 423\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/2/15.\n */\n\nimport _ from 'lodash'\nimport d3 from 'd3'\nimport UID from './UniqueId'\nimport SelectionManager from './SelectionManager'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport DescriptorModelFactory from './model/DescriptorModelFactory'\n\nimport '../styles/Animations.scss'\n\nconst DELETE = 26;\nconst BACKSPACE = 8;\n\nfunction onlyUnique(value, index, self) {\n\treturn self.indexOf(value) === index;\n}\n\nfunction createDeleteEvent(e, uid, eventName = 'cut') {\n\tconst data = {\n\t\tbubbles: true,\n\t\tcancelable: true,\n\t\tdetail: {\n\t\t\tuid: uid,\n\t\t\toriginalEvent: e\n\t\t}\n\t};\n\tif (window.CustomEvent.prototype.initCustomEvent) {\n\t\t// support IE\n\t\tvar evt = document.createEvent('CustomEvent');\n\t\tevt.initCustomEvent(eventName, data.bubbles, data.cancelable, data.detail);\n\t\treturn evt;\n\t}\n\treturn new CustomEvent(eventName, data);\n}\n\nexport default class DeletionManager {\n\n\tstatic onDeleteKey(event) {\n\t\tconst target = event.target;\n\t\tif (event.defaultPrevented) {\n\t\t\treturn\n\t\t}\n\t\tif ((event.which === DELETE || event.which === BACKSPACE) && /^BODY|SVG|DIV$/i.test(target.tagName)) {\n\t\t\tevent.preventDefault();\n\t\t\tDeletionManager.deleteSelected(event);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tstatic deleteSelected(event) {\n\n\t\t// TODO refactor this to be a flux action e.g. move this code into ComposerAppActions.deleteSelected()\n\n\t\tconst selected = SelectionManager.getSelections();\n\n\t\t// get a valid list of items to potentially remove via the cut event handler\n\t\tconst removeElementList = selected.filter(d => d).filter(onlyUnique).reduce((r, uid) => {\n\t\t\tconst elements = Array.from(document.querySelectorAll('[data-uid=\"' + uid + '\"]'));\n\t\t\treturn r.concat(elements);\n\t\t}, []).filter(d => d);\n\n\t\tif (removeElementList.length === 0 && selected.length > 0) {\n\t\t\t// something was selected but we did not find any dom elements with data-uid!\n\t\t\tconsole.error(`No valid DescriptorModel instance found on element. Did you forget to put data-uid={m.uid}`,\n\t\t\t\tselected.map(uid => Array.from(document.querySelectorAll(`[data-uid=\"${uid}\"]`))));\n\t\t}\n\n\t\t// proactively update the UI for visual transitions\n\t\td3.selectAll(removeElementList).classed('-with-animations deleteItemAnimation', true).transition().each('end', function () {\n\t\t\td3.select(this);\n\t\t});\n\n\t\tSelectionManager.removeOutline();\n\n\t\t// give time for the delete animation to play out\n\t\tsetTimeout(() => {\n\n\t\t\t// now actually update the model\n\t\t\tconst invokedEventAlreadyMap = {};\n\t\t\tconst failedToRemoveList = removeElementList.map(removedElement => {\n\n\t\t\t\tconst uid = UID.from(removedElement);\n\n\t\t\t\tif (invokedEventAlreadyMap[uid]) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst cancelled = !removedElement.dispatchEvent(createDeleteEvent(event, uid));\n\t\t\t\t\tif (cancelled) {\n\t\t\t\t\t\td3.select(removedElement).classed('-with-animations deleteItemAnimation', false).style({opacity: null});\n\t\t\t\t\t\treturn removedElement;\n\t\t\t\t\t}\n\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.warn(`Exception caught dispatching 'cut' event: ${error}`,\n\t\t\t\t\t\tselected.map(uid => Array.from(document.querySelectorAll(`[data-uid=\"${uid}\"]`))));\n\t\t\t\t\treturn removedElement;\n\t\t\t\t}\n\n\t\t\t}).filter(d => d).filter(onlyUnique);\n\n\t\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\t\tfailedToRemoveList.forEach(d => SelectionManager.addSelection(d));\n\t\t\tSelectionManager.refreshOutline();\n\n\t\t}, 230);\n\n\t}\n\n\tstatic addEventListeners() {\n\t\tDeletionManager.removeEventListeners();\n\t\tdocument.body.addEventListener('keydown', DeletionManager.onDeleteKey);\n\t}\n\n\tstatic removeEventListeners() {\n\t\tdocument.body.removeEventListener('keydown', DeletionManager.onDeleteKey);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/DeletionManager.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/11/15.\n */\nimport alt from '../alt';\n\n/*\n This class manages Catalog Data State\n */\n\nclass CatalogItemsActions {\n\n\tconstructor() {\n\t\tthis.generateActions('catalogItemMetaDataChanged', 'catalogItemDescriptorChanged', 'createCatalogItem', 'editCatalogItem', 'duplicateSelectedCatalogItem', 'selectCatalogItem', 'deleteSelectedCatalogItem', 'cancelCatalogItemChanges', 'saveCatalogItem', 'exportSelectedCatalogItems');\n\t}\n\n}\n\nexport default alt.createActions(CatalogItemsActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CatalogItemsActions.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport d3 from 'd3'\nimport UID from './../UniqueId'\nimport guid from '../guid'\nimport Position from './../graph/Position'\nimport ColorGroups from '../ColorGroups'\nimport DescriptorModel from './DescriptorModel'\nimport DescriptorModelMetaFactory from './DescriptorModelMetaFactory'\nimport DescriptorModelMetaProperty from './DescriptorModelMetaProperty'\n\nimport Classifier from './descriptors/Classifier'\nimport ClassifierMatchAttributes from './descriptors/ClassifierMatchAttributes'\nimport ConnectionPoint from './descriptors/ConnectionPoint'\nimport VnfdConnectionPointRef from './descriptors/VnfdConnectionPointRef'\nimport ConstituentVnfd from './descriptors/ConstituentVnfd'\nimport ConstituentVnfdConnectionPoint from './descriptors/ConstituentVnfdConnectionPoint'\nimport ForwardingGraph from './descriptors/ForwardingGraph'\nimport InternalConnectionPoint from './descriptors/InternalConnectionPoint'\nimport InternalVirtualLink from './descriptors/InternalVirtualLink'\nimport NetworkService from './descriptors/NetworkService'\nimport PhysicalNetworkFunction from './descriptors/PhysicalNetworkFunction'\nimport RecordServicePath from './descriptors/RecordServicePath'\nimport RspConnectionPointRef from './descriptors/RspConnectionPointRef'\nimport VirtualDeploymentUnit from './descriptors/VirtualDeploymentUnit'\nimport VirtualLink from './descriptors/VirtualLink'\nimport VirtualNetworkFunction from './descriptors/VirtualNetworkFunction'\nimport VirtualNetworkFunctionReadOnlyWrapper from './descriptors/VirtualNetworkFunctionReadOnlyWrapper'\n\nfunction findChildDescriptorModelAndUpdateModel(model, parent) {\n\tif (parent instanceof DescriptorModel) {\n\t\tconst child = parent.findChildByUid(model);\n\t\tif (child) {\n\t\t\tchild.model = model;\n\t\t\treturn child;\n\t\t}\n\t}\n}\n\nlet identity = 0;\n\nclass DescriptorModelFactory {\n\n\n\tstatic containerIdentity(d) {\n\t\tconst parentId = UID.from(d && d.parent);\n\t\t// note the incremental counter is to always force d3 models to update\n\t\treturn (parentId ? parentId + ':' : '') + UID.from(d) + ':' + identity++;\n\t}\n\n\t/**\n\t * Create a reduce function that creates a DescriptorModel element tree\n\t * representation of a Catalog Item and then returns a flat list of\n\t * DescriptorModel elements. The first item in the array is root.\n\n\t * @returns {Function}\n\t */\n\tstatic buildCatalogItemFactory(catalogs) {\n\n\t\tfunction findCatalogItemByTypeAndId(type, id) {\n\t\t\treturn catalogs.filter(catalog => catalog.type === type).reduce((a, b) => a.concat(b.descriptors), []).filter(d => d.id === id)[0];\n\t\t}\n\n\t\tfunction mapVLD(vld, containerList) {\n\t\t\tcontainerList.push(vld);\n\t\t\tvld.connection.forEach(d => containerList.push(d));\n\t\t}\n\n\t\tfunction mapIVLD(ivld, containerList) {\n\t\t\tcontainerList.push(ivld);\n\t\t}\n\n\t\tfunction mapRspConnectionPoint(cp, containerList) {\n\t\t\tcontainerList.push(cp);\n\t\t}\n\n\t\tfunction mapClassifier(classifier, containerList) {\n\t\t\tcontainerList.push(classifier);\n\t\t}\n\n\t\tfunction mapRSP(rsp, containerList) {\n\t\t\tcontainerList.push(rsp);\n\t\t\trsp.vnfdConnectionPointRef.forEach(cpRef => mapRspConnectionPoint(cpRef, containerList));\n\t\t\trsp.classifier.forEach(classifier => mapClassifier(classifier, containerList));\n\t\t}\n\n\t\tfunction mapFG(fg, containerList) {\n\t\t\tcontainerList.push(fg);\n\t\t\tfg.rsp.forEach(rsp => mapRSP(rsp, containerList));\n\t\t}\n\n\t\tfunction mapVDU(vdu, containerList) {\n\t\t\tcontainerList.push(vdu);\n\t\t}\n\n\t\tfunction mapCVNFD(cvnfd, containerList) {\n\t\t\t// get the referenced vnfd required for rendering the connection points\n\t\t\tconst vnfdRef = findCatalogItemByTypeAndId('vnfd', cvnfd.model['vnfd-id-ref']);\n\t\t\tif (!vnfdRef) {\n\t\t\t\tconsole.warn('No VNFD found in catalog with id: ' + cvnfd['vnfd-id-ref']);\n\t\t\t}\n\t\t\tcvnfd.vnfdRef = vnfdRef;\n\t\t\tcontainerList.push(cvnfd);\n\t\t\tcvnfd.vld.forEach(vld => mapIVLD(vld, containerList));\n\t\t\tcvnfd.connectionPoint.forEach(cp => containerList.push(cp));\n\t\t}\n\n\t\tfunction mapNSD(nsd, containerList) {\n\t\t\tcontainerList.push(nsd);\n\t\t\tnsd.constituentVnfd.forEach(cvnfd => mapCVNFD(cvnfd, containerList));\n\t\t\tnsd.vld.forEach(vld => mapVLD(vld, containerList));\n\t\t\tnsd.vnffgd.forEach(fg => mapFG(fg, containerList));\n\t\t}\n\n\t\tfunction mapVNFD(vnfd, containerList) {\n\t\t\tcontainerList.push(vnfd);\n\t\t\tvnfd.vdu.forEach(vdu => mapVDU(vdu, containerList));\n\t\t\tvnfd.vld.forEach(vld => mapIVLD(vld, containerList));\n\t\t}\n\n\t\tfunction mapPNFD(pnfd, containerList) {\n\t\t\tcontainerList.push(pnfd);\n\t\t}\n\n\t\treturn (containerList, obj) => {\n\t\t\tif (_.isEmpty(obj)) {\n\t\t\t\treturn containerList;\n\t\t\t}\n\t\t\tswitch (obj.meta.type) {\n\t\t\tcase 'nsd':\n\t\t\t\tmapNSD(DescriptorModelFactory.newNetworkService(obj), containerList);\n\t\t\t\tbreak;\n\t\t\tcase 'vnfd':\n\t\t\t\tmapVNFD(DescriptorModelFactory.newVirtualNetworkFunction(obj), containerList);\n\t\t\t\tbreak;\n\t\t\tcase 'pnfd':\n\t\t\t\tmapPNFD(DescriptorModelFactory.newPhysicalNetworkFunction(obj), containerList);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new ReferenceError('only catalog items can be rendered in the canvas. unexpected type: ' + obj.meta.type);\n\t\t\t}\n\t\t\treturn containerList;\n\t\t};\n\n\t}\n\n\tstatic newNetworkService(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new NetworkService(model, parent);\n\t}\n\n\tstatic newConstituentVnfd(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfd(model, parent);\n\t}\n\n\tstatic newVirtualNetworkFunction(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunction(model, parent);\n\t}\n\n\tstatic newConnectionPoint(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new ConnectionPoint(model, parent);\n\t}\n\n\tstatic newInternalConnectionPoint(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new InternalConnectionPoint(model, parent);\n\t}\n\n\tstatic newVirtualDeploymentUnit(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnit(model, parent);\n\t}\n\n\tstatic newVirtualLink(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualLink(model, parent);\n\t}\n\n\tstatic newInternalVirtualLink(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new InternalVirtualLink(model, parent);\n\t}\n\n\tstatic newPhysicalNetworkFunction(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new PhysicalNetworkFunction(model, parent);\n\t}\n\n\tstatic newConstituentVnfdConnectionPoint(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfdConnectionPoint(model, parent);\n\t}\n\n\tstatic newVnfdConnectionPointRef(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new VnfdConnectionPointRef(model, parent);\n\t}\n\n\tstatic newForwardingGraph(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new ForwardingGraph(model, parent);\n\t}\n\n\tstatic newRecordServicePath(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new RecordServicePath(model, parent);\n\t}\n\n\tstatic newRspConnectionPointRef(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new RspConnectionPointRef(model, parent);\n\t}\n\n\tstatic newVirtualNetworkFunctionReadOnlyWrapper(vnfdToWrap, parent) {\n\t\tlet model;\n\t\tif (vnfdToWrap instanceof DescriptorModel) {\n\t\t\tif (vnfdToWrap instanceof VirtualNetworkFunction) {\n\t\t\t\tmodel = vnfdToWrap.model;\n\t\t\t} else {\n\t\t\t\tthrow new ReferenceError(`expected a VirtualNetworkFunction but got a ${vnfdToWrap.className}`);\n\t\t\t}\n\t\t} else {\n\t\t\tmodel = vnfdToWrap;\n\t\t}\n\t\treturn new VirtualNetworkFunctionReadOnlyWrapper(_.cloneDeep(model), parent);\n\t}\n\n\tstatic newClassifier(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new Classifier(model, parent);\n\t}\n\n\tstatic newClassifierMatchAttributes(model, parent) {\n\t\treturn findChildDescriptorModelAndUpdateModel(model, parent) || new ClassifierMatchAttributes(model, parent);\n\t}\n\n\t/**\n\t * Special instance of a RecordServicePath that will create its parent ForwardingGraph it does not exist.\n\t *\n\t * This is useful to present a stub RSP as an initiator to create Paths without explicitly creating an RSP - just\n\t * start building a path and it auto-magically builds the RSP.\n\t *\n\t * @param parent\n\t * @param model\n\t */\n\tstatic newRecordServicePathFactory(model, parent) {\n\t\treturn new AutoCreateRecordServicePath(model, parent);\n\t}\n\n\tstatic isContainer(obj) {\n\t\treturn obj instanceof DescriptorModel;\n\t}\n\n\tstatic isConnector(obj) {\n\t\treturn obj instanceof ConnectionPoint;\n\t}\n\n\tstatic isConnectionPoint(obj) {\n\t\treturn obj instanceof ConnectionPoint;\n\t}\n\n\tstatic isConstituentVnfd(obj) {\n\t\treturn obj instanceof ConstituentVnfd;\n\t}\n\n\tstatic isNetworkService(obj) {\n\t\treturn obj instanceof NetworkService;\n\t}\n\n\tstatic isVnfdConnectionPointRef(obj) {\n\t\treturn obj instanceof VnfdConnectionPointRef;\n\t}\n\n\tstatic isRecordServicePath(obj) {\n\t\treturn obj instanceof RecordServicePath;\n\t}\n\n\tstatic isRspConnectionPointRef(obj) {\n\t\treturn obj instanceof RspConnectionPointRef;\n\t}\n\n\tstatic isVirtualLink(obj) {\n\t\treturn obj instanceof VirtualLink;\n\t}\n\n\tstatic isVirtualNetworkFunction(obj) {\n\t\treturn obj instanceof VirtualNetworkFunction;\n\t}\n\n\tstatic isForwardingGraph(obj) {\n\t\treturn obj instanceof ForwardingGraph;\n\t}\n\n\tstatic get VirtualLink () {\n\t\treturn VirtualLink;\n\t}\n\n\tstatic get NetworkService () {\n\t\treturn NetworkService;\n\t}\n\n\tstatic get ForwardingGraph () {\n\t\treturn ForwardingGraph;\n\t}\n\n\tstatic get VirtualNetworkFunction () {\n\t\treturn VirtualNetworkFunction;\n\t}\n\n\tstatic get ConstituentVnfd () {\n\t\treturn ConstituentVnfd;\n\t}\n\n\tstatic get Classifier() {\n\t\treturn Classifier;\n\t}\n\n\tstatic get ClassifierMatchAttribute() {\n\t\treturn ClassifierMatchAttributes;\n\t}\n\n\tstatic get VnfdConnectionPointRef() {\n\t\treturn VnfdConnectionPointRef;\n\t}\n\n\tstatic get VirtualDeploymentUnit() {\n\t\treturn VirtualDeploymentUnit;\n\t}\n\n}\n\n/**\n * Auto create a RecordServicePath when a VnfdConnectionPointRef is added.\n */\nclass AutoCreateRecordServicePath extends RecordServicePath {\n\n\tconstructor(model, parent) {\n\t\tsuper(model, null);\n\t\tthis.parent = parent;\n\t\tthis.isFactory = true;\n\t}\n\n\tcreate() {\n\t\treturn this.parent.createRsp();\n\t}\n\n\tcreateVnfdConnectionPointRef(obj) {\n\t\tconst rsp = this.create();\n\t\trsp.createVnfdConnectionPointRef(obj);\n\t\treturn rsp;\n\t}\n\n}\n\nexport default DescriptorModelFactory;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorModelFactory.js\n **/","/**\n * Created by onvelocity on 2/3/16.\n */\n'use strict';\nconst pairedColors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99','#b15928'];\n\nimport colorTheme from 'json!../assets/rift.ware-color-theme.json'\n\n/**\n *\n * Colors are also defined in _ColorGroups.scss. HINT: Uncomment the console statement at the bottom of this file to\n * generate the variables and then copy and paste them into the .scss file.\n *\n * Externalized colors into a .json file to make it easier to modify them.\n */\nconst ColorGroups = {\n\t// http://colorbrewer2.org/?type=qualitative&scheme=Paired&n=12\n\tgetColorPair(index) {\n\t\tindex = index - 1;\n\t\t// make sure index is not larger than our list of colors\n\t\tindex = (index * 2) % 12;\n\t\treturn {\n\t\t\tprimary: pairedColors[index + 1],\n\t\t\tsecondary: pairedColors[index]\n\t\t};\n\t},\n\tgetColorCSS() {\n\t\treturn Object.keys(colorTheme).map((key) => {\n\t\t\tif (typeof colorTheme[key] === 'object') {\n\t\t\t\tconst color = colorTheme[key];\n\t\t\t\treturn Object.keys(color).map(name => {\n\t\t\t\t\treturn `\\$${key}-${name}-color: ${color[name]};`\n\t\t\t\t}).join('\\n');\n\t\t\t}\n\t\t\tif (typeof colorTheme[key] === 'string') {\n\t\t\t\tconst color = colorTheme[key];\n\t\t\t\treturn `$descriptor-${key}: ${color};\\n\\n`\n\t\t\t}\n\t\t}).join('\\n\\n');\n\t},\n\tgetColorPairForType(type) {\n\t\tconst colors = colorTheme[type];\n\t\tif (colors) {\n\t\t\treturn colors;\n\t\t}\n\t\treturn colorTheme.common;\n\t}\n};\n\n//console.log(ColorGroups.getColorCSS());\n\nObject.assign(ColorGroups, colorTheme);\n\nexport default ColorGroups;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/ColorGroups.js\n **/","module.exports = {\n\t\"nsd\": {\n\t\t\"primary\": \"#6c71c4\",\n\t\t\"secondary\": \"#6c71c4\"\n\t},\n\t\"vld\": {\n\t\t\"primary\": \"#073642\",\n\t\t\"secondary\": \"#073642\"\n\t},\n\t\"vdu\": {\n\t\t\"primary\": \"#b58900\",\n\t\t\"secondary\": \"#b58900\"\n\t},\n\t\"vnfd\": {\n\t\t\"primary\": \"#268bd2\",\n\t\t\"secondary\": \"#268bd2\"\n\t},\n\t\"constituent-vnfd\": {\n\t\t\"primary\": \"#268bd2\",\n\t\t\"secondary\": \"#268bd2\"\n\t},\n\t\"vnffgd\": {\n\t\t\"primary\": \"#2aa198\",\n\t\t\"secondary\": \"#2aa198\"\n\t},\n\t\"common\": {\n\t\t\"primary\": \"black\",\n\t\t\"secondary\": \"white\",\n\t\t\"background\": \"white\",\n\t\t\"foreground\": \"black\"\n\t}\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/json-loader!./src/assets/rift.ware-color-theme.json\n ** module id = 428\n ** module chunks = 0\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport Position from '../../graph/Position'\nimport DescriptorModel from '../DescriptorModel'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\nimport RspConnectionPointRef from './RspConnectionPointRef'\nimport VnfdConnectionPointRef from './VnfdConnectionPointRef'\n\n/**\n * A ConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience\n * methods are add to access the fields needed to do that.\n */\nexport default class Classifier extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'classifier';\n\t}\n\n\tstatic get className() {\n\t\treturn 'Classifier';\n\t}\n\n\tstatic get qualifiedType() {\n\t\treturn 'nsd.vnffgd.rsp.classifier';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = Classifier.type;\n\t\tthis.meta['qualified-type'] = Classifier.qualifiedType;\n\t\tthis.className = Classifier.className;\n\t\tthis.position = new Position();\n\t}\n\n\tget matchAttributes() {\n\t\tif (!this.model['match-attributes']) {\n\t\t\tthis.model['match-attributes'] = {};\n\t\t}\n\t\treturn DescriptorModelFactory.newClassifierMatchAttributes(this.model['match-attributes'], this);\n\t}\n\n\tset matchAttributes(obj) {\n\t\tthis.model['match-attributes'] = obj.model;\n\t}\n\n\tremoveMatchAttributes(child) {\n\t\tthis.matchAttributes = null;\n\t\tthis.removeChild(child);\n\t}\n\n\tremove() {\n\t\treturn this.parent.removeClassifier(this);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/Classifier.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport VnfdConnectionPointRef from './VnfdConnectionPointRef'\n\nexport default class RspConnectionPointRef extends VnfdConnectionPointRef {\n\n\tstatic get type() {\n\t\treturn 'rsp-connection-point-ref';\n\t}\n\n\tstatic get className() {\n\t\treturn 'RspConnectionPointRef';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'rsp-connection-point-ref';\n\t\tthis.meta['qualified-type'] = 'nsd.vnffgd.rsp.vnfd-connection-point-ref';\n\t\tthis.className = 'RspConnectionPointRef';\n\t}\n\n\tremove() {\n\t\treturn this.parent.removeRspConnectionPointRef(this);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/RspConnectionPointRef.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\n\n/**\n * This class creates the identity of a ConnectionPoint on a VNFD. Visually\n * this class represents an svg:Path between the parent VLD and ConnectionPoint.\n *\n *     VNFD.ConnectionPoint ====path==== VLD\n *\n * The VNFD is referenced by nsd.constituent-vnfd.member-vnf-index.\n * The ConnectionPoint is referenced by vnfd.connection-point.name.\n */\nexport default class VnfdConnectionPointRef extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'vnfd-connection-point-ref';\n\t}\n\n\tstatic get className() {\n\t\treturn 'VnfdConnectionPointRef';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'vnfd-connection-point-ref';\n\t\tthis.meta['qualified-type'] = 'nsd.vld.vnfd-connection-point-ref';\n\t\tthis.className = 'VnfdConnectionPointRef';\n\t}\n\n\tget key() {\n\t\treturn this.model['member-vnf-index-ref'] + '/' + this.model['vnfd-connection-point-ref'];\n\t}\n\n\tget title() {\n\t\treturn this.type;\n\t}\n\n\tget vnfdId() {\n\t\treturn this.model['vnfd-id-ref'];\n\t}\n\n\tset vnfdId(id) {\n\t\treturn this.model['vnfd-id-ref'] = id;\n\t}\n\n\tget vnfdIndex() {\n\t\treturn this.model['member-vnf-index-ref'];\n\t}\n\n\tset vnfdIndex(index) {\n\t\treturn this.model['member-vnf-index-ref'] = index;\n\t}\n\n\tget vnfdConnectionPointName() {\n\t\treturn this.model['vnfd-connection-point-ref'];\n\t}\n\n\tset vnfdConnectionPointName(name) {\n\t\treturn this.model['vnfd-connection-point-ref'] = name;\n\t}\n\n\tget cpNumber() {\n\t\treturn this.meta.cpNumber;\n\t}\n\n\tset cpNumber(n) {\n\t\tthis.meta.cpNumber = n;\n\t}\n\n\tremove() {\n\t\tif (this.parent) {\n\t\t\treturn this.parent.removeVnfdConnectionPointRefKey(this.key);\n\t\t}\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/VnfdConnectionPointRef.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport Position from '../../graph/Position'\nimport DescriptorModel from '../DescriptorModel'\nimport RspConnectionPointRef from './RspConnectionPointRef'\nimport VnfdConnectionPointRef from './VnfdConnectionPointRef'\n\n/**\n * A ConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience\n * methods are add to access the fields needed to do that.\n */\nexport default class ClassifierMatchAttributes extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'match-attributes';\n\t}\n\n\tstatic get className() {\n\t\treturn 'ClassifierMatchAttributes';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = ClassifierMatchAttributes.type;\n\t\tthis.meta['qualified-type'] = 'nsd.vnffgd.rsp.classifier.match-attributes';\n\t\tthis.className = ClassifierMatchAttributes.className;\n\t\tthis.position = new Position();\n\t}\n\n\tgetFieldValue(name) {\n\t\treturn this.model[name];\n\t}\n\n\tsetFieldValue(name, value) {\n\t\tthis.model[name] = value;\n\t}\n\n\tremove() {\n\t\treturn this.parent.removeMatchAttributes(this);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/ClassifierMatchAttributes.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport Position from '../../graph/Position'\nimport DescriptorModel from '../DescriptorModel'\nimport RspConnectionPointRef from './RspConnectionPointRef'\nimport VnfdConnectionPointRef from './VnfdConnectionPointRef'\n\n/**\n * A ConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience\n * methods are add to access the fields needed to do that.\n */\nexport default class ConnectionPoint extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'connection-point';\n\t}\n\n\tstatic get className() {\n\t\treturn 'ConnectionPoint';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'connection-point';\n\t\tthis.meta['qualified-type'] = 'vnfd.connection-point';\n\t\tthis.className = 'ConnectionPoint';\n\t\tthis.location = 'bottom-left';\n\t\tthis.position = new Position(parent.position.value());\n\t\tthis.position.top = parent.position.bottom;\n\t\tthis.position.width = 14;\n\t\tthis.position.height = 14;\n\t}\n\n\tget id() {\n\t\treturn this.model.name;\n\t}\n\n\tget key() {\n\t\treturn this.parent.key + '/' + this.model.name;\n\t}\n\n\tget name() {\n\t\treturn this.model.name;\n\t}\n\n\tget vnfdIndex() {\n\t\treturn this.parent.vnfdIndex;\n\t}\n\n\tget vnfdId() {\n\t\treturn this.parent.vnfdId;\n\t}\n\n\tget cpNumber() {\n\t\treturn this.meta.cpNumber;\n\t}\n\n\tset cpNumber(n) {\n\t\tthis.meta.cpNumber = n;\n\t}\n\n\t/**\n\t * Convenience method to generate a VnfdConnectionPointRef instance from any given ConnectionPoint.\n\t *\n\t * @returns {RspConnectionPointRef}\n\t */\n\ttoRspConnectionPointRef() {\n\t\tconst ref = new RspConnectionPointRef({});\n\t\tref.vnfdId = this.vnfdId;\n\t\tref.vnfdIndex = this.vnfdIndex;\n\t\tref.vnfdConnectionPointName = this.name;\n\t\tref.cpNumber = this.cpNumber;\n\t\treturn ref;\n\t}\n\n\ttoVnfdConnectionPointRef() {\n\t\tconst ref = new VnfdConnectionPointRef({});\n\t\tref.vnfdId = this.vnfdId;\n\t\tref.vnfdIndex = this.vnfdIndex;\n\t\tref.vnfdConnectionPointName = this.name;\n\t\tref.cpNumber = this.cpNumber;\n\t\treturn ref;\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/ConnectionPoint.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\n\nexport default class ConstituentVnfd extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'constituent-vnfd';\n\t}\n\n\tstatic get className() {\n\t\treturn 'ConstituentVnfd';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'constituent-vnfd';\n\t\tthis.meta['qualified-type'] = 'nsd.constituent-vnfd';\n\t\tthis.className = 'ConstituentVnfd';\n\t\tthis.addProp('vnfdRef', DescriptorModelFactory.newVirtualNetworkFunctionReadOnlyWrapper({}, this));\n\t}\n\n\tget id() {\n\t\treturn this.vnfdIndex;\n\t}\n\n\tget vld() {\n\t\tif (this.vnfdRef) {\n\t\t\treturn this.vnfdRef.vld;\n\t\t}\n\t\treturn [];\n\t}\n\n\tget connectionPoint() {\n\t\tif (this.vnfdRef) {\n\t\t\treturn this.vnfdRef.connectionPoint;\n\t\t}\n\t\treturn [];\n\t}\n\n\tget connectors() {\n\t\treturn this.connectionPoint\n\t}\n\n\tget vnfdRef() {\n\t\treturn this.getProp('vnfdRef');\n\t}\n\n\tset vnfdRef(ref) {\n\t\tthis.addProp('vnfdRef', DescriptorModelFactory.newVirtualNetworkFunctionReadOnlyWrapper(ref, this));\n\t\t// since this vnfd reference is not part of\n\t\t// the YANG, we need to provide info needed\n\t\t// for the details editor to manipulate it.\n\t\tthis.meta.vnfdIndex = this.vnfdIndex;\n\t\tthis.meta.displayName = this.title;\n\t}\n\n\tget vnfdIndex() {\n\t\treturn this.model['member-vnf-index'];\n\t}\n\n\tset vnfdIndex(index) {\n\t\tthis.model['member-vnf-index'] = index;\n\t}\n\n\tget vnfdId() {\n\t\treturn this.model['vnfd-id-ref'];\n\t}\n\n\tset vnfdId(id) {\n\t\tthis.model['vnfd-id-ref'] = id;\n\t}\n\n\tget name() {\n\t\treturn this.vnfdRef.model.name;\n\t}\n\n\tget 'short-name'() {\n\t\treturn this.vnfdRef.model['short-name'];\n\t}\n\n\tget title() {\n\t\treturn this['short-name'] || this.name;\n\t}\n\n\tremove() {\n\t\treturn this.parent.removeConstituentVnfd(this);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/ConstituentVnfd.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport ConnectionPoint from './ConnectionPoint'\n\nexport default class ConstituentVnfdConnectionPoint extends ConnectionPoint {\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/ConstituentVnfdConnectionPoint.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport DescriptorModel from '../DescriptorModel'\nimport RecordServicePath from './RecordServicePath'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\nimport DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'\n\nexport default class ForwardingGraph extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'vnffgd';\n\t}\n\n\tstatic get className() {\n\t\treturn 'ForwardingGraph';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'vnffgd';\n\t\tthis.meta['qualified-type'] = 'nsd.vnffgd';\n\t\tthis.className = 'ForwardingGraph';\n\t}\n\n\tget rsp() {\n\t\tif (!this.model.rsp) {\n\t\t\tthis.model.rsp = [];\n\t\t}\n\t\treturn this.model.rsp.map(d => DescriptorModelFactory.newRecordServicePath(d, this));\n\t}\n\n\tset rsp(obj) {\n\t\tthis.updateModelList('rsp', obj, RecordServicePath);\n\t}\n\n\tcreateRsp() {\n\t\tconst model = DescriptorModelMetaFactory.createModelInstanceForType('nsd.vnffgd.rsp');\n\t\treturn this.rsp = new RecordServicePath(model, this);\n\t}\n\n\tremoveRsp(obj) {\n\t\tthis.children.filter(d => d.id === obj.id).forEach(rsp => rsp.remove());\n\t}\n\n\tget recordServicePaths() {\n\t\treturn this.rsp;\n\t}\n\n\tremoveRecordServicePath(child) {\n\t\tthis.rsp = this.rsp.filter(rsp => rsp.uid !== child.uid);\n\t\tthis.removeChild(child);\n\t}\n\n\tremove() {\n\t\tif (this.parent) {\n\t\t\t// nothing for vnffgd to do so let the parent remove this instance\n\t\t\treturn this.parent.removeVnffgd(this);\n\t\t}\n\t}\n\n\tgetColor() {\n\n\t}\n\n\tremoveVnfdConnectionPointRefForVnfdIndex(vnfdIndex) {\n\t\tthis.rsp.forEach(rsp => rsp.removeVnfdConnectionPointRefForVnfdIndex(vnfdIndex));\n\t}\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/ForwardingGraph.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport Classifier from './Classifier'\nimport DescriptorModel from '../DescriptorModel'\nimport RspConnectionPointRef from './RspConnectionPointRef'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\nimport DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'\n\nexport default class RecordServicePath extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'rsp';\n\t}\n\n\tstatic get className() {\n\t\treturn 'RecordServicePath';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'rsp';\n\t\tthis.meta['qualified-type'] = 'nsd.vnffgd.rsp';\n\t\tthis.className = 'RecordServicePath';\n\t}\n\n\tget vnfdConnectionPointRef() {\n\t\tif (!this.model['vnfd-connection-point-ref']) {\n\t\t\tthis.model['vnfd-connection-point-ref'] = [];\n\t\t}\n\t\treturn this.model['vnfd-connection-point-ref'].map(d => DescriptorModelFactory.newRspConnectionPointRef(d, this));\n\t}\n\n\tset vnfdConnectionPointRef(obj) {\n\t\tthis.updateModelList('vnfd-connection-point-ref', obj, RspConnectionPointRef);\n\t}\n\n\tcreateVnfdConnectionPointRef(connectionPoint) {\n\t\tlet ref;\n\t\tif (DescriptorModelFactory.isConnectionPoint(connectionPoint)) {\n\t\t\tref = connectionPoint.toRspConnectionPointRef();\n\t\t} else {\n\t\t\tconst model = DescriptorModelMetaFactory.createModelInstanceForType('nsd.vnffgd.rsp.vnfd-connection-point-ref');\n\t\t\tref = new RspConnectionPointRef(model, this);\n\t\t}\n\t\tthis.vnfdConnectionPointRef = ref;\n\t\treturn ref;\n\t}\n\n\tget connectionPoints() {\n\t\treturn this.vnfdConnectionPointRef;\n\t}\n\n\tget classifier() {\n\t\tif (!this.model['classifier']) {\n\t\t\tthis.model['classifier'] = [];\n\t\t}\n\t\treturn this.model['classifier'].map(d => DescriptorModelFactory.newClassifier(d, this));\n\t}\n\n\tset classifier(obj) {\n\t\tthis.updateModelList('classifier', obj, Classifier);\n\t}\n\n\tcreateClassifier(model) {\n\t\tmodel = model || DescriptorModelMetaFactory.createModelInstanceForType(DescriptorModelFactory.Classifier.qualifiedType);\n\t\treturn this.classifier = DescriptorModelFactory.newClassifier(model, this);\n\t}\n\n\tremoveClassifier(child) {\n\t\treturn this.removeModelListItem('classifier', child);\n\t}\n\n\tremove() {\n\t\treturn this.parent.removeRecordServicePath(this);\n\t}\n\n\t/**\n\t * Remove all connection points refs associate with this vnfd.\n\t *\n\t * @param vnfdIndex\n\t */\n\tremoveVnfdConnectionPointRefForVnfdIndex(vnfdIndex) {\n\t\tif (typeof vnfdIndex !== 'undefined') {\n\t\t\tconst len = this.vnfdConnectionPointRef.length;\n\t\t\tthis.vnfdConnectionPointRef = this.vnfdConnectionPointRef.filter(d => d.vnfdIndex !== vnfdIndex);\n\t\t\treturn len !== this.vnfdConnectionPointRef.length;\n\t\t}\n\t}\n\n\tremoveRspConnectionPointRef(child) {\n\t\treturn this.removeModelListItem('vnfdConnectionPointRef', child);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/RecordServicePath.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport ConnectionPoint from './ConnectionPoint'\n\nexport default class InternalConnectionPoint extends ConnectionPoint {\n\n\tstatic get type() {\n\t\treturn 'internal-connection-point';\n\t}\n\n\tstatic get className() {\n\t\treturn 'InternalConnectionPoint';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.className = 'InternalConnectionPoint';\n\t\tthis.type = 'internal-connection-point';\n\t}\n\n\tget key() {\n\t\treturn this.parent.key + '/' + this.model.key;\n\t}\n\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/InternalConnectionPoint.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\n\nexport default class InternalVirtualLink extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'internal-vld';\n\t}\n\n\tstatic get className() {\n\t\treturn 'InternalVirtualLink';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'internal-vld';\n\t\tthis.className = 'InternalVirtualLink';\n\t}\n\n\tget title() {\n\t\treturn this.name || this['short-name'] || (this.model.type + '/' + this.id);\n\t}\n\n\tget connection() {\n\t\tif (this.model && this.model['internal−connection−points']) {\n\t\t\treturn this.model['internal−connection−points'];\n\t\t}\n\t\treturn [];\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/InternalVirtualLink.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport _ from 'lodash'\nimport ColorGroups from '../../ColorGroups'\nimport DescriptorModel from '../DescriptorModel'\nimport ForwardingGraph from './ForwardingGraph'\nimport VirtualLink from './VirtualLink'\nimport ConstituentVnfd from './ConstituentVnfd'\nimport PhysicalNetworkFunction from './PhysicalNetworkFunction'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\nimport DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'\n\nconst indexAsInteger = d => 1 + parseInt(d.model['member-vnf-index'], 10);\n\nconst suffixAsInteger = function (field) {\n\treturn (d) => 1 + parseInt(String(d.model[field]).split('').reverse().join(''), 10) || 0;\n};\n\nconst toBiggestValue = (newIndex, curIndex) => Math.max(newIndex, curIndex);\n\nexport default class NetworkService extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'nsd';\n\t}\n\n\tstatic get className() {\n\t\treturn 'NetworkService';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'nsd';\n\t\tthis.className = 'NetworkService';\n\t\tthis._connectors = [];\n\t}\n\n\tget constituentVnfd() {\n\t\tif (!this.model['constituent-vnfd']) {\n\t\t\tthis.model['constituent-vnfd'] = [];\n\t\t}\n\t\treturn this.model['constituent-vnfd'].map(d => DescriptorModelFactory.newConstituentVnfd(d, this));\n\t}\n\n\tset constituentVnfd(obj) {\n\t\tconst updateNextVnfdIndex = (cvnfd) => {\n\t\t\tcvnfd.model['member-vnf-index'] = this.constituentVnfd.map(indexAsInteger).reduce(toBiggestValue, this.constituentVnfd.length);\n\t\t};\n\t\tthis.updateModelList('constituent-vnfd', obj, ConstituentVnfd, updateNextVnfdIndex);\n\t}\n\n\tcreateConstituentVnfd(model) {\n\t\tmodel = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.constituent-vnfd');\n\t\treturn this.constituentVnfd = DescriptorModelFactory.newConstituentVnfd(model, this);\n\t}\n\n\tremoveConstituentVnfd(cvnfd) {\n\t\tcvnfd = this.findChildByUid(cvnfd);\n\t\tthis.vld.forEach(vld => vld.removeVnfdConnectionPointRefForVnfdIndex(cvnfd.vnfdIndex));\n\t\tthis.vnffgd.forEach(fg => fg.removeVnfdConnectionPointRefForVnfdIndex(cvnfd.vnfdIndex));\n\t\treturn this.removeModelListItem('constituentVnfd', cvnfd);\n\t}\n\n\tget pnfd() {\n\t\tif (!this.model.pnfd) {\n\t\t\tthis.model.pnfd = [];\n\t\t}\n\t\treturn this.model.pnfd.map(d => DescriptorModelFactory.newPhysicalNetworkFunction(d, this));\n\t}\n\n\tset pnfd(obj) {\n\t\tthis.updateModelList('pnfd', obj, PhysicalNetworkFunction);\n\t}\n\n\tcreatePnfd(model) {\n\t\tmodel = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.pnfd');\n\t\treturn this.pnfd = DescriptorModelFactory.newPhysicalNetworkFunction(model, this);\n\t}\n\n\tremovePnfd(pnfd) {\n\t\treturn this.removeModelListItem('pnfd', pnfd);\n\t}\n\n\n\tget vld() {\n\t\tif (!this.model.vld) {\n\t\t\tthis.model.vld = [];\n\t\t}\n\t\treturn this.model.vld.map(d => DescriptorModelFactory.newVirtualLink(d, this));\n\t}\n\n\tset vld(obj) {\n\t\tthis.updateModelList('vld', obj, VirtualLink);\n\t}\n\n\tcreateVld() {\n\t\tconst model = DescriptorModelMetaFactory.createModelInstanceForType('nsd.vld');\n\t\treturn this.vld = DescriptorModelFactory.newVirtualLink(model, this);\n\t}\n\n\tremoveVLD(vld) {\n\t\treturn this.removeModelListItem('vld', vld);\n\t}\n\n\n\tget vnffgd() {\n\t\tif (!this.model.vnffgd) {\n\t\t\tthis.model.vnffgd = [];\n\t\t}\n\t\treturn this.model.vnffgd.map(d => DescriptorModelFactory.newForwardingGraph(d, this));\n\t}\n\n\tset vnffgd(obj) {\n\t\tconst onAddForwardingGraph = (fg) => {\n\t\t\tconst index = this.vnffgd.map(suffixAsInteger('short-name')).reduce(toBiggestValue, this.vnffgd.length);\n\t\t\tfg.model['short-name'] = 'FG-' + index;\n\t\t\tfg.meta.colors = ColorGroups.getColorPair(index);\n\t\t};\n\t\tthis.updateModelList('vnffgd', obj, ForwardingGraph, onAddForwardingGraph);\n\t}\n\n\tcreateVnffgd(model) {\n\t\tmodel = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.vnffgd');\n\t\treturn this.vnffgd = DescriptorModelFactory.newForwardingGraph(model, this);\n\t}\n\n\tremoveVnffgd(fg) {\n\t\treturn this.removeModelListItem('vnffgd', fg);\n\t}\n\n\tget forwardingGraphs() {\n\t\treturn this.vnffgd;\n\t}\n\n\n\t// NOTE temporarily disable NSD connection points\n\t// https://trello.com/c/crVgg2A1/88-do-not-render-nsd-connection-in-the-composer\n\t//get connectionPoint() {\n\t//\tif (this.model && this.model['connection-point']) {\n\t//\t\treturn this.model['connection-point'];\n\t//\t}\n\t//\treturn [];\n\t//}\n\t//\n\t//get connectors() {\n\t//\tconst parent = this;\n\t//\tif (!this._connectors.length) {\n\t//\t\tthis._connectors = this.connectionPoint.map(cp => {\n\t//\t\t\treturn DescriptorModelFactory.newConnectionPoint(parent, cp);\n\t//\t\t});\n\t//\t}\n\t//\treturn this._connectors;\n\t//}\n\n\tremoveAnyConnectionsForConnector(cpc) {\n\t\t// todo need to also remove connection points from related ForwardingGraph paths\n\t\tthis.vld.map(vld => DescriptorModelFactory.newVirtualLink(vld)).forEach(vldc => vldc.removeVnfdConnectionPointRefKey(cpc.key));\n\t}\n\n\tcreateConstituentVnfdForVnfd(vnfdRef) {\n\t\tconst cvnfd = this.createConstituentVnfd();\n\t\tcvnfd.vnfdRef = vnfdRef;\n\t\tcvnfd.vnfdId = vnfdRef.id;\n\t\treturn cvnfd;\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/NetworkService.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport UID from '../../../libraries/UniqueId'\nimport DescriptorModel from '../DescriptorModel'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\nimport DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'\n\nexport default class VirtualLink extends DescriptorModel {\n\n\tstatic get className() {\n\t\treturn 'VirtualLink';\n\t}\n\n\tstatic get type() {\n\t\treturn 'vld';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'vld';\n\t\tthis.className = VirtualLink.className;\n\t}\n\n\tget title() {\n\t\tconst title = this.model['short-name'] || this.model.name || (this.model.type + '/' + this.id);\n\t\tif (title && title.length > 18) {\n\t\t\treturn title.substr(0, 18) + '...';\n\t\t}\n\t\treturn title;\n\t}\n\n\tget connection() {\n\t\tif (!this.model['vnfd-connection-point-ref']) {\n\t\t\tthis.model['vnfd-connection-point-ref'] = [];\n\t\t}\n\t\treturn this.model['vnfd-connection-point-ref'].map(d => DescriptorModelFactory.newVnfdConnectionPointRef(d, this));\n\t}\n\n\tset connection(connections) {\n\t\tthis.updateModelList('vnfd-connection-point-ref', connections, DescriptorModelFactory.VnfdConnectionPointRef);\n\t}\n\n\tcreateVnfdConnectionPointRef(model) {\n\t\tmodel = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.vld.vnfd-connection-point-ref');\n\t\treturn this.connection = DescriptorModelFactory.newVnfdConnectionPointRef(model, this);\n\t}\n\n\tremoveVnfdConnectionPointRefKey(cpRefKey) {\n\t\tconst child = this.connection.filter(d => d.key === cpRefKey)[0];\n\t\treturn this.removeModelListItem('connection', child);\n\t}\n\n\taddConnectionPoint(cp) {\n\t\tconst cpRef = cp.toVnfdConnectionPointRef();\n\t\tthis.connection = this.connection.concat(cpRef);\n\t}\n\n\tfindConnectionPointRef(vnfdId, vnfdIndex, vnfdConnectionPointName) {\n\t\treturn this.connection.filter(d => d.vnfdId === vnfdId && d.vnfdIndex === vnfdIndex && d.vnfdConnectionPointName === vnfdConnectionPointName)[0];\n\t}\n\n\tremove() {\n\t\tconst nsdc = this.parent;\n\t\treturn nsdc.removeVLD(this);\n\t}\n\n\tremoveVnfdConnectionPointRefForVnfdIndex(vnfdIndex) {\n\t\tconst size = this.connection.length;\n\t\tif (typeof vnfdIndex !== 'undefined') {\n\t\t\tthis.connection = this.connection.filter(d => d.vnfdIndex !== vnfdIndex).map(d => d.model);\n\t\t}\n\t\treturn size !== this.connection.length;\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/VirtualLink.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\n\nexport default class PhysicalNetworkFunction extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'pnfd';\n\t}\n\n\tstatic get className() {\n\t\treturn 'PhysicalNetworkFunction';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'pnfd';\n\t\tthis.className = 'PhysicalNetworkFunction';\n\t}\n\n\tget connectionPoint() {\n\t\tif (this.model && this.model['connection-points']) {\n\t\t\treturn this.model['connection-points'];\n\t\t}\n\t\treturn [];\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/PhysicalNetworkFunction.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\n\nexport default class VirtualDeploymentUnit extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'vdu';\n\t}\n\n\tstatic get className() {\n\t\treturn 'VirtualDeploymentUnit';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'vdu';\n\t\tthis.meta['qualified-type'] = 'vnfd.vdu';\n\t\tthis.className = 'VirtualDeploymentUnit';\n\t\tthis._connectors = [];\n\t}\n\n\tget key() {\n\t\treturn this.parent.key + '/' + super.key;\n\t}\n\n\tget internalConnectionPoint() {\n\t\t//https://trello.com/c/ZOyKQd3z/122-hide-lines-representing-interface-connection-point-references-both-internal-and-external-interfaces\n\t\tconst vduc = this;\n\t\tif (this.model && this.model['internal-interface']) {\n\t\t\tconst icpMap = this.model['internal-connection-point'].reduce((r, d) => {\n\t\t\t\tr[d.id] = d;\n\t\t\t\treturn r;\n\t\t\t}, {});\n\t\t\treturn this.model['internal-interface'].reduce((result, internalIfc) => {\n\t\t\t\tconst id = internalIfc['vdu-internal-connection-point-ref'];\n\t\t\t\tconst keyPrefix = vduc.parent ? vduc.parent.key + '/' : '';\n\t\t\t\tconst icp = Object.assign({}, icpMap[id], {\n\t\t\t\t\tkey: keyPrefix + id,\n\t\t\t\t\tname: internalIfc.name,\n\t\t\t\t\t'virtual-interface': internalIfc['virtual-interface']\n\t\t\t\t});\n\t\t\t\tresult.push(icp);\n\t\t\t\treturn result;\n\t\t\t}, []);\n\t\t}\n\t\treturn [];\n\t}\n\n\tget externalConnectionPoint() {\n\t\t// https://trello.com/c/ZOyKQd3z/122-hide-lines-representing-interface-connection-point-references-both-internal-and-external-interfaces\n\t\t//const vduc = this;\n\t\t//if (vduc.model && vduc.model['external-interface']) {\n\t\t//\treturn vduc.model['external-interface'].reduce((result, externalIfc) => {\n\t\t//\t\tconst id = externalIfc['vnfd-connection-point-ref'];\n\t\t//\t\tconst keyPrefix = vduc.parent ? vduc.parent.key + '/' : '';\n\t\t//\t\tresult.push({id: id, key: keyPrefix + id});\n\t\t//\t\treturn result;\n\t\t//\t}, []);\n\t\t//}\n\t\treturn [];\n\t}\n\n\tget connectors() {\n\t\tif (!this._connectors.length) {\n\t\t\tthis._connectors = this.internalConnectionPoint.map(icp => {\n\t\t\t\treturn DescriptorModelFactory.newInternalConnectionPoint(icp, this);\n\t\t\t});\n\t\t}\n\t\treturn this._connectors;\n\t}\n\n\tget connection() {\n\t\treturn this.externalConnectionPoint;\n\t}\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/VirtualDeploymentUnit.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\n\nexport default class VirtualNetworkFunction extends DescriptorModel {\n\n\tstatic get type() {\n\t\treturn 'vnfd';\n\t}\n\n\tstatic get className() {\n\t\treturn 'VirtualNetworkFunction';\n\t}\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t\tthis.type = 'vnfd';\n\t\tthis.className = 'VirtualNetworkFunction';\n\t}\n\n\tget vdu() {\n\t\tif (!this.model.vdu) {\n\t\t\tthis.model.vdu = [];\n\t\t}\n\t\treturn this.model.vdu.map(d => DescriptorModelFactory.newVirtualDeploymentUnit(d, this));\n\t}\n\n\tget vld() {\n\t\tif (!this.model['internal−vld']) {\n\t\t\tthis.model['internal−vld'] = [];\n\t\t}\n\t\treturn this.model['internal−vld'].map(d => DescriptorModelFactory.newInternalVirtualLink(d, this));\n\t}\n\n\tget connectionPoint() {\n\t\tif (!this.model['connection-point']) {\n\t\t\tthis.model['connection-point'] = [];\n\t\t}\n\t\treturn this.model['connection-point'].map(d => DescriptorModelFactory.newConnectionPoint(d, this));\n\t}\n\n\tget connectors() {\n\t\treturn this.connectionPoint;\n\t}\n\n\tremove() {\n\t\tif (this.parent) {\n\t\t\tthis.parent.removeConstituentVnfd(this);\n\t\t\tthis.connectors.forEach(cpc => this.parent.removeAnyConnectionsForConnector(cpc));\n\t\t}\n\t}\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/VirtualNetworkFunction.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/23/15.\n */\n\n'use strict';\n\nimport DescriptorModel from '../DescriptorModel'\nimport DescriptorModelFactory from '../DescriptorModelFactory'\n\nexport default class VirtualNetworkFunctionReadOnlyWrapper extends DescriptorModel{\n\n\tconstructor(model, parent) {\n\t\tsuper(model, parent);\n\t}\n\n\tget vld() {\n\t\tif (!this.model['internal−vld']) {\n\t\t\tthis.model['internal−vld'] = [];\n\t\t}\n\t\treturn this.model['internal−vld'].map(d => DescriptorModelFactory.newInternalVirtualLink(d, this.parent));\n\t}\n\n\tget connectionPoint() {\n\t\tif (!this.model['connection-point']) {\n\t\t\tthis.model['connection-point'] = [];\n\t\t}\n\t\treturn this.model['connection-point'].map(d => DescriptorModelFactory.newConstituentVnfdConnectionPoint(d, this.parent));\n\t}\n\n\tget connectors() {\n\t\treturn this.connectionPoint;\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/descriptors/VirtualNetworkFunctionReadOnlyWrapper.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./Animations.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./Animations.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./Animations.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/Animations.scss\n ** module id = 446\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".-with-animations {\\n  -webkit-animation-duration: 200ms;\\n  animation-duration: 200ms;\\n  -webkit-animation-fill-mode: both;\\n  animation-fill-mode: both;\\n}\\n\\n.deleteItemAnimation {\\n  -webkit-animation-name: deleteItemKeyframes;\\n  animation-name: deleteItemKeyframes;\\n  position: fixed;\\n}\\n\\n@-webkit-keyframes deleteItemKeyframes {\\n  0% {\\n    opacity: 1;\\n    -webkit-filter: blur(0px);\\n  }\\n  50% {\\n    opacity: 0.5;\\n    -webkit-filter: blur(10px);\\n  }\\n  100% {\\n    opacity: 0;\\n    -webkit-filter: blur(20px);\\n  }\\n}\\n\\n@keyframes deleteItemKeyframes {\\n  0% {\\n    opacity: 1;\\n    -webkit-filter: blur(0px);\\n  }\\n  50% {\\n    opacity: 0.5;\\n    -webkit-filter: blur(10px);\\n  }\\n  100% {\\n    opacity: 0;\\n    -webkit-filter: blur(20px);\\n  }\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/Animations.scss\n ** module id = 447\n ** module chunks = 0\n **/","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function() {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\tvar result = [];\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar item = this[i];\n\t\t\tif(item[2]) {\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\n\t\t\t} else {\n\t\t\t\tresult.push(item[1]);\n\t\t\t}\n\t\t}\n\t\treturn result.join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t//  when a module is imported multiple times with different media queries.\n\t\t\t//  I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader/lib/css-base.js\n ** module id = 448\n ** module chunks = 0\n **/","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nvar stylesInDom = {},\n\tmemoize = function(fn) {\n\t\tvar memo;\n\t\treturn function () {\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\treturn memo;\n\t\t};\n\t},\n\tisOldIE = memoize(function() {\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t}),\n\tgetHeadElement = memoize(function () {\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t}),\n\tsingletonElement = null,\n\tsingletonCounter = 0,\n\tstyleElementsInsertedAtTop = [];\n\nmodule.exports = function(list, options) {\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n\t// tags it will allow on a page\n\tif (typeof options.singleton === \"undefined\") options.singleton = isOldIE();\n\n\t// By default, add <style> tags to the bottom of <head>.\n\tif (typeof options.insertAt === \"undefined\") options.insertAt = \"bottom\";\n\n\tvar styles = listToStyles(list);\n\taddStylesToDom(styles, options);\n\n\treturn function update(newList) {\n\t\tvar mayRemove = [];\n\t\tfor(var i = 0; i < styles.length; i++) {\n\t\t\tvar item = styles[i];\n\t\t\tvar domStyle = stylesInDom[item.id];\n\t\t\tdomStyle.refs--;\n\t\t\tmayRemove.push(domStyle);\n\t\t}\n\t\tif(newList) {\n\t\t\tvar newStyles = listToStyles(newList);\n\t\t\taddStylesToDom(newStyles, options);\n\t\t}\n\t\tfor(var i = 0; i < mayRemove.length; i++) {\n\t\t\tvar domStyle = mayRemove[i];\n\t\t\tif(domStyle.refs === 0) {\n\t\t\t\tfor(var j = 0; j < domStyle.parts.length; j++)\n\t\t\t\t\tdomStyle.parts[j]();\n\t\t\t\tdelete stylesInDom[domStyle.id];\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction addStylesToDom(styles, options) {\n\tfor(var i = 0; i < styles.length; i++) {\n\t\tvar item = styles[i];\n\t\tvar domStyle = stylesInDom[item.id];\n\t\tif(domStyle) {\n\t\t\tdomStyle.refs++;\n\t\t\tfor(var j = 0; j < domStyle.parts.length; j++) {\n\t\t\t\tdomStyle.parts[j](item.parts[j]);\n\t\t\t}\n\t\t\tfor(; j < item.parts.length; j++) {\n\t\t\t\tdomStyle.parts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\t\t} else {\n\t\t\tvar parts = [];\n\t\t\tfor(var j = 0; j < item.parts.length; j++) {\n\t\t\t\tparts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\t\t\tstylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};\n\t\t}\n\t}\n}\n\nfunction listToStyles(list) {\n\tvar styles = [];\n\tvar newStyles = {};\n\tfor(var i = 0; i < list.length; i++) {\n\t\tvar item = list[i];\n\t\tvar id = item[0];\n\t\tvar css = item[1];\n\t\tvar media = item[2];\n\t\tvar sourceMap = item[3];\n\t\tvar part = {css: css, media: media, sourceMap: sourceMap};\n\t\tif(!newStyles[id])\n\t\t\tstyles.push(newStyles[id] = {id: id, parts: [part]});\n\t\telse\n\t\t\tnewStyles[id].parts.push(part);\n\t}\n\treturn styles;\n}\n\nfunction insertStyleElement(options, styleElement) {\n\tvar head = getHeadElement();\n\tvar lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];\n\tif (options.insertAt === \"top\") {\n\t\tif(!lastStyleElementInsertedAtTop) {\n\t\t\thead.insertBefore(styleElement, head.firstChild);\n\t\t} else if(lastStyleElementInsertedAtTop.nextSibling) {\n\t\t\thead.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);\n\t\t} else {\n\t\t\thead.appendChild(styleElement);\n\t\t}\n\t\tstyleElementsInsertedAtTop.push(styleElement);\n\t} else if (options.insertAt === \"bottom\") {\n\t\thead.appendChild(styleElement);\n\t} else {\n\t\tthrow new Error(\"Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.\");\n\t}\n}\n\nfunction removeStyleElement(styleElement) {\n\tstyleElement.parentNode.removeChild(styleElement);\n\tvar idx = styleElementsInsertedAtTop.indexOf(styleElement);\n\tif(idx >= 0) {\n\t\tstyleElementsInsertedAtTop.splice(idx, 1);\n\t}\n}\n\nfunction createStyleElement(options) {\n\tvar styleElement = document.createElement(\"style\");\n\tstyleElement.type = \"text/css\";\n\tinsertStyleElement(options, styleElement);\n\treturn styleElement;\n}\n\nfunction createLinkElement(options) {\n\tvar linkElement = document.createElement(\"link\");\n\tlinkElement.rel = \"stylesheet\";\n\tinsertStyleElement(options, linkElement);\n\treturn linkElement;\n}\n\nfunction addStyle(obj, options) {\n\tvar styleElement, update, remove;\n\n\tif (options.singleton) {\n\t\tvar styleIndex = singletonCounter++;\n\t\tstyleElement = singletonElement || (singletonElement = createStyleElement(options));\n\t\tupdate = applyToSingletonTag.bind(null, styleElement, styleIndex, false);\n\t\tremove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);\n\t} else if(obj.sourceMap &&\n\t\ttypeof URL === \"function\" &&\n\t\ttypeof URL.createObjectURL === \"function\" &&\n\t\ttypeof URL.revokeObjectURL === \"function\" &&\n\t\ttypeof Blob === \"function\" &&\n\t\ttypeof btoa === \"function\") {\n\t\tstyleElement = createLinkElement(options);\n\t\tupdate = updateLink.bind(null, styleElement);\n\t\tremove = function() {\n\t\t\tremoveStyleElement(styleElement);\n\t\t\tif(styleElement.href)\n\t\t\t\tURL.revokeObjectURL(styleElement.href);\n\t\t};\n\t} else {\n\t\tstyleElement = createStyleElement(options);\n\t\tupdate = applyToTag.bind(null, styleElement);\n\t\tremove = function() {\n\t\t\tremoveStyleElement(styleElement);\n\t\t};\n\t}\n\n\tupdate(obj);\n\n\treturn function updateStyle(newObj) {\n\t\tif(newObj) {\n\t\t\tif(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)\n\t\t\t\treturn;\n\t\t\tupdate(obj = newObj);\n\t\t} else {\n\t\t\tremove();\n\t\t}\n\t};\n}\n\nvar replaceText = (function () {\n\tvar textStore = [];\n\n\treturn function (index, replacement) {\n\t\ttextStore[index] = replacement;\n\t\treturn textStore.filter(Boolean).join('\\n');\n\t};\n})();\n\nfunction applyToSingletonTag(styleElement, index, remove, obj) {\n\tvar css = remove ? \"\" : obj.css;\n\n\tif (styleElement.styleSheet) {\n\t\tstyleElement.styleSheet.cssText = replaceText(index, css);\n\t} else {\n\t\tvar cssNode = document.createTextNode(css);\n\t\tvar childNodes = styleElement.childNodes;\n\t\tif (childNodes[index]) styleElement.removeChild(childNodes[index]);\n\t\tif (childNodes.length) {\n\t\t\tstyleElement.insertBefore(cssNode, childNodes[index]);\n\t\t} else {\n\t\t\tstyleElement.appendChild(cssNode);\n\t\t}\n\t}\n}\n\nfunction applyToTag(styleElement, obj) {\n\tvar css = obj.css;\n\tvar media = obj.media;\n\tvar sourceMap = obj.sourceMap;\n\n\tif(media) {\n\t\tstyleElement.setAttribute(\"media\", media)\n\t}\n\n\tif(styleElement.styleSheet) {\n\t\tstyleElement.styleSheet.cssText = css;\n\t} else {\n\t\twhile(styleElement.firstChild) {\n\t\t\tstyleElement.removeChild(styleElement.firstChild);\n\t\t}\n\t\tstyleElement.appendChild(document.createTextNode(css));\n\t}\n}\n\nfunction updateLink(linkElement, obj) {\n\tvar css = obj.css;\n\tvar media = obj.media;\n\tvar sourceMap = obj.sourceMap;\n\n\tif(sourceMap) {\n\t\t// http://stackoverflow.com/a/26603875\n\t\tcss += \"\\n/*# sourceMappingURL=data:application/json;base64,\" + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + \" */\";\n\t}\n\n\tvar blob = new Blob([css], { type: \"text/css\" });\n\n\tvar oldSrc = linkElement.href;\n\n\tlinkElement.href = URL.createObjectURL(blob);\n\n\tif(oldSrc)\n\t\tURL.revokeObjectURL(oldSrc);\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/style-loader/addStyles.js\n ** module id = 449\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/9/15.\n */\n'use strict';\n\nimport getZoomFactor from './zoomFactor'\nimport '../styles/ResizableManager.scss'\n\nconst sideComplement = {\n\tleft: 'right',\n\tright: 'left',\n\ttop: 'bottom',\n\tbottom: 'top'\n};\n\nfunction zoneName(sides) {\n\treturn sides.sort((a, b) => {\n\t\tif (!a) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!b) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (a.side === 'top' || a.side === 'bottom') {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 1;\n\t}).join('-');\n}\n\nconst resizeDragZones = {\n\ttop (position, x, y, resizeDragZoneWidth) {\n\t\tconst adj = y > 0 && y < document.body.clientHeight;\n\t\tconst pos = position.top - (adj ? resizeDragZoneWidth / 2 : 0);\n\t\tif (Math.abs(y - pos) < resizeDragZoneWidth) {\n\t\t\treturn 'top';\n\t\t}\n\t},\n\tbottom (position, x, y, resizeDragZoneWidth) {\n\t\tconst adj = y > 0 && y < document.body.clientHeight;\n\t\tconst pos = position.bottom - (adj ? resizeDragZoneWidth / 2 : 0);\n\t\tif (Math.abs(y - pos) < resizeDragZoneWidth) {\n\t\t\treturn 'bottom';\n\t\t}\n\t},\n\tright (position, x, y, resizeDragZoneWidth) {\n\t\tconst adj = x > 0 && x < document.body.clientWidth;\n\t\tconst pos = position.right - (adj ? resizeDragZoneWidth / 2 : 0);\n\t\tif (Math.abs(x - pos) < resizeDragZoneWidth) {\n\t\t\treturn 'right';\n\t\t}\n\t},\n\tleft (position, x, y, resizeDragZoneWidth) {\n\t\tconst adj = x > 0 && x < document.body.clientWidth;\n\t\tconst pos = position.left - (adj ? resizeDragZoneWidth / 2 : 0);\n\t\tif (Math.abs(x - pos) < resizeDragZoneWidth) {\n\t\t\treturn 'left';\n\t\t}\n\t},\n\toutside (position, x, y, resizeDragZoneWidth) {\n\t\tif (x < (position.left - resizeDragZoneWidth) || x > (position.right + resizeDragZoneWidth) || y < (position.top - resizeDragZoneWidth) || y > (position.bottom + resizeDragZoneWidth)) {\n\t\t\treturn 'outside';\n\t\t}\n\t}\n};\n\nconst resizeDragLimitForSide = {\n\ttop (position, x, y, resizeDragZoneWidth, resizing) {\n\t\t// y must be inside the position coordinates\n\t\tconst adj = y > 0 && y < document.body.clientHeight;\n\t\tconst top = position.top - (adj ? resizeDragZoneWidth / 2 : 0);\n\t\tconst bottom = position.bottom + (adj ? resizeDragZoneWidth / 2 : 0);\n\t\treturn y > top && y < bottom;\n\t},\n\tbottom (position, x, y, resizeDragZoneWidth) {\n\t\treturn this.top(position, x, y, resizeDragZoneWidth);\n\t},\n\tright (position, x, y, resizeDragZoneWidth) {\n\t\tconst adj = x > 0 && x < document.body.clientWidth;\n\t\tconst left = position.left - (adj ? resizeDragZoneWidth / 2 : 0);\n\t\tconst right = position.right + (adj ? resizeDragZoneWidth / 2 : 0);\n\t\treturn x > left && x < right;\n\t},\n\tleft (position, x, y, resizeDragZoneWidth) {\n\t\treturn this.right(position, x, y, resizeDragZoneWidth);\n\t},\n\tlimit_top (position, x, y, resizeDragZoneWidth, resizing) {\n\t\t// must be outside the position coordinates\n\t\tconst limit = {\n\t\t\ttop: 0,\n\t\t\tright: position.right,\n\t\t\tbottom: position.bottom,\n\t\t\tleft: position.left\n\t\t};\n\t\treturn this.top(limit, x, y, resizeDragZoneWidth, resizing);\n\t},\n\tlimit_bottom (position, x, y, resizeDragZoneWidth, resizing) {\n\t\tconst limit = {\n\t\t\ttop: position.top,\n\t\t\tright: position.right,\n\t\t\tbottom:0,\n\t\t\tleft: position.left\n\t\t};\n\t\treturn this.bottom(limit, x, y, resizeDragZoneWidth, resizing);\n\t},\n\tlimit_right (position, x, y, resizeDragZoneWidth, resizing) {\n\t\tconst limit = {\n\t\t\ttop: position.top,\n\t\t\tright: 0,\n\t\t\tbottom: position.bottom,\n\t\t\tleft: position.left\n\t\t};\n\t\treturn this.right(position, x, y, resizeDragZoneWidth, resizing);\n\t},\n\tlimit_left (position, x, y, resizeDragZoneWidth, resizing) {\n\t\tconst limit = {\n\t\t\ttop: position.top,\n\t\t\tright: position.right,\n\t\t\tbottom: position.bottom,\n\t\t\tleft: 0\n\t\t};\n\t\treturn this.left(position, x, y, resizeDragZoneWidth, resizing);\n\t}\n};\n\nfunction createEvent(e, eventName = 'resize') {\n\tconst lastX = this.resizing.lastX || 0;\n\tconst lastY = this.resizing.lastY || 0;\n\tconst zoomFactor = getZoomFactor();\n\tthis.resizing.lastX = (e.clientX / zoomFactor);\n\tthis.resizing.lastY = (e.clientY / zoomFactor);\n\tconst data = {\n\t\tbubbles: true,\n\t\tcancelable: true,\n\t\tdetail: {\n\t\t\tx: e.clientX / zoomFactor,\n\t\t\ty: e.clientY / zoomFactor,\n\t\t\tside: this.resizing.side,\n\t\t\tstart: {x: this.resizing.startX, y: this.resizing.startY},\n\t\t\tmoved: {\n\t\t\t\tx: lastX - (e.clientX / zoomFactor),\n\t\t\t\ty: lastY - (e.clientY / zoomFactor)\n\t\t\t},\n\t\t\ttarget: this.resizing.target,\n\t\t\toriginalEvent: e\n\t\t}\n\t};\n\tif (window.CustomEvent.prototype.initCustomEvent) {\n\t\t// support IE\n\t\tvar evt = document.createEvent('CustomEvent');\n\t\tevt.initCustomEvent(eventName, data.bubbles, data.cancelable, data.detail);\n\t\treturn evt;\n\t}\n\treturn new CustomEvent(eventName, data);\n}\n\nclass ResizableManager {\n\n\tconstructor(target = document, dragZones = resizeDragZones) {\n\t\tthis.target = target;\n\t\tthis.resizing = null;\n\t\tthis.lastResizable = null;\n\t\tthis.activeResizable = null;\n\t\tthis.resizeDragZones = dragZones;\n\t\tthis.defaultDragZoneWidth = 10;\n\t\tthis.isPaused = false;\n\t\tthis.addAllEventListeners();\n\t}\n\n\tpause() {\n\t\tthis.isPaused = true;\n\t\tthis.removeAllEventListeners();\n\t}\n\n\tresume() {\n\t\tif (this.isPaused) {\n\t\t\tthis.addAllEventListeners();\n\t\t\tthis.isPaused = false;\n\t\t}\n\t}\n\n\taddAllEventListeners() {\n\t\tthis.removeAllEventListeners();\n\t\tthis.mouseout = this.mouseout.bind(this);\n\t\tthis.mousedown = this.mousedown.bind(this);\n\t\tthis.dispatchResizeStop = this.dispatchResizeStop.bind(this);\n\t\tthis.dispatchResize = this.dispatchResize.bind(this);\n\t\tthis.updateResizeCursor = this.updateResizeCursor.bind(this);\n\t\tthis.target.addEventListener('mousemove', this.updateResizeCursor, true);\n\t\tthis.target.addEventListener('mousedown', this.mousedown, true);\n\t\tthis.target.addEventListener('mousemove', this.dispatchResize, true);\n\t\tthis.target.addEventListener('mouseup', this.dispatchResizeStop, true);\n\t\tthis.target.addEventListener('mouseout', this.mouseout, true);\n\t}\n\n\tremoveAllEventListeners() {\n\t\tthis.target.removeEventListener('mousemove', this.updateResizeCursor, true);\n\t\tthis.target.removeEventListener('mousedown', this.mousedown, true);\n\t\tthis.target.removeEventListener('mousemove', this.dispatchResize, true);\n\t\tthis.target.removeEventListener('mouseup', this.dispatchResizeStop, true);\n\t\tthis.target.removeEventListener('mouseout', this.mouseout, true);\n\t}\n\n\tmakeResizableActive(d) {\n\t\tthis.activeResizable = d;\n\t}\n\n\tclearActiveResizable() {\n\t\tthis.activeResizable = null;\n\t}\n\n\tmouseout(e) {\n\t\tif (this.resizing && (e.clientX > window.innerWidth || e.clientX < 0 || e.clientY < 0 || e.clientY > window.innerHeight)) {\n\t\t\tthis.dispatchResizeStop(e);\n\t\t}\n\t}\n\n\tmousedown(e) {\n\t\tif (!this.resizing && this.activeResizable) {\n\t\t\tthis.resizing = this.activeResizable;\n\t\t\tconst zoomFactor = getZoomFactor();\n\t\t\tthis.resizing.startX = e.clientX / zoomFactor;\n\t\t\tthis.resizing.startY = e.clientY / zoomFactor;\n\t\t\te.preventDefault();\n\t\t\tthis.dispatchResizeStart(e);\n\t\t}\n\t}\n\n\tdispatchResize(e) {\n\t\tif (this.resizing && !this.resizeLimitReached) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tconst resizeEvent = createEvent.call(this, e, 'resize');\n\t\t\tthis.resizing.target.dispatchEvent(resizeEvent)\n\t\t}\n\t}\n\n\tdispatchResizeStart(e) {\n\t\tif (this.resizing) {\n\t\t\tdocument.body.classList.add('resizing');\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tconst resizeEvent = createEvent.call(this, e, 'resize-start');\n\t\t\tthis.resizing.target.dispatchEvent(resizeEvent)\n\t\t}\n\t}\n\n\tdispatchResizeStop(e) {\n\t\tif (this.resizing) {\n\t\t\tdocument.body.classList.remove('resizing');\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tconst resizeEvent = createEvent.call(this, e, 'resize-stop');\n\t\t\tthis.resizing.target.dispatchEvent(resizeEvent)\n\t\t\tthis.lastResizable = this.resizing;\n\t\t} else {\n\t\t\tthis.lastResizable = this.activeResizable;\n\t\t}\n\t\tthis.clearActiveResizable();\n\t\tthis.resizing = null;\n\t}\n\n\tisResizing() {\n\t\treturn this.activeResizable && this.resizing;\n\t}\n\n\tupdateResizeCursor(e) {\n\t\tif (e.defaultPrevented) {\n\t\t\tif (this.activeResizable) {\n\t\t\t\tdocument.body.style.cursor = '';\n\t\t\t\tthis.clearActiveResizable();\n\t\t\t\tthis.dispatchResizeStop(e);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst zoomFactor = getZoomFactor();\n\t\tconst x = e.clientX / zoomFactor;\n\t\tconst y = e.clientY / zoomFactor;\n\t\tconst resizables = Array.prototype.slice.call(\n\t\t\t// convert NodeList to Array\n\t\t\tdocument.querySelectorAll('[resizable], [data-resizable]')\n\t\t);\n\t\tif (this.isResizing()) {\n\t\t\tconst others = resizables.filter(d => d !== this.activeResizable.target);\n\t\t\tthis.resizeLimitReached = this.checkResizeLimitReached(x, y, others);\n\t\t\treturn;\n\t\t}\n\t\tif (this.lastResizable) {\n\t\t\tresizables.unshift(this.lastResizable.target)\n\t\t}\n\t\tlet resizable = null;\n\t\tfor (resizable of resizables) {\n\t\t\tconst result = this.isCoordinatesOnDragZone(x, y, resizable);\n\t\t\tif (result.side === 'inside' || result.side === 'outside') {\n\t\t\t\tdocument.body.style.cursor = '';\n\t\t\t\tthis.clearActiveResizable();\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (result.side === 'right' || result.side === 'left') {\n\t\t\t\tdocument.body.style.cursor = 'col-resize';\n\t\t\t} else if (result.side === 'top' || result.side === 'bottom') {\n\t\t\t\tdocument.body.style.cursor = 'row-resize';\n\t\t\t} else if (result.side === 'top-right' || result.side === 'bottom-left') {\n\t\t\t\tdocument.body.style.cursor = 'nesw-resize';\n\t\t\t} else if (result.side === 'top-left' || result.side === 'bottom-right') {\n\t\t\t\tdocument.body.style.cursor = 'nwse-resize';\n\t\t\t}\n\t\t\tthis.makeResizableActive(result);\n\t\t\tbreak\n\t\t}\n\t}\n\n\tcheckResizeLimitReached(x, y, resizables) {\n\t\tlet hasReachedLimit = false;\n\t\tif (this.isResizing()) {\n\t\t\tconst sides = this.activeResizable.side.split('-');\n\t\t\tresizables.filter(resizable => {\n\t\t\t\tconst resizableSide = resizable.dataset.resizable;\n\t\t\t\treturn sides.filter(side => resizableSide.indexOf(sideComplement[side]) > -1).length;\n\t\t\t}).forEach(resizable => {\n\t\t\t\tconst position = resizable.getBoundingClientRect();\n\t\t\t\tconst zoneWidth = resizable.dataset.resizableDragZoneWidth || this.defaultDragZoneWidth;\n\t\t\t\tconst resizableSide = resizable.dataset.resizable;\n\t\t\t\tconst isLimit = /^limit/.test(resizableSide);\n\t\t\t\tsides.forEach(side => {\n\t\t\t\t\tconst key = (isLimit ? 'limit_' : '') + side;\n\t\t\t\t\tif (resizeDragLimitForSide[key]) {\n\t\t\t\t\t\tif (resizeDragLimitForSide[key](position, x, y, zoneWidth, this.resizing)) {\n\t\t\t\t\t\t\thasReachedLimit = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\treturn hasReachedLimit;\n\t}\n\n\tisCoordinatesOnDragZone(x, y, element) {\n\t\tconst result = {\n\t\t\tside: 'inside',\n\t\t\ttarget: element\n\t\t};\n\t\tconst check = this.resizeDragZones;\n\t\tconst sides = element.dataset.resizable || 'top,right,bottom,left';\n\t\tconst zoneWidth = element.dataset.resizableDragZoneWidth || this.defaultDragZoneWidth;\n\t\tconst position = element.getBoundingClientRect();\n\t\tconst temp = [];\n\t\tif (check.outside && check.outside(position, x, y, zoneWidth)) {\n\t\t\tresult.side = 'outside';\n\t\t\treturn result;\n\t\t}\n\t\tsides.split(/\\W+|\\s*,\\s*/).forEach(side => {\n\t\t\tif (check[side]) {\n\t\t\t\tconst r = check[side](position, x, y, zoneWidth);\n\t\t\t\tif (r) {\n\t\t\t\t\ttemp.push(r);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (temp.length) {\n\t\t\tresult.side = zoneName(temp);\n\t\t\treturn result;\n\t\t}\n\t\treturn result;\n\t}\n\n}\n\nexport default ResizableManager;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/ResizableManager.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\nexport default function zoomFactor(element = document.body) {\n\tlet factor;\n\tlet rect = element.getBoundingClientRect();\n\tlet physicalW = rect.right - rect.left;\n\tlet logicalW = element.offsetWidth;\n\tfactor = Math.round((physicalW / logicalW) * 100) / 100;\n\treturn factor;\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/zoomFactor.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ResizableManager.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ResizableManager.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ResizableManager.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/ResizableManager.scss\n ** module id = 452\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\nbody * {\\n  cursor: inherit;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/ResizableManager.scss\n ** module id = 453\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by kkashalk on 11/10/15.\n */\n\n'use strict';\n\nimport utils from '../libraries/utils'\nimport React from 'react'\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport RiftHeaderActions from '../actions/RiftHeaderActions'\nimport RiftHeaderStore from '../stores/RiftHeaderStore'\n\nimport '../styles/RiftHeader.scss'\n\nconst uiTransientState = {\n\ttimeoutId: 0\n};\n\nconst RiftHeader = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn RiftHeaderStore.getState();\n\t},\n\tgetDefaultProps() {\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t\tRiftHeaderStore.listen(this.onChange);\n\t\tconst loadCatalogs = function () {\n\t\t\tRiftHeaderStore.loadCatalogs();\n\t\t\tuiTransientState.timeoutId = setTimeout(loadCatalogs, 2000);\n\t\t};\n\t\tloadCatalogs();\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t\tif (uiTransientState.timeoutId) {\n\t\t\tclearTimeout(uiTransientState.timeoutId);\n\t\t}\n\t\tRiftHeaderStore.unlisten(this.onChange);\n\t},\n\n\tonChange(state) {\n\t\tthis.setState(state);\n\t},\n\tonClickOpenDashboard() {\n\t\tif (uiTransientState.timeoutId) {\n\t\t\tclearTimeout(uiTransientState.timeoutId);\n\t\t}\n\t\tRiftHeaderStore.unlisten(this.onChange);\n\t\twindow.location.href = '//' + window.location.hostname + ':8000/index.html?api_server=' + utils.getSearchParams(window.location).api_server + '#/launchpad/' + utils.getSearchParams(window.location).mgmt_domain_name;\n\t},\n\trender() {\n\t\treturn (\n\t\t\t<div className=\"RiftHeader\">\n\t\t\t\t<header className=\"header-app\">\n\t\t\t\t\t<h1>{this.state.headerTitle}</h1>\n\t\t\t\t\t<nav className=\"header-nav\"> </nav>\n\t\t\t\t</header>\n\t\t\t\t<div>\n\t\t\t        <a href=\"#\" onClick={this.onClickOpenDashboard} style={{fontWeight: 'normal', color: 'black'}}>DASHBOARD</a>\n\t\t\t\t\t<span style={{'marginRight': '0.5rem', 'marginLeft': '0.5rem',fontWeight:'bold'}}>|</span>\n\t\t\t\t\t<span style={{'display': 'flex', 'marginBottom': '0.5rem', 'marginRight': '0.25rem', 'fontWeight': 'bold'}}>CATALOG</span>\n\t\t\t\t\t<span style={{'marginRight': '0.25rem', 'marginLeft': '0.25rem'}}>({this.state.descriptorCount})</span>\n\t\t\t    </div>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default RiftHeader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/RiftHeader.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by kkashalk on 11/10/15.\n */\nimport alt from '../alt';\n\nclass RiftHeaderActions {\n\n\tconstructor() {\n\t\tthis.generateActions('navigateToDashboard');\n\t}\n\n}\n\nexport default alt.createActions(RiftHeaderActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/RiftHeaderActions.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by kkashalk on 11/10/15.\n */\n'use strict';\n\nimport alt from '../alt'\nimport React from 'react'\nimport utils from '../libraries/utils'\nimport RiftHeaderActions from '../actions/RiftHeaderActions'\nimport CatalogDataSource from '../sources/CatalogDataSource'\nimport CatalogDataSourceActions from '../actions/CatalogDataSourceActions'\n\nclass RiftHeaderStore {\n\n\tconstructor() {\n\t\tthis.headerTitle = 'Launchpad: ' + unescape(utils.getSearchParams(window.location).mgmt_domain_name);\n\t\tthis.nsdCount = 0;\n\t\tthis.registerAsync(CatalogDataSource);\n\t\tthis.bindAction(CatalogDataSourceActions.LOAD_CATALOGS_SUCCESS, this.loadCatalogsSuccess);\n\t\tthis.bindActions(RiftHeaderActions);\n\t}\n\n\tloadCatalogsSuccess(data) {\n\t\tlet self = this;\n\t\tlet descriptorCount = 0;\n\t\tdata.data.forEach((catalog) => {\n\t\t\tdescriptorCount += catalog.descriptors.length;\n\t\t});\n\n\t\tself.setState({\n\t\t\tdescriptorCount: descriptorCount\n\t\t});\n\t}\n}\n\nexport default alt.createStore(RiftHeaderStore, 'RiftHeaderStore');\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/stores/RiftHeaderStore.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport $ from 'jquery'\nimport alt from '../alt'\nimport utils from '../libraries/utils'\nimport serializers from '../libraries/model/DescriptorConfDSerializer'\nimport CatalogDataSourceActions from '../actions/CatalogDataSourceActions'\n\nconst CatalogDataSource = {\n\n\tloadCatalogs: function() {\n\t\treturn {\n\t\t\tremote: function() {\n\t\t\t\treturn new Promise(function(resolve, reject) {\n\t\t\t\t\t$.ajax({\n\t\t\t\t\t\tbeforeSend: utils.addAuthorizationStub,\n\t\t\t\t\t\turl: 'http://' + window.location.hostname + ':3000/launchpad/catalog?api_server=' + utils.getSearchParams(window.location).api_server,\n\t\t\t\t\t\t//url: 'assets/ping-pong-catalog.json',\n\t\t\t\t\t\t//url: 'assets/empty-nsd-catalog.json',\n\t\t\t\t\t\tsuccess: function(data) {\n\t\t\t\t\t\t\tif (typeof data == 'string') {\n\t\t\t\t\t\t\t\tdata = JSON.parse(data);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst context = Object.assign({}, this, {data: data});\n\t\t\t\t\t\t\tresolve(context);\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(error) {\n\t\t\t\t\t\t\tif (typeof error == 'string') {\n\t\t\t\t\t\t\t\terror = JSON.parse(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tsuccess: CatalogDataSourceActions.loadCatalogsSuccess,\n\t\t\terror: CatalogDataSourceActions.loadCatalogsError\n\t\t}\n\t},\n\n\tdeleteCatalogItem: function() {\n\t\treturn {\n\t\t\tremote: function(state, catalogType, itemId) {\n\t\t\t\treturn new Promise(function(resolve, reject) {\n\t\t\t\t\t$.ajax({\n\t\t\t\t\t\turl: 'http://' + window.location.hostname + ':3000/launchpad/catalog/' + catalogType + '/' + itemId + '?api_server=' + utils.getSearchParams(window.location).api_server,\n\t\t\t\t\t\ttype: 'DELETE',\n\t\t\t\t\t\tbeforeSend: utils.addAuthorizationStub,\n\t\t\t\t\t\tsuccess: function(data) {\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tdata: data,\n\t\t\t\t\t\t\t\tcatalogType: catalogType,\n\t\t\t\t\t\t\t\titemId: itemId\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(error) {\n\t\t\t\t\t\t\treject({\n\t\t\t\t\t\t\t\terror: error,\n\t\t\t\t\t\t\t\tcatalogType: catalogType,\n\t\t\t\t\t\t\t\titemId: itemId\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tsuccess: CatalogDataSourceActions.deleteCatalogItemSuccess,\n\t\t\terror: CatalogDataSourceActions.deleteCatalogItemError\n\t\t}\n\t},\n\n\tsaveCatalogItem: function () {\n\t\treturn {\n\t\t\tremote: function (state, item = {}) {\n\t\t\t\tconst method = item.meta.isNew ? 'POST' : 'PUT';\n\t\t\t\tconst payload = serializers.serialize(item);\n\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\tif (payload === false) {\n\t\t\t\t\t\treject({\n\t\t\t\t\t\t\terror: 'unable to serialize item: ' + item.id,\n\t\t\t\t\t\t\tcatalogType: item.meta.type,\n\t\t\t\t\t\t\titemId: payload.id\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (method === 'POST') {\n\t\t\t\t\t\t$.ajax({\n\t\t\t\t\t\t\turl: 'http://' + window.location.hostname + ':3000/launchpad/catalog/' + item.meta.type + '?api_server=' + utils.getSearchParams(window.location).api_server,\n\t\t\t\t\t\t\ttype: method,\n\t\t\t\t\t\t\tbeforeSend: utils.addAuthorizationStub,\n\t\t\t\t\t\t\tdata: payload,\n\t\t\t\t\t\t\tdataType: 'json',\n\t\t\t\t\t\t\tsuccess: function(data) {\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tdata: data,\n\t\t\t\t\t\t\t\t\tcatalogType: item.meta.type,\n\t\t\t\t\t\t\t\t\titemId: payload.id\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\terror: function(error) {\n\t\t\t\t\t\t\t\treject({\n\t\t\t\t\t\t\t\t\terror: error,\n\t\t\t\t\t\t\t\t\tcatalogType: item.meta.type,\n\t\t\t\t\t\t\t\t\titemId: payload.id\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$.ajax({\n\t\t\t\t\t\t\turl: 'http://' + window.location.hostname + ':3000/launchpad/catalog/' + item.meta.type + '/' + payload.id + '?api_server=' + utils.getSearchParams(window.location).api_server,\n\t\t\t\t\t\t\ttype: method,\n\t\t\t\t\t\t\tbeforeSend: utils.addAuthorizationStub,\n\t\t\t\t\t\t\tdata: payload,\n\t\t\t\t\t\t\tdataType: 'json',\n\t\t\t\t\t\t\tsuccess: function(data) {\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tdata: data,\n\t\t\t\t\t\t\t\t\tcatalogType: item.meta.type,\n\t\t\t\t\t\t\t\t\titemId: payload.id\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\terror: function(error) {\n\t\t\t\t\t\t\t\treject({\n\t\t\t\t\t\t\t\t\terror: error,\n\t\t\t\t\t\t\t\t\tcatalogType: item.meta.type,\n\t\t\t\t\t\t\t\t\titemId: payload.id\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tsuccess: CatalogDataSourceActions.saveCatalogItemSuccess,\n\t\t\terror: CatalogDataSourceActions.saveCatalogItemError\n\t\t};\n\t}\n};\n\nexport default CatalogDataSource;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/sources/CatalogDataSource.js\n **/","/*!\n * jQuery JavaScript Library v2.1.4\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:01Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Support: Firefox 18+\n// Can't be in strict mode, several libs including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n//\n\nvar arr = [];\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\tversion = \"2.1.4\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Not plain objects:\n\t\t// - Any object or value whose internal [[Class]] property is not \"[object Object]\"\n\t\t// - DOM nodes\n\t\t// - window\n\t\tif ( jQuery.type( obj ) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call( obj.constructor.prototype, \"isPrototypeOf\" ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the function hasn't returned already, we're confident that\n\t\t// |obj| is a plain object, created by {} or constructed with new Object\n\t\treturn true;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\t// Support: Android<4.0, iOS<6 (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tvar script,\n\t\t\tindirect = eval;\n\n\t\tcode = jQuery.trim( code );\n\n\t\tif ( code ) {\n\t\t\t// If the code includes a valid, prologue position\n\t\t\t// strict mode pragma, execute code by injecting a\n\t\t\t// script tag into the document.\n\t\t\tif ( code.indexOf(\"use strict\") === 1 ) {\n\t\t\t\tscript = document.createElement(\"script\");\n\t\t\t\tscript.text = code;\n\t\t\t\tdocument.head.appendChild( script ).parentNode.removeChild( script );\n\t\t\t} else {\n\t\t\t// Otherwise, avoid the DOM node creation, insertion\n\t\t\t// and removal by using an indirect global eval\n\t\t\t\tindirect( code );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Support: IE9-11+\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tlen = this.length,\n\t\t\tret = [],\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[0] === \"<\" && selector[ selector.length - 1 ] === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Support: Blackberry 4.6\n\t\t\t\t\t// gEBID returns nodes no longer in the document (#6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\ttruncate = until !== undefined;\n\n\t\twhile ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmatched.push( elem );\n\t\t\t}\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar matched = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tmatched.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn matched;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\twhile ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.unique( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// Flag to know if list is currently firing\n\t\tfiring,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// Add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\twindow.removeEventListener( \"load\", completed, false );\n\tjQuery.ready();\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// We once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t} else {\n\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Kick off the DOM ready check even if the user does not\njQuery.ready.promise();\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlen ? fn( elems[0], key ) : emptyGet;\n};\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( owner ) {\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\t/* jshint -W018 */\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\nfunction Data() {\n\t// Support: Android<4,\n\t// Old WebKit does not have Object.preventExtensions/freeze method,\n\t// return new empty object instead with no [[set]] accessor\n\tObject.defineProperty( this.cache = {}, 0, {\n\t\tget: function() {\n\t\t\treturn {};\n\t\t}\n\t});\n\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\nData.accepts = jQuery.acceptData;\n\nData.prototype = {\n\tkey: function( owner ) {\n\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t// but we should not, see #8335.\n\t\t// Always return the key for a frozen object.\n\t\tif ( !Data.accepts( owner ) ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar descriptor = {},\n\t\t\t// Check if the owner object already has a cache key\n\t\t\tunlock = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !unlock ) {\n\t\t\tunlock = Data.uid++;\n\n\t\t\t// Secure it in a non-enumerable, non-writable property\n\t\t\ttry {\n\t\t\t\tdescriptor[ this.expando ] = { value: unlock };\n\t\t\t\tObject.defineProperties( owner, descriptor );\n\n\t\t\t// Support: Android<4\n\t\t\t// Fallback to a less secure definition\n\t\t\t} catch ( e ) {\n\t\t\t\tdescriptor[ this.expando ] = unlock;\n\t\t\t\tjQuery.extend( owner, descriptor );\n\t\t\t}\n\t\t}\n\n\t\t// Ensure the cache object\n\t\tif ( !this.cache[ unlock ] ) {\n\t\t\tthis.cache[ unlock ] = {};\n\t\t}\n\n\t\treturn unlock;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\t// There may be an unlock assigned to this node,\n\t\t\t// if there is no entry for this \"owner\", create one inline\n\t\t\t// and set the unlock as though an owner entry had always existed\n\t\t\tunlock = this.key( owner ),\n\t\t\tcache = this.cache[ unlock ];\n\n\t\t// Handle: [ owner, key, value ] args\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ data ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\t\t\t// Fresh assignments by object are shallow copied\n\t\t\tif ( jQuery.isEmptyObject( cache ) ) {\n\t\t\t\tjQuery.extend( this.cache[ unlock ], data );\n\t\t\t// Otherwise, copy the properties one-by-one to the cache object\n\t\t\t} else {\n\t\t\t\tfor ( prop in data ) {\n\t\t\t\t\tcache[ prop ] = data[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\t// Either a valid cache is found, or will be created.\n\t\t// New caches will be created and the unlock returned,\n\t\t// allowing direct access to the newly created\n\t\t// empty data object. A valid owner object must be provided.\n\t\tvar cache = this.cache[ this.key( owner ) ];\n\n\t\treturn key === undefined ?\n\t\t\tcache : cache[ key ];\n\t},\n\taccess: function( owner, key, value ) {\n\t\tvar stored;\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t((key && typeof key === \"string\") && value === undefined) ) {\n\n\t\t\tstored = this.get( owner, key );\n\n\t\t\treturn stored !== undefined ?\n\t\t\t\tstored : this.get( owner, jQuery.camelCase(key) );\n\t\t}\n\n\t\t// [*]When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i, name, camel,\n\t\t\tunlock = this.key( owner ),\n\t\t\tcache = this.cache[ unlock ];\n\n\t\tif ( key === undefined ) {\n\t\t\tthis.cache[ unlock ] = {};\n\n\t\t} else {\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = key.concat( key.map( jQuery.camelCase ) );\n\t\t\t} else {\n\t\t\t\tcamel = jQuery.camelCase( key );\n\t\t\t\t// Try the string as a key before any manipulation\n\t\t\t\tif ( key in cache ) {\n\t\t\t\t\tname = [ key, camel ];\n\t\t\t\t} else {\n\t\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\t\tname = camel;\n\t\t\t\t\tname = name in cache ?\n\t\t\t\t\t\t[ name ] : ( name.match( rnotwhite ) || [] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ name[ i ] ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\treturn !jQuery.isEmptyObject(\n\t\t\tthis.cache[ owner[ this.expando ] ] || {}\n\t\t);\n\t},\n\tdiscard: function( owner ) {\n\t\tif ( owner[ this.expando ] ) {\n\t\t\tdelete this.cache[ owner[ this.expando ] ];\n\t\t}\n\t}\n};\nvar data_priv = new Data();\n\nvar data_user = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdata_user.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend({\n\thasData: function( elem ) {\n\t\treturn data_user.hasData( elem ) || data_priv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn data_user.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdata_user.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to data_priv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn data_priv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdata_priv.remove( elem, name );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = data_user.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !data_priv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdata_priv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tdata_user.set( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data,\n\t\t\t\tcamelKey = jQuery.camelCase( key );\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key as-is\n\t\t\t\tdata = data_user.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key camelized\n\t\t\t\tdata = data_user.get( elem, camelKey );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, camelKey, undefined );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each(function() {\n\t\t\t\t// First, attempt to store a copy or reference of any\n\t\t\t\t// data that might've been store with a camelCased key.\n\t\t\t\tvar data = data_user.get( this, camelKey );\n\n\t\t\t\t// For HTML5 data-* attribute interop, we have to\n\t\t\t\t// store property names with dashes in a camelCase form.\n\t\t\t\t// This might not apply to all properties...*\n\t\t\t\tdata_user.set( this, camelKey, value );\n\n\t\t\t\t// *... In the case of properties that might _actually_\n\t\t\t\t// have dashes, we need to also store a copy of that\n\t\t\t\t// unchanged property.\n\t\t\t\tif ( key.indexOf(\"-\") !== -1 && data !== undefined ) {\n\t\t\t\t\tdata_user.set( this, key, value );\n\t\t\t\t}\n\t\t\t});\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tdata_user.remove( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = data_priv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = data_priv.access( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn data_priv.get( elem, key ) || data_priv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tdata_priv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = data_priv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Safari<=5.1\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Safari<=5.1, Android<4.2\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<=11+\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n})();\nvar strundefined = typeof undefined;\n\n\n\nsupport.focusinBubbles = \"onfocusin\" in window;\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = data_priv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = data_priv.hasData( elem ) && data_priv.get( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\t\t\tdata_priv.remove( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( data_priv.get( cur, \"events\" ) || {} )[ event.type ] && data_priv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, j, ret, matched, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( data_priv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.disabled !== true || event.type !== \"click\" ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar eventDoc, doc, body,\n\t\t\t\tbutton = original.button;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: Cordova 2.5 (WebKit) (#13255)\n\t\t// All events should have a target; Cordova deviceready doesn't\n\t\tif ( !event.target ) {\n\t\t\tevent.target = document;\n\t\t}\n\n\t\t// Support: Safari 6.0+, Chrome<28\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle, false );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: Android<4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && e.preventDefault ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// Support: Chrome 15+\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// Support: Firefox, Chrome, Safari\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = data_priv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdata_priv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = data_priv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdata_priv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdata_priv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar origFn, type;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nvar\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\n\t\t// Support: IE9\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t_default: [ 0, \"\", \"\" ]\n\t};\n\n// Support: IE9\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: 1.x compatibility\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (elem.getAttribute(\"type\") !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdata_priv.set(\n\t\t\telems[ i ], \"globalEval\", !refElements || data_priv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( data_priv.hasData( src ) ) {\n\t\tpdataOld = data_priv.access( src );\n\t\tpdataCur = data_priv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( data_user.hasData( src ) ) {\n\t\tudataOld = data_user.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdata_user.set( dest, udataCur );\n\t}\n}\n\nfunction getAll( context, tag ) {\n\tvar ret = context.getElementsByTagName ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\tcontext.querySelectorAll ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar elem, tmp, tag, wrap, contains, j,\n\t\t\tfragment = context.createDocumentFragment(),\n\t\t\tnodes = [],\n\t\t\ti = 0,\n\t\t\tl = elems.length;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\t// Support: QtWebKit, PhantomJS\n\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\t\ttmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[ 2 ];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[ 0 ];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: QtWebKit, PhantomJS\n\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Remember the top-level container\n\t\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\t\ttmp.textContent = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Remove wrapper from fragment\n\t\tfragment.textContent = \"\";\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn fragment;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type, key,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[ i ]) !== undefined; i++ ) {\n\t\t\tif ( jQuery.acceptData( elem ) ) {\n\t\t\t\tkey = elem[ data_priv.expando ];\n\n\t\t\t\tif ( key && (data = data_priv.cache[ key ]) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( data_priv.cache[ key ] ) {\n\t\t\t\t\t\t// Discard any remaining `private` data\n\t\t\t\t\t\tdelete data_priv.cache[ key ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Discard any remaining `user` data\n\t\t\tdelete data_user.cache[ elem[ data_user.expando ] ];\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each(function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[ 0 ],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t\t\t// jQuery.merge because push.apply(_, arraylike) throws\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[ i ], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!data_priv.access( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( node.textContent.replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: QtWebKit\n\t\t\t// .get() because push.apply(_, arraylike) throws\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optimization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = iframe[ 0 ].contentDocument;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// Support: IE9\n\t// getPropertyValue is only needed for .css('filter') (#12537)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\t}\n\n\tif ( computed ) {\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// Support: iOS < 6\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\tvar pixelPositionVal, boxSizingReliableVal,\n\t\tdocElem = document.documentElement,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE9-11+\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;\" +\n\t\t\"position:absolute\";\n\tcontainer.appendChild( div );\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computePixelPositionAndBoxSizingReliable() {\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\t\tdiv.innerHTML = \"\";\n\t\tdocElem.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div, null );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\tdocElem.removeChild( container );\n\t}\n\n\t// Support: node.js jsdom\n\t// Don't assume that getComputedStyle is a property of the global object\n\tif ( window.getComputedStyle ) {\n\t\tjQuery.extend( support, {\n\t\t\tpixelPosition: function() {\n\n\t\t\t\t// This test is executed only once but we still do memoizing\n\t\t\t\t// since we can use the boxSizingReliable pre-computing.\n\t\t\t\t// No need to check if the test was already performed, though.\n\t\t\t\tcomputePixelPositionAndBoxSizingReliable();\n\t\t\t\treturn pixelPositionVal;\n\t\t\t},\n\t\t\tboxSizingReliable: function() {\n\t\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\t\tcomputePixelPositionAndBoxSizingReliable();\n\t\t\t\t}\n\t\t\t\treturn boxSizingReliableVal;\n\t\t\t},\n\t\t\treliableMarginRight: function() {\n\n\t\t\t\t// Support: Android 2.3\n\t\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t\t// gets computed margin-right based on width of container. (#3333)\n\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t// This support function is only executed once so no memoizing is needed.\n\t\t\t\tvar ret,\n\t\t\t\t\tmarginDiv = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\t\tmarginDiv.style.cssText = div.style.cssText =\n\t\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\t\tdiv.style.width = \"1px\";\n\t\t\t\tdocElem.appendChild( container );\n\n\t\t\t\tret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );\n\n\t\t\t\tdocElem.removeChild( container );\n\t\t\t\tdiv.removeChild( marginDiv );\n\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t});\n\t}\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t// Swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[0].toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// Both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// At this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// At this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// At this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// Some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// Check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox &&\n\t\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// Use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = data_priv.get( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = data_priv.access( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display !== \"none\" || !hidden ) {\n\t\t\t\tdata_priv.set( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.extend({\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\n// Support: Android 2.3\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE9\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*.\n\t\t\t\t\t// Use string for doubling so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur(),\n\t\t\t\t// break the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = data_priv.get( elem, \"fxshow\" );\n\n\t// Handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// Height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE9-10 do not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tdata_priv.get( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\t\t\tstyle.display = \"inline-block\";\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always(function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t});\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = data_priv.access( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// Store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\n\t\t\tdata_priv.remove( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// Support: Android 2.3\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || data_priv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = data_priv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = data_priv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: iOS<=5.1, Android<=4.2+\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE<=11+\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: Android<=2.3\n\t// Options inside disabled selects are incorrectly marked as disabled\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE<=11+\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tjQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle;\n\t\tif ( !isXML ) {\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ name ];\n\t\t\tattrHandle[ name ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tname.toLowerCase() :\n\t\t\t\tnull;\n\t\t\tattrHandle[ name ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n});\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.hasAttribute( \"tabindex\" ) || rfocusable.test( elem.nodeName ) || elem.href ?\n\t\t\t\t\telem.tabIndex :\n\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\tproceed = typeof value === \"string\" && value,\n\t\t\ti = 0,\n\t\t\tlen = this.length;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value,\n\t\t\ti = 0,\n\t\t\tlen = this.length;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// Toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tdata_priv.set( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : data_priv.get( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// Handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// IE6-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute( \"disabled\" ) === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\n// Support: Android 2.3\n// Workaround failure to string-cast null input\njQuery.parseJSON = function( data ) {\n\treturn JSON.parse( data + \"\" );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE9\n\ttry {\n\t\ttmp = new DOMParser();\n\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Document location\n\tajaxLocation = window.location.href,\n\n\t// Segment location into parts\n\tajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[0] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" )\n\t\t\t.replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[ 0 ] ) {\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0;\n};\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new XMLHttpRequest();\n\t} catch( e ) {}\n};\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSuccessStatus = {\n\t\t// file protocol always yields status code 0, assume 200\n\t\t0: 200,\n\t\t// Support: IE9\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE9\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]();\n\t\t}\n\t});\n}\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport(function( options ) {\n\tvar callback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = xhr.onload = xhr.onerror = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\t// file: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\t\t\t\t\t\t\t\t\t// Support: IE9\n\t\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText === \"string\" ? {\n\t\t\t\t\t\t\t\t\t\ttext: xhr.responseText\n\t\t\t\t\t\t\t\t\t} : undefined,\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\txhr.onerror = callback(\"error\");\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = xhrCallbacks[ id ] = callback(\"abort\");\n\n\t\t\t\ttry {\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery(\"<script>\").prop({\n\t\t\t\t\tasync: true,\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t}).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf(\"auto\") > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\telem = this[ 0 ],\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// Support: BlackBerry 5, iOS 3 (original iPhone)\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top + win.pageYOffset - docElem.clientTop,\n\t\t\tleft: box.left + win.pageXOffset - docElem.clientLeft\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// Assume getBoundingClientRect is there when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : window.pageXOffset,\n\t\t\t\t\ttop ? val : window.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Support: Safari<7+, Chrome<37+\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/jquery/dist/jquery.js\n ** module id = 458\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/20/15.\n */\n\nimport _ from 'lodash'\nimport utils from './../utils'\nimport DescriptorModelMetaFactory from './DescriptorModelMetaFactory'\n\nconst nsdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd').concat('meta');\nconst vldFields = DescriptorModelMetaFactory.getModelFieldNamesForType('vld');\nconst vnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('vnfd').concat('meta');\nconst cvnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.constituent-vnfd');\n\nconst serializers = {\n\tserialize(model) {\n\t\tconst type = model.meta && model.meta.type;\n\t\tconst serializer = this[type];\n\t\tif (serializer) {\n\t\t\tmodel = serializer.serialize(model);\n\t\t\tthis[':clean'](model);\n\t\t\treturn model;\n\t\t}\n\t\treturn false;\n\t},\n\t':clean'(model) {\n\t\t// remove meta from all elements accept nsd and vnfd\n\t\tfunction cleanMeta(m) {\n\t\t\tObject.keys(m).forEach(k => {\n\t\t\t\tconst isMetaAllowed = /^nsd|vnfd$/.test(m.meta && m.meta.type);\n\t\t\t\tif (k === 'meta') {\n\t\t\t\t\tif (isMetaAllowed) {\n\t\t\t\t\t\t// remove transient ui state properties\n\t\t\t\t\t\t// TODO removing icon-svg for now bc backend chokes on large strings\n\t\t\t\t\t\tconst meta = _.pick(m.meta, [/*'icon-svg',*/'containerPositionMap']);\n\t\t\t\t\t\tif (!_.isEmpty(meta)) {\n\t\t\t\t\t\t\t// meta field must be a string\n\t\t\t\t\t\t\tm['meta'] = JSON.stringify(meta);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdelete m[k];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (typeof m[k] === 'object') {\n\t\t\t\t\tcleanMeta(m[k]);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tcleanMeta(model);\n\t\treturn model;\n\t},\n\tnsd: {\n\t\tserialize(nsdModel) {\n\n\t\t\tconst confd = _.pick(nsdModel, nsdFields);\n\n\t\t\t// vnfd is defined in the ETSI etsi_gs reference manual but RIFT does not use it\n\t\t\tdelete confd.vnfd;\n\n\t\t\t// map the vnfd instances into the CONFD constituent-vnfd ref instances\n\t\t\tconfd['constituent-vnfd'] = confd['constituent-vnfd'].map((d, index) => {\n\n\t\t\t\tconst constituentVNFD = {\n\t\t\t\t\t'member-vnf-index': d['member-vnf-index'],\n\t\t\t\t\t'vnfd-id-ref': d['vnfd-id-ref']\n\t\t\t\t};\n\n\t\t\t\tif (d['vnf-configuration']) {\n\t\t\t\t\tconst vnfConfig = _.cloneDeep(d['vnf-configuration']);\n\t\t\t\t\tconst configType = vnfConfig['config-type'] || 'none';\n\t\t\t\t\t// make sure we send the correct values based on config type\n\t\t\t\t\tif (configType === 'none') {\n\t\t\t\t\t\tconstituentVNFD['vnf-configuration'] = {'config-type': 'none'};\n\t\t\t\t\t\tconst configPriority = utils.resolvePath(vnfConfig, 'input-params.config-priority');\n\t\t\t\t\t\tconst configPriorityValue = _.isNumber(configPriority) ? configPriority : d.meta['member-vnf-index'];\n\t\t\t\t\t\tutils.assignPathValue(constituentVNFD['vnf-configuration'], 'input-params.config-priority', configPriorityValue);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// remove any unused configuration options\n\t\t\t\t\t\t['netconf', 'rest', 'script', 'juju'].forEach(type => {\n\t\t\t\t\t\t\tif (configType !== type) {\n\t\t\t\t\t\t\t\tdelete vnfConfig[type];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconstituentVNFD['vnf-configuration'] = vnfConfig;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn constituentVNFD;\n\n\t\t\t});\n\n\t\t\t// serialize the VLD instances\n\t\t\tconfd.vld = confd.vld.map(d => {\n\t\t\t\treturn serializers.serialize(d);\n\t\t\t});\n\n\t\t\treturn confd;\n\n\t\t}\n\t},\n\tvld: {\n\t\tserialize(vldModel) {\n\t\t\tconst confd = _.pick(vldModel, vldFields);\n\t\t\tconst property = 'vnfd-connection-point-ref';\n\n\t\t\t// TODO: There is a bug in RIFT-REST that is not accepting empty\n\t\t\t// strings for string properties.\n\t\t\t// once that is fixed, remove this piece of code.\n\t\t\t// fix-start\n\t\t\tfor (var key in confd) {\n\t\t\t\tif (confd.hasOwnProperty(key) && confd[key] === '') {\n\t\t\t\t\tdelete confd[key];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deepProperty = 'provider-network';\n\t\t\tfor (var key in confd[deepProperty]) {\n\t\t\t\tif (confd[deepProperty].hasOwnProperty(key) && confd[deepProperty][key] === '') {\n\t\t\t\t\tdelete confd[deepProperty][key];\n\t\t\t\t}\n\t\t\t}\n\t\t\t// fix-end\n\n\n\t\t\tconfd[property] = confd[property].map(d => serializers[property].serialize(d));\n\t\t\treturn confd;\n\t\t}\n\t},\n\t'vnfd-connection-point-ref': {\n\t\tserialize(ref) {\n\t\t\treturn _.pick(ref, ['member-vnf-index-ref', 'vnfd-id-ref', 'vnfd-connection-point-ref']);\n\t\t}\n\t},\n\t'constituent-vnfd': {\n\t\tserialize(cvnfdModel) {\n\t\t\treturn _.pick(cvnfdModel, cvnfdFields);\n\t\t}\n\t},\n\tvnfd: {\n\t\tserialize(vnfdModel) {\n\t\t\tconst confd = _.pick(vnfdModel, vnfdFields);\n\t\t\tconfd.vdu = confd.vdu.map(d => serializers.serialize(d));\n\t\t\treturn confd;\n\t\t}\n\t},\n\tvdu: {\n\t\tserialize(vduModel) {\n\t\t\tconst confd = _.omit(vduModel, ['meta']);\n\t\t\treturn confd;\n\t\t}\n\t}\n};\n\nexport default serializers;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorConfDSerializer.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/11/15.\n */\nimport alt from '../alt';\n\nclass CatalogDataSourceActions {\n\n\tconstructor() {\n\t\tthis.generateActions('loadCatalogsSuccess', 'loadCatalogsError', 'deleteCatalogItemSuccess', 'deleteCatalogItemError', 'saveCatalogItemSuccess', 'saveCatalogItemError');\n\t}\n\n}\n\nexport default alt.createActions(CatalogDataSourceActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CatalogDataSourceActions.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./RiftHeader.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./RiftHeader.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./RiftHeader.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/RiftHeader.scss\n ** module id = 461\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.RiftHeader .header-app {\\n  background-color: #f1f1f1;\\n  height: 131px;\\n  padding: 20px 0;\\n  position: relative;\\n}\\n\\n.RiftHeader .header-app h1 {\\n  background: url(\" + require(\"../images/header-logo.png\") + \") no-repeat left center;\\n  height: 51px;\\n  line-height: 51px;\\n  margin-left: 80px;\\n  padding-left: 118px;\\n  position: absolute;\\n  left: 0;\\n  text-transform: uppercase;\\n  font-size: 1.625rem;\\n  font-weight: normal;\\n}\\n\\n.RiftHeader div {\\n  background-color: #f1f1f1;\\n  padding-left: 1.25rem;\\n  display: flex;\\n  margin: 0 0 0.5rem 0;\\n}\\n\\n.RiftHeader div a {\\n  cursor: pointer;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/RiftHeader.scss\n ** module id = 462\n ** module chunks = 0\n **/","module.exports = \"data:image/png;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/header-logo.png\n ** module id = 463\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport React from 'react'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport utils from '../libraries/utils'\nimport messages from './messages'\nimport DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'\nimport CatalogItemCanvasEditor from './CatalogItemCanvasEditor'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport CanvasEditorActions from '../actions/CanvasEditorActions'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport CanvasZoom from './CanvasZoom'\nimport CanvasPanelTray from './CanvasPanelTray'\nimport ForwardingGraphCanvasEditor from './ForwardingGraphPathsEditor'\nimport SelectionManager from '../libraries/SelectionManager'\n\nimport '../styles/CanvasPanel.scss'\n\nconst CanvasPanel = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {};\n\t},\n\tgetDefaultProps() {\n\t\treturn {\n\t\t\ttitle: '',\n\t\t\tlayout: {\n\t\t\t\tleft: 300,\n\t\t\t\tright: 300\n\t\t\t},\n\t\t\tshowMore: false,\n\t\t\tcontainers: []\n\t\t};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t\tSelectionManager.addEventListeners();\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t\tSelectionManager.removeEventListeners();\n\t},\n\trender() {\n\t\tvar style = {\n\t\t\tleft: this.props.layout.left\n\t\t};\n\t\tconst hasItem = this.props.containers.length !== 0;\n\t\tconst hasNoCatalogs = this.props.hasNoCatalogs;\n\t\tconst bodyComponent = hasItem ? <CatalogItemCanvasEditor zoom={this.props.zoom} isShowingMoreInfo={this.props.showMore} containers={this.props.containers}/> : messages.canvasWelcome();\n\t\treturn (\n\t\t\t<div className=\"CanvasPanel\" style={style} onDragOver={this.onDragOver} onDrop={this.onDrop}>\n\t\t\t\t<div className=\"CanvasPanelHeader panel-header\" data-resizable=\"limit_bottom\">\n\t\t\t\t\t<h1>\n\t\t\t\t\t\t<span className=\"model-name\">{this.props.title}</span>\n\t\t\t\t\t</h1>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"CanvasPanelBody panel-body\" style={{marginRight: this.props.layout.right, bottom: this.props.layout.bottom}} >\n\t\t\t\t\t{hasNoCatalogs ? null : bodyComponent}\n\t\t\t\t</div>\n\t\t\t\t<CanvasZoom zoom={this.props.zoom} style={{bottom: this.props.layout.bottom + 20}}/>\n\t\t\t\t<CanvasPanelTray layout={this.props.layout}>\n\t\t\t\t\t<ForwardingGraphCanvasEditor containers={this.props.containers} />\n\t\t\t\t</CanvasPanelTray>\n\t\t\t</div>\n\t\t);\n\t},\n\tonDragOver(event) {\n\t\tconst isDraggingFiles = _.contains(event.dataTransfer.types, 'Files');\n\t\tif (!isDraggingFiles) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.dataTransfer.dropEffect = 'copy';\n\t\t}\n\t},\n\tonDrop(event) {\n\t\t// given a drop event determine which action to take in the canvas:\n\t\t// open item or add item to an existing, already opened nsd\n\t\t// note: nsd is the only editable container\n\t\tconst data = utils.parseJSONIgnoreErrors(event.dataTransfer.getData('text'));\n\t\tif (data.type === 'catalog-item') {\n\t\t\tthis.handleDropCatalogItem(event, data);\n\t\t} else if (data.type === 'action') {\n\t\t\tthis.handleDropCanvasAction(event, data);\n\t\t}\n\t},\n\thandleDropCanvasAction(event, data) {\n\t\tif (data.action === 'add-vld') {\n\t\t\tevent.preventDefault();\n\t\t\tthis.addVirtualLink({clientX: event.clientX, clientY: event.clientY});\n\t\t} else if (data.action === 'add-vnffgd') {\n\t\t\tevent.preventDefault();\n\t\t\tthis.addForwardingGraph({clientX: event.clientX, clientY: event.clientY});\n\t\t}\n\t},\n\thandleDropCatalogItem(event, data) {\n\t\tlet openItem = null;\n\t\tconst currentItem = this.props.containers[0];\n\t\tif (data.item.meta.type === 'nsd') {\n\t\t\t// if item is an nsd then open the descriptor in the canvas\n\t\t\topenItem = data.item;\n\t\t\t// if item is a vnfd or pnfd then check if the current item is an nsd\n\t\t} else if (DescriptorModelFactory.isNetworkService(currentItem)) {\n\t\t\t// so add the item to the nsd and re-render the canvas\n\t\t\tswitch (data.item.meta.type) {\n\t\t\tcase 'vnfd':\n\t\t\t\tthis.addVirtualNetworkFunction(data.item, {clientX: event.clientX, clientY: event.clientY});\n\t\t\t\tbreak;\n\t\t\tcase 'pnfd':\n\t\t\t\tthis.addPhysicalNetworkFunction(data.item, {clientX: event.clientX, clientY: event.clientY});\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tconsole.warn(`Unknown catalog-item type. Expect type \"nsd\", \"vnfd\" or \"pnfd\" but got ${data.item.meta.type}.`);\n\t\t\t}\n\t\t} else {\n\t\t\t// otherwise the default action is to open the item\n\t\t\topenItem = data.item;\n\t\t}\n\t\tif (openItem) {\n\t\t\tevent.preventDefault();\n\t\t\tCatalogItemsActions.editCatalogItem(openItem);\n\t\t}\n\t},\n\taddVirtualLink(dropCoordinates) {\n\t\tconst currentItem = this.props.containers[0];\n\t\tif (DescriptorModelFactory.isNetworkService(currentItem)) {\n\t\t\tconst vld = currentItem.createVld();\n\t\t\tvld.meta.dropCoordinates = dropCoordinates;\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(currentItem);\n\t\t}\n\t},\n\taddForwardingGraph(dropCoordinates) {\n\t\tconst currentItem = this.props.containers[0];\n\t\tif (DescriptorModelFactory.isNetworkService(currentItem)) {\n\t\t\tconst vld = currentItem.createVnffgd();\n\t\t\tvld.meta.dropCoordinates = dropCoordinates;\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(currentItem);\n\t\t}\n\t},\n\taddVirtualNetworkFunction(model, dropCoordinates) {\n\t\tconst currentItem = this.props.containers[0];\n\t\tif (DescriptorModelFactory.isNetworkService(currentItem)) {\n\t\t\tconst vnfd = DescriptorModelFactory.newVirtualNetworkFunction(model);\n\t\t\tconst cvnfd = currentItem.createConstituentVnfdForVnfd(vnfd);\n\t\t\tcvnfd.meta.dropCoordinates = dropCoordinates;\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(currentItem);\n\t\t}\n\t},\n\taddPhysicalNetworkFunction(model, dropCoordinates) {\n\t\tconst currentItem = this.props.containers[0];\n\t\tif (DescriptorModelFactory.isNetworkService(currentItem)) {\n\t\t\tconst pnfd = DescriptorModelFactory.newPhysicalNetworkFunction(model);\n\t\t\tpnfd.meta.dropCoordinates = dropCoordinates;\n\t\t\tcurrentItem.createPnfd(pnfd);\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(currentItem);\n\t\t}\n\t}\n});\n\nexport default CanvasPanel;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CanvasPanel.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/20/15.\n */\n'use strict';\n\nimport React from 'react'\n\nimport imgOnboard from '../images/upload109.svg'\n\nconst message = {\n\tdetailsWelcome() {\n\t\treturn <p className=\"welcome-message\">Select an object to view details.</p>;\n\t},\n\tcanvasWelcome() {\n\t\treturn (\n\t\t\t<span>\n\t\t\t\t<p className=\"welcome-message\">Double-click a Descriptor to open.</p>\n\t\t\t\t<p className=\"welcome-message\">Or drag a Descriptor to add to Canvas.</p>\n\t\t\t</span>\n\t\t);\n\t},\n\tget showMoreTitle() {\n\t\treturn 'Show More';\n\t},\n\tget showLessTitle() {\n\t\treturn 'Show Less';\n\t},\n\tget catalogWelcome() {\n\t\treturn <p className=\"welcome-message\">To onboard a descriptor, drag the package to the catalog or click the Onboard button (<img style={{width: '20px'}} src={imgOnboard} />) to select the package.</p>;\n\t},\n\tgetSaveActionLabel(isNew) {\n\t\treturn isNew ? 'Onboard' : 'Update';\n\t}\n};\n\nexport default message;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/messages.js\n **/","module.exports = __webpack_public_path__ + \"e2e83528bb717142f18e0ae8724e2308.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/upload109.svg\n ** module id = 466\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport DescriptorGraph from '../libraries/graph/DescriptorGraph'\nimport ReactTooltip from 'react-tooltip'\nimport ComposerAppStore from '../stores/ComposerAppStore'\n\nimport '../styles/CatalogItemCanvasEditor.scss'\nimport '../styles/DescriptorGraph.scss'\n\nconst CatalogItemCanvasEditor = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {\n\t\t\tgraph: null\n\t\t};\n\t},\n\tgetDefaultProps() {\n\t\treturn {\n\t\t\tzoom: 100,\n\t\t\tcontainers: [],\n\t\t\tisShowingMoreInfo: false\n\t\t};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t\tconst element = ReactDOM.findDOMNode(this.refs.descriptorGraph);\n\t\tconst options = {\n\t\t\tzoom: this.props.zoom\n\t\t};\n\t\tconst graph = new DescriptorGraph(element, options);\n\t\tgraph.containers = this.props.containers;\n\t\tthis.setState({graph: graph});\n\t},\n\tcomponentDidUpdate() {\n\t\tthis.state.graph.containers = this.props.containers;\n\t\tconst isNSD = this.props.containers[0] && this.props.containers[0].meta.type === 'nsd';\n\t\tif (isNSD) {\n\t\t\tthis.state.graph.showMoreInfo = this.props.isShowingMoreInfo;\n\t\t} else {\n\t\t\tthis.state.graph.showMoreInfo = true;\n\t\t}\n\t\tthis.state.graph.update();\n\t\ttry {\n\t\t\t// todo fix tooltips for IE11 - it throws an error\n\t\t\tReactTooltip.rebuild();\n\t\t} catch (ignore) {}\n\t},\n\tcomponentWillUnmount() {\n\t\tthis.state.graph.destroy();\n\t},\n\trender() {\n\t\tconst graph = this.state.graph;\n\t\tif (graph) {\n\t\t\tgraph.zoom(this.props.zoom);\n\t\t}\n\t\treturn (\n\t\t\t<div data-offset-parent=\"true\" className=\"CatalogItemCanvasEditor\">\n\t\t\t\t<div key=\"outline-indicator\" data-outline-indicator=\"true\"></div>\n\t\t\t\t<div id='canvas-dropzone' style={{visibility: 'hidden'}}></div>\n\t\t\t\t<div ref=\"descriptorGraph\" className=\"DescriptorGraph\"></div>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default CatalogItemCanvasEditor;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogItemCanvasEditor.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/24/15.\n */\n'use strict';\n\nimport _ from 'lodash'\nimport d3 from 'd3'\nimport math from './math'\nimport ClassNames from 'classnames'\nimport ColorGroups from '../ColorGroups'\nimport DescriptorModel from './../model/DescriptorModel'\nimport DescriptorModelFactory from './../model/DescriptorModelFactory'\nimport DescriptorGraphSelection from './DescriptorGraphSelection'\nimport DescriptorGraphEdgeBuilder from './DescriptorGraphPathBuilder'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\nimport DescriptorGraphGrid from './DescriptorGraphGrid'\nimport SelectionManager from './../SelectionManager'\nimport GraphConnectionPointNumber from './GraphConnectionPointNumber'\nimport RelationsAndNetworksLayout from './layouts/RelationsAndNetworksLayout'\n\nconst defaults = {\n\twidth: 1000,\n\theight: 500,\n\tpadding: 10,\n\tsnapTo: 15,\n\tzoom: 100,\n\tconnectionPointSize: 135\n};\n\nexport default class DescriptorGraph {\n\n\tconstructor(element, props) {\n\n\t\tthis.element = element;\n\t\tthis.props = Object.assign({}, props, defaults);\n\t\tthis.layouts = [RelationsAndNetworksLayout];\n\t\tthis.containers = [];\n\t\tthis.showMoreInfo = false;\n\t\tthis.scale = 1;\n\n\t\tif (!element) {\n\t\t\tthrow new ReferenceError('An HTML DOM element is required to render DescriptorGraph.');\n\t\t}\n\n\t\tthis.svg = d3.select(element).append('svg')\n\t\t\t.attr('class', 'DescriptorGraph')\n\t\t\t.attr('width', this.props.width)\n\t\t\t.attr('height', this.props.height)\n\t\t\t.attr('data-offset-parent', true);\n\n\t\tthis.g = this.svg.append('g')\n\t\t\t.attr('class', 'viewport');\n\n\t\t// set the scale of everything\n\t\tthis.zoom(this.props.zoom || defaults.zoom);\n\n\t\tthis.defs = this.svg.append('defs');\n\t\tthis.grid = this.g.append('g').classed('grid', true);\n\t\tthis.paths = this.g.append('g').classed('paths', true);\n\t\tthis.connectorsGroup = this.g.append('g').classed('connectors', true);\n\t\tthis.containersGroup = this.g.append('g').classed('containers', true);\n\t\tthis.cpNumbers = this.g.append('g').classed('connection-point-numbers', true);\n\t\tthis.forwardingGraphPaths = this.g.append('g').classed('forwarding-graph-paths', true);\n\t\tthis.selectionOutlineGroup = this.g.append('g').attr('data-outline-indicator', true);\n\n\t\tthis.defs.append('marker')\n\t\t\t.attr({\n\t\t\t\tid: 'relation-marker-end',\n\t\t\t\t'markerWidth': 30,\n\t\t\t\t'markerHeight': 30,\n\t\t\t\t'orient': '0',\n\t\t\t\t//markerUnits: 'userSpaceOnUse'\n\t\t\t\tviewBox: '-15 -15 30 30'\n\t\t\t})\n\t\t\t.append('path')\n\t\t\t.attr({\n\t\t\t\td: d3.svg.symbol().type('circle'),\n\t\t\t\t'class': 'relation-marker-end'\n\t\t\t});\n\n\t\tthis.update();\n\n\t}\n\n\tzoom(zoom) {\n\t\tconst scale = zoom / 100;\n\t\tif (this.scale !== scale) {\n\t\t\tthis.scale = scale;\n\t\t\tconst transform = 'scale(' + this.scale + ')';\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.g.attr('transform', transform);\n\t\t\t});\n\t\t}\n\t}\n\n\tget containerPositionMap() {\n\t\tif (this.containers[0].meta.containerPositionMap) {\n\t\t\treturn this.containers[0].meta.containerPositionMap;\n\t\t} else {\n\t\t\treturn this.containers[0].meta.containerPositionMap = {};\n\t\t}\n\t}\n\n\tlookupSavedContainerPosition(container) {\n\t\treturn this.containerPositionMap[container.key];\n\t}\n\n\tsaveContainerPosition(container) {\n\t\tthis.containerPositionMap[container.key] = container.position.value();\n\t}\n\n\tupdate() {\n\n\t\tconst graph = this;\n\n\t\tconst filterContainers = d => (graph.showMoreInfo ? true : d.type !== 'vdu');\n\t\tconst containers = this.containers.filter(filterContainers);\n\t\tconst layouts = graph.layouts.map(layoutFactory => layoutFactory.bind(this)());\n\n\t\tfunction runLayout(i) {\n\t\t\tconst layout = layouts[i];\n\t\t\tif (layout) {\n\t\t\t\tlayout.addContainers(containers);\n\t\t\t\tlayout.render(graph, runLayout.bind(null, i + 1));\n\t\t\t}\n\t\t}\n\t\trunLayout(0);\n\n\t\tconst selection = new DescriptorGraphSelection(graph);\n\t\tselection.addContainers(containers);\n\t\tselection.render();\n\n\t\tconst edgeBuilder = new DescriptorGraphEdgeBuilder(graph);\n\t\tedgeBuilder.addContainers(containers);\n\t\tedgeBuilder.render();\n\n\t\tconst grid = new DescriptorGraphGrid(graph, {size: defaults.snapTo, padding: defaults.padding});\n\t\tgrid.render();\n\n\t}\n\n\tdestroy() {\n\t\tif (this.svg) {\n\t\t\tthis.svg.remove();\n\t\t\tdelete this.svg;\n\t\t}\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/DescriptorGraph.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 9/1/15.\n */\n\nimport Position from './Position'\n\nconst angleOfLine = function (x1, y1, x2, y2) {\n\n\tconst y = y2 - y1;\n\tconst x = x2 - x1;\n\n\tconst rad = Math.atan2(y, x);\n\tconst deg = Math.abs(rad * 180 / Math.PI);\n\n\tlet addDeg = 0;\n\n\tif (rad <= 0) {\n\t\taddDeg = 360;\n\t}\n\n\t// - addDeg bc atan2 returns -π to π where -π is the upper side of rectangle\n\t// - 360 bc our ui grid system has zero in upper left corner not lower left\n\treturn Math.abs(Math.abs(deg - addDeg) - 360);\n\n};\n\nconst angleBetweenPositions = function (src, dst) {\n\tif (!src instanceof Position) {\n\t\tthrow new ReferenceError('require a position instance');\n\t}\n\tif (!dst instanceof Position) {\n\t\tthrow new ReferenceError('require a position instance');\n\t}\n\tconst srcCenter = src.centerPoint();\n\tconst dstCenter = dst.centerPoint();\n\treturn angleOfLine(srcCenter.x, srcCenter.y, dstCenter.x, dstCenter.y);\n};\n\nconst distanceBetweenPositions = function (src, dst) {\n\tif (!src instanceof Position) {\n\t\tthrow new ReferenceError('require a position instance');\n\t}\n\tif (!dst instanceof Position) {\n\t\tthrow new ReferenceError('require a position instance');\n\t}\n\tconst srcCenter = src.centerPoint();\n\tconst dstCenter = dst.centerPoint();\n\tconst x = Math.pow(dstCenter.x - srcCenter.x, 2);\n\tconst y = Math.pow(dstCenter.y - srcCenter.y, 2);\n\tconst distance = Math.sqrt((x) + (y));\n\tif (isNaN(distance)) {\n\t\tconsole.log('nan distance', srcCenter, dstCenter);\n\t}\n\treturn distance;\n};\n\nconst rectangleAnglesFromCenter = function (position) {\n\t/* given a rectangle defined by a Position, determine the angle of each corner from center.\n\t // note: 0˚ is on x-axis; angles are given counterclockwise from x-axis\n\t // for example:\n\t // the line AB(0, 0, 5, 0) would have angle 0˚\n\t // the line AC(0, 0, 0, 5) would have angle 90˚\n\t // the line BC(5, 0, 0, 5) would have angle 135˚\n\t // the line BA(5, 0, 0, 0) would have angle 180˚\n\t */\n\tif (!position instanceof Position) {\n\t\tthrow new ReferenceError('require a Position instance');\n\t}\n\tconst center = position.centerPoint();\n\treturn [\n\t\tangleOfLine(center.x, center.y, position.right, position.top),\n\t\tangleOfLine(center.x, center.y, position.left, position.top),\n\t\tangleOfLine(center.x, center.y, position.left, position.bottom),\n\t\tangleOfLine(center.x, center.y, position.right, position.bottom)\n\t];\n};\n\nconst edgeLocation = function (rectangleInclinations) {\n\t/* given the angle of a line, determine which edge of the rectangle the line should attach. */\n\tlet inclinations = rectangleInclinations;\n\tif (rectangleInclinations instanceof Position) {\n\t\tinclinations = rectangleAnglesFromCenter(rectangleInclinations);\n\t}\n\treturn angle => {\n\t\tangle = parseFloat(angle);\n\t\tif (angle >= inclinations[3]) {\n\t\t\treturn 'right';\n\t\t}\n\t\tif (angle >= 270) {\n\t\t\treturn 'bottom-right';\n\t\t}\n\t\tif (angle >= inclinations[2]) {\n\t\t\treturn 'bottom-left';\n\t\t}\n\t\tif (angle >= inclinations[1]) {\n\t\t\treturn 'left';\n\t\t}\n\t\tif (angle >= 90) {\n\t\t\treturn 'top-left';\n\t\t}\n\t\tif (angle >= inclinations[0]) {\n\t\t\treturn 'top-right';\n\t\t}\n\t\treturn 'right';\n\t};\n};\n\nconst upperLowerEdgeLocation = function (angle) {\n\tangle = parseFloat(angle);\n\tif (angle > 270) {\n\t\treturn 'bottom-right';\n\t}\n\tif (angle > 180) {\n\t\treturn 'bottom-left';\n\t}\n\tif (angle > 90) {\n\t\treturn 'top-left';\n\t}\n\treturn 'top-right';\n};\n\nexport default {\n\tangleOfLine: angleOfLine,\n\tangleBetweenPositions: angleBetweenPositions,\n\tdistanceBetweenPositions: distanceBetweenPositions,\n\tanglesFromCenter: rectangleAnglesFromCenter,\n\tedgeLocation: edgeLocation,\n\tupperLowerEdgeLocation: upperLowerEdgeLocation\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/math.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Provide the visual treatment for selecting elements in the Canvas.\n *\n * Clicking on a Descriptor toggles selection.\n * Clicking on a Path toggles selection.\n * Clicking on the SVG container removes selection.\n * Only one thing can be selected at a time.\n *\n */\nimport d3 from 'd3'\nimport DescriptorModelFactory from './../model/DescriptorModelFactory'\nimport ComposerAppActions from '../../actions/ComposerAppActions'\nimport SelectionManager from '../SelectionManager'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\n\nexport default class DescriptorGraphSelection {\n\n\tconstructor(graph) {\n\t\tthis.graph = graph;\n\t\tthis.containers = [];\n\t}\n\n\taddContainers(containers) {\n\t\tthis.containers = containers;\n\t}\n\n\trender() {\n\n\t\tconst comp = this;\n\n\t\t// prevent multiple bindings of the same listener\n\t\tthis.unbindListeners();\n\n\t\t// clicking on the background deselects all descriptors\n\t\tcomp.boundClickSVGHandler = function () {\n\t\t\t// do not deselect if user is dragging: https://github.com/mbostock/d3/issues/1445\n\t\t\tif (d3.event.defaultPrevented) return;\n\t\t\tconst target = SelectionManager.getClosestElementWithUID(d3.event.target);\n\t\t\tif (target) {\n\t\t\t\tconst data = d3.select(target).datum() || {};\n\t\t\t\tif (target && DescriptorModelFactory.isContainer(data)) {\n\t\t\t\t\tComposerAppActions.selectModel(data);\n\t\t\t\t\tComposerAppActions.outlineModel(data);\n\t\t\t\t} else {\n\t\t\t\t\tComposerAppActions.clearSelection();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tComposerAppActions.clearSelection();\n\t\t\t}\n\t\t};\n\t\tcomp.graph.svg.on('click.selection', comp.boundClickSVGHandler);\n\n\t}\n\n\tunbindListeners() {\n\t\tthis.graph.svg.on('.selection', null);\n\t}\n\n\tdestroy() {\n\t\tthis.unbindListeners();\n\t\tthis.containers.length = 0;\n\t\tthis.graph = null;\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/DescriptorGraphSelection.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by kkashalk on 11/30/15.\n */\nimport alt from '../alt';\n\nclass ComposerAppActions {\n\n\tconstructor() {\n\t\tthis.generateActions('showError', 'clearError', 'setDragState', 'propertySelected', 'showJsonViewer', 'closeJsonViewer', 'selectModel', 'outlineModel', 'clearSelection');\n\t}\n\n}\n\nexport default alt.createActions(ComposerAppActions);\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/ComposerAppActions.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Draw edges by dragging a ConnectionPoint to VNFD, VLD or another ConnectionPoint.\n *\n * If VLD does not exist between two VNFDs then add one.\n *\n * CSS for this class is defined in DescriptorGraph.scss.\n *\n */\n\nimport d3 from 'd3'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\nimport SelectionManager from '../SelectionManager'\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\n\nconst line = d3.svg.line()\n\t.x(d => {\n\t\treturn d.x;\n\t})\n\t.y(d => {\n\t\treturn d.y;\n\t});\n\nfunction mouseWithinPosition(position, mouseCoordinates, scale = 1) {\n\tconst x = mouseCoordinates[0] / scale;\n\tconst y = mouseCoordinates[1] / scale;\n\tconst withinXBoundary = position.left < x && position.right > x;\n\tconst withinYBoundary = position.top < y && position.bottom > y;\n\treturn withinXBoundary && withinYBoundary;\n}\n\nfunction getContainerUnderMouse(comp, element, scale) {\n\t// determine if there is a connection point\n\tconst dstConnectionPoint = comp.connectionPoints().filter(d => {\n\t\tif (d.type === 'connection-point') {\n\t\t\treturn mouseWithinPosition(d.position, d3.mouse(element), scale);\n\t\t}\n\t});\n\tif (dstConnectionPoint[0].length) {\n\t\treturn dstConnectionPoint;\n\t} else {\n\t\t// otherwise determine if destination is a VLD\n\t\tconst dstVirtualLink = comp.descriptors().filter(d => {\n\t\t\treturn d.type === 'vld' && mouseWithinPosition(d.position, d3.mouse(element), scale);\n\t\t});\n\t\tif (dstVirtualLink[0].length) {\n\t\t\treturn dstVirtualLink;\n\t\t}\n\t}\n}\n\nexport default class DescriptorGraphPathBuilder {\n\n\tconstructor(graph) {\n\t\tthis.graph = graph;\n\t\tthis.containers = [];\n\t}\n\n\tdescriptors() {\n\t\treturn this.graph.containersGroup.selectAll('.descriptor');\n\t}\n\n\tconnectionPoints() {\n\t\treturn this.graph.connectorsGroup.selectAll('.connector');\n\t}\n\n\tpaths() {\n\t\treturn this.graph.g.selectAll('.connection');\n\t}\n\n\taddContainers(containers) {\n\t\tthis.containers = this.containers.concat(containers);\n\t}\n\n\tstatic addConnection(srcSelection, dstSelection) {\n\n\t\t// return true on success; falsy otherwise to allow the caller to clean up accordingly\n\n\t\tif (srcSelection[0].length === 0 || dstSelection[0].length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst srcConnector = srcSelection.datum();\n\t\tconst dstConnector = dstSelection.datum();\n\n\t\t// dstConnector can be a Connection Point or a VLD - branch accordingly\n\n\t\tif (srcConnector.parent === dstConnector.parent) {\n\t\t\t// connection points cannot connect to same VNFD\n\t\t\treturn false;\n\t\t}\n\n\t\tconst nsdContainer = srcConnector.getRootNSDContainer();\n\n\t\tif (nsdContainer) {\n\t\t\tconst vld = nsdContainer.createVld();\n\t\t\tnsdContainer.removeAnyConnectionsForConnector(srcConnector);\n\t\t\tnsdContainer.removeAnyConnectionsForConnector(dstConnector);\n\t\t\tvld.addConnectionPoint(srcConnector);\n\t\t\tvld.addConnectionPoint(dstConnector);\n\n\t\t\t// notify catalog items have changed to force a redraw and update state accordingly\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(nsdContainer);\n\n\t\t\treturn true;\n\t\t}\n\n\t}\n\n\tstatic addConnectionToVLD(srcSelection, dstSelection) {\n\n\t\tif (srcSelection[0].length === 0 || dstSelection[0].length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst dstVirtualLink = dstSelection.datum();\n\t\tconst srcConnectionPoint = srcSelection.datum();\n\n\t\tdstVirtualLink.addConnectionPoint(srcConnectionPoint);\n\n\t\t// notify catalog items have changed to force a redraw and update state accordingly\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(dstVirtualLink.getRoot());\n\n\t\treturn true;\n\n\t}\n\n\trender() {\n\n\t\t/*\n\t\t\tStrategy: compare mouse position with the position of all the selectable elements.\n\t\t\tOn mouse down:\n\t\t\t    determine if there is a connection point under the mouse (the source)\n\t\t\t    determine if there is already a path connected on this source\n\t\t\tOn mouse move:\n\t\t\t    draw a tracer line from the source to the mouse\n\t\t\tOn mouse up:\n\t\t\t    determine if there is a connection point or VLD under the mouse (the destination)\n\t\t\t    take the respective action and notify\n\t\t */\n\n\t\tconst comp = this;\n\t\tconst drawLine = line.interpolate('basis');\n\n\t\tcomp.boundMouseDownHandler = function (d) {\n\n\t\t\tlet hasInitializedMouseMoveHandler = false;\n\n\t\t\t//SelectionManager.clearSelectionAndRemoveOutline();\n\n\t\t\tconst srcConnectionPoint = comp.connectionPoints().filter(d => {\n\t\t\t\tif (d.type === 'connection-point') {\n\t\t\t\t\treturn mouseWithinPosition(d.position, d3.mouse(this), comp.graph.scale);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (srcConnectionPoint[0].length) {\n\n\t\t\t\tconst src = srcConnectionPoint.datum() || {};\n\n\t\t\t\t// determine if there is already a path on this connection point\n\t\t\t\t// if there is then hide it; the mouseup handler will clean up\n\t\t\t\tconst existingPath = comp.paths().filter(d => {\n\t\t\t\t\treturn d && d.parent && d.parent.type === 'vld' && d.key === src.key;\n\t\t\t\t});\n\n\t\t\t\t// create a new path to follow the mouse\n\t\t\t\tconst path = comp.graph.paths.selectAll('.new-connection').data([srcConnectionPoint.datum()], DescriptorModelFactory.containerIdentity);\n\t\t\t\tpath.enter().append('path').classed('new-connection', true);\n\t\t\t\tcomp.boundMouseMoveHandler = function () {\n\n\t\t\t\t\tconst mouseCoordinates = d3.mouse(this);\n\n\t\t\t\t\tpath.attr({\n\t\t\t\t\t\tfill: 'red',\n\t\t\t\t\t\tstroke: 'red',\n\t\t\t\t\t\t'stroke-width': '4px',\n\t\t\t\t\t\td: d => {\n\t\t\t\t\t\t\tconst srcPosition = d.position.centerPoint();\n\t\t\t\t\t\t\tconst dstPosition = {\n\t\t\t\t\t\t\t\tx: mouseCoordinates[0] / comp.graph.scale,\n\t\t\t\t\t\t\t\ty: mouseCoordinates[1] / comp.graph.scale\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\treturn drawLine([srcPosition, dstPosition]);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!hasInitializedMouseMoveHandler) {\n\t\t\t\t\t\thasInitializedMouseMoveHandler = true;\n\n\t\t\t\t\t\texistingPath.style({\n\t\t\t\t\t\t\topacity: 0\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// allow for visual treatment of this drag operation\n\t\t\t\t\t\tsrcConnectionPoint.classed('-selected', true);\n\n\t\t\t\t\t\t// allow for visual treatment of this drag operation\n\t\t\t\t\t\tcomp.graph.svg.classed('-is-dragging-connection-point', true);\n\n\t\t\t\t\t\t// identify which descriptors are a valid drop target\n\t\t\t\t\t\tcomp.descriptors().filter(d => {\n\t\t\t\t\t\t\tif (srcConnectionPoint.datum().key === d.key) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (d.type === 'vld') {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}).classed('-is-valid-drop-target', true);\n\n\t\t\t\t\t\t// identify which connection points are a valid drop target\n\t\t\t\t\t\tcomp.connectionPoints().filter(d => {\n\t\t\t\t\t\t\tconst src = srcConnectionPoint.datum();\n\t\t\t\t\t\t\treturn !(src.key === d.key || src.parent.key === d.parent.key || d.type === 'internal-connection-point');\n\t\t\t\t\t\t}).classed('-is-valid-drop-target', true);\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst validDropTarget = getContainerUnderMouse(comp, this, comp.graph.scale);\n\t\t\t\t\tcomp.graph.g.selectAll('.-is-drag-over').classed('-is-drag-over', false);\n\t\t\t\t\tif (validDropTarget) {\n\t\t\t\t\t\tvalidDropTarget.classed('-is-drag-over', true);\n\t\t\t\t\t}\n\n\t\t\t\t};\n\n\t\t\t\t// determine what the interaction is and do it\n\t\t\t\tcomp.boundMouseUpHandler = function () {\n\n\t\t\t\t\t// remove these handlers so they start fresh on the next drag operation\n\t\t\t\t\tcomp.graph.svg\n\t\t\t\t\t\t.on('mouseup.edgeBuilder', null)\n\t\t\t\t\t\t.on('mousemove.edgeBuilder', null);\n\n\t\t\t\t\t// remove visual treatments\n\t\t\t\t\tcomp.graph.svg.classed('-is-dragging-connection-point', false);\n\t\t\t\t\tcomp.descriptors().classed('-is-valid-drop-target', false);\n\t\t\t\t\tcomp.connectionPoints().classed('-is-valid-drop-target', false);\n\t\t\t\t\tcomp.graph.g.selectAll('.-is-drag-over').classed('-is-drag-over', false);\n\n\t\t\t\t\t// determine if there is a connection point\n\t\t\t\t\tconst dstConnectionPoint = comp.connectionPoints().filter(d => {\n\t\t\t\t\t\tif (d.type === 'connection-point') {\n\t\t\t\t\t\t\treturn mouseWithinPosition(d.position, d3.mouse(this), comp.graph.scale);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (dstConnectionPoint[0].length) {\n\t\t\t\t\t\tconst src = srcConnectionPoint.datum();\n\t\t\t\t\t\tconst dst = dstConnectionPoint.datum();\n\t\t\t\t\t\tif (src.key !== dst.key) {\n\t\t\t\t\t\t\t// do not drop on self\n\t\t\t\t\t\t\tif (DescriptorGraphPathBuilder.addConnection(srcConnectionPoint, dstConnectionPoint)) {\n\t\t\t\t\t\t\t\texistingPath.remove();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// otherwise determine if destination is a VLD\n\t\t\t\t\t\tconst dstVirtualLink = comp.descriptors().filter(d => {\n\t\t\t\t\t\t\treturn d.type === 'vld' && mouseWithinPosition(d.position, d3.mouse(this), comp.graph.scale);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (dstVirtualLink[0].length) {\n\t\t\t\t\t\t\tif (DescriptorGraphPathBuilder.addConnectionToVLD(srcConnectionPoint, dstVirtualLink)) {\n\t\t\t\t\t\t\t\texistingPath.remove();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// if we hid an existing path restore it\n\t\t\t\t\texistingPath.style({\n\t\t\t\t\t\topacity: null\n\t\t\t\t\t});\n\n\t\t\t\t\t// remove the tracer path\n\t\t\t\t\tpath.remove();\n\n\t\t\t\t};\n\n\t\t\t\t// init drag handlers\n\t\t\t\tcomp.graph.svg\n\t\t\t\t\t.on('mouseup.edgeBuilder', comp.boundMouseUpHandler)\n\t\t\t\t\t.on('mousemove.edgeBuilder', comp.boundMouseMoveHandler);\n\t\t\t}\n\n\t\t};\n\n\t\t// enable dragging features\n\t\tcomp.graph.svg\n\t\t\t.on('mousedown.edgeBuilder', comp.boundMouseDownHandler);\n\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/DescriptorGraphPathBuilder.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 12/3/15.\n */\n\nimport d3 from 'd3'\n\nconst defaults = {\n\tsize: 15,\n\tpadding: 5\n};\n\nexport default class DescriptorGraphGrid {\n\n\tconstructor(graph, props) {\n\t\tthis.graph = graph;\n\t\tObject.assign(props, defaults);\n\t\tthis.size = props.size;\n\t\tthis.padding = props.padding;\n\t}\n\n\trender() {\n\n\t\tconst grid = this.graph.grid;\n\t\tconst width = 2 * this.graph.svg.attr('width');\n\t\tconst height = 2 * this.graph.svg.attr('height');\n\t\tconst yAxis = d3.range(0, height, this.size);\n\t\tconst xAxis = d3.range(0, width, this.size);\n\n\t\tgrid.selectAll('line.vertical')\n\t\t\t.data(xAxis)\n\t\t\t.enter().append('svg:line')\n\t\t\t.classed('vertical', true)\n\t\t\t.attr('x1', (d) => d)\n\t\t\t.attr('y1', 0)\n\t\t\t.attr('x2', (d) => d)\n\t\t\t.attr('y2', height);\n\n\t\tgrid.selectAll('line.horizontal')\n\t\t\t.data(yAxis)\n\t\t\t.enter().append('svg:line')\n\t\t\t.classed('horizontal', true)\n\t\t\t.attr('x1', 0)\n\t\t\t.attr('y1', (d) => d)\n\t\t\t.attr('x2', width)\n\t\t\t.attr('y2', (d) => d);\n\n\t}\n\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/DescriptorGraphGrid.js\n **/","/**\n * Created by onvelocity on 2/8/16.\n */\n'use strict';\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nconst defaults = {\n\tadjustTop: -9,\n\tadjustBottom: 21\n};\nexport default class GraphConnectionPointNumber {\n\n\tconstructor(graph, props) {\n\t\tthis.cpNumbersGroup = graph.cpNumbers;\n\t\tObject.assign(this, defaults, props);\n\t\tthis.containers = [];\n\t}\n\n\taddContainers(containers) {\n\t\tthis.containers = containers.filter(d => DescriptorModelFactory.isConnectionPoint(d));\n\t}\n\n\trender() {\n\t\tconst cpNumber = this.cpNumbersGroup.selectAll('.connection-point-number').data(this.containers, d => d.uid);\n\t\tcpNumber.enter().append('text').text(d => d.meta.cpNumber);\n\t\tcpNumber.attr({\n\t\t\t'data-key': d => d.key,\n\t\t\t'data-cp-number': d => d.meta.cpNumber,\n\t\t\t'text-anchor': 'middle',\n\t\t\t'class': 'connection-point-number',\n\t\t\ttransform: d => {\n\t\t\t\tconst point = d.position.centerPoint();\n\t\t\t\tconst yAdjust = (/top/.test(d.location) ? this.adjustTop : this.adjustBottom);\n\t\t\t\treturn 'translate(' + (point.x) + ', ' + (point.y + yAdjust) + ')';\n\t\t\t}\n\t\t});\n\t\tcpNumber.exit().remove();\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphConnectionPointNumber.js\n **/","/**\n * Created by onvelocity on 2/10/16.\n */\nimport alt from '../../../alt'\nimport d3 from 'd3'\nimport math from '../math'\nimport ClassNames from 'classnames'\nimport ColorGroups from '../../ColorGroups'\nimport GraphVirtualLink from '../GraphVirtualLink'\nimport GraphNetworkService from '../GraphNetworkService'\nimport GraphForwardingGraph from '../GraphForwardingGraph'\nimport GraphConstituentVnfd from '../GraphConstituentVnfd'\nimport GraphVirtualNetworkFunction from '../GraphVirtualNetworkFunction'\nimport SelectionManager from '../../SelectionManager'\nimport GraphConnectionPointNumber from '../GraphConnectionPointNumber'\nimport CatalogItemsActions from '../../../actions/CatalogItemsActions'\nimport DescriptorModelFactory from '../../model/DescriptorModelFactory'\nimport DescriptorGraphSelection from '../DescriptorGraphSelection'\nimport GraphVirtualDeploymentUnit from '../GraphVirtualDeploymentUnit'\nimport GraphRecordServicePath from '../GraphRecordServicePath'\n\nfunction onCutDelegateToRemove(container) {\n\tfunction onCut(event) {\n\t\tevent.target.removeEventListener('cut', onCut);\n\t\tif (container.remove()) {\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());\n\t\t} else {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\tthis.addEventListener('cut', onCut);\n}\n\nexport default function RelationsAndNetworksLayout() {\n\n\tconst graph = this;\n\tconst props = this.props;\n\tconst containerWidth = 250;\n\tconst containerHeight = 55;\n\tconst marginTop = 20;\n\tconst marginLeft = 10;\n\tconst containerList = [];\n\tconst leftOffset = containerWidth;\n\n\tconst snapTo = (value) => {\n\t\treturn Math.max(props.snapTo * Math.round(value / props.snapTo), props.padding);\n\t};\n\n\tconst line = d3.svg.line()\n\t\t.x(d => {\n\t\t\treturn d.x;\n\t\t})\n\t\t.y(d => {\n\t\t\treturn d.y;\n\t\t});\n\n\tfunction countAncestors(container = {}) {\n\t\tlet count = 0;\n\t\twhile (container.parent) {\n\t\t\tcount++;\n\t\t\tcontainer = container.parent;\n\t\t}\n\t\treturn count;\n\t}\n\n\tfunction renderRelationPath(src, dst) {\n\t\tconst path = line.interpolate('basis');\n\t\tconst srcPoint = src.position.centerPoint();\n\t\tconst dstPoint = dst.position.centerPoint();\n\t\tconst angle = math.angleBetweenPositions(src.position, dst.position);\n\t\tif (angle < 180) {\n\t\t\tsrcPoint.y = src.position.top;\n\t\t\tdstPoint.y = dst.position.bottom;\n\t\t} else {\n\t\t\tsrcPoint.y = src.position.bottom;\n\t\t\tdstPoint.y = dst.position.top;\n\t\t}\n\t\treturn path([srcPoint, dstPoint]);\n\t}\n\n\tfunction renderConnectionPath(cpRef) {\n\t\tconst path = line.interpolate('basis');\n\t\tconst srcPoint = cpRef.position.centerPoint();\n\t\tconst dstPoint = cpRef.parent.position.centerPoint();\n\t\tconst srcIsTopMounted = /top/.test(cpRef.location);\n\t\t//const srcIsLeftMounted = /left/.test(cpRef.parent.location);\n\t\tconst srcSpline1 = {\n\t\t\tx: srcPoint.x,\n\t\t\ty: (srcIsTopMounted ? cpRef.position.top - 15 : cpRef.position.bottom + 15)\n\t\t};\n\t\tconst srcSpline2 = {\n\t\t\tx: srcPoint.x,\n\t\t\ty: (srcIsTopMounted ? cpRef.position.top - 15 : cpRef.position.bottom + 15)\n\t\t};\n\t\treturn path([srcPoint, srcSpline1, srcSpline2, dstPoint]);\n\t}\n\n\tconst containerLayoutInfo = {\n\t\tnsd: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\ttop() {\n\t\t\t\treturn 10;\n\t\t\t},\n\t\t\tleft(container, layouts) {\n\t\t\t\tconst positionIndex = layouts.vnffgd.list.length + this.list.length;\n\t\t\t\treturn (positionIndex * (this.width * 1.5)) + leftOffset / 2;\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\tvnffgd: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\ttop(container, layouts) {\n\t\t\t\tconst positionIndex = layouts.nsd.list.length + this.list.length;\n\t\t\t\treturn (positionIndex * (this.height * 1.5)) + 20;\n\t\t\t},\n\t\t\tleft(container, layouts) {\n\t\t\t\treturn 10;\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\tvnfd: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\ttop(container) {\n\t\t\t\treturn (countAncestors(container) * 100) + 10;\n\t\t\t},\n\t\t\tleft() {\n\t\t\t\tconst positionIndex = this.list.length;\n\t\t\t\treturn (positionIndex * (this.width * 1.5)) + leftOffset;\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\t'constituent-vnfd': {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\ttop(container) {\n\t\t\t\treturn (countAncestors(container) * 100) + 10;\n\t\t\t},\n\t\t\tleft() {\n\t\t\t\tconst positionIndex = this.list.length;\n\t\t\t\treturn (positionIndex * (this.width * 1.5)) + leftOffset;\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\tpnfd: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\ttop(container) {\n\t\t\t\treturn (countAncestors(container) * 100) + 10;\n\t\t\t},\n\t\t\tleft() {\n\t\t\t\tconst positionIndex = this.list.length;\n\t\t\t\treturn (positionIndex * (this.width * 1.5)) + leftOffset;\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\tvld: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: 38,\n\t\t\ttop(container) {\n\t\t\t\treturn (countAncestors(container) * 100) + 100;\n\t\t\t},\n\t\t\tleft() {\n\t\t\t\tconst positionIndex = this.list.reduce((count, d) => {\n\t\t\t\t\tconst root = d.getRoot();\n\t\t\t\t\tif (root && root.meta.containerPositionMap && !root.meta.containerPositionMap[d.key]) {\n\t\t\t\t\t\tcount++;\n\t\t\t\t\t}\n\t\t\t\t\treturn count;\n\t\t\t\t}, 0);\n\t\t\t\treturn (positionIndex * (containerWidth * 1.5)) + ((containerWidth * 1.5) / 2) + ((containerHeight * 1.5) / 2);\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\tivld: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\ttop(container, containerLayouts) {\n\t\t\t\tconst maxVDUCount = containerList.reduce((maxCount, d) => {\n\t\t\t\t\tif (d.vdu) {\n\t\t\t\t\t\treturn Math.max(maxCount, d.vdu.length);\n\t\t\t\t\t}\n\t\t\t\t\treturn maxCount;\n\t\t\t\t}, 0);\n\t\t\t\treturn (maxVDUCount + 1) * (containerLayouts.vdu.height + containerLayouts.vdu.gutter) + 225;\n\t\t\t},\n\t\t\tleft() {\n\t\t\t\tconst positionIndex = this.list.length;\n\t\t\t\tconst marginOffsetFactor = 1.5;\n\t\t\t\tconst gutterOffsetFactor = 1.5;\n\t\t\t\treturn (positionIndex * (this.width * gutterOffsetFactor)) + ((this.width * marginOffsetFactor) / 2);\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t},\n\t\tvdu: {\n\t\t\tlist: [],\n\t\t\twidth: containerWidth,\n\t\t\theight: containerHeight,\n\t\t\tgutter: 30,\n\t\t\ttop(container) {\n\t\t\t\tconst rowTop = (countAncestors(container) * 100) + 100;\n\t\t\t\tconst positionIndex = this.list.reduce((a, d) => {\n\t\t\t\t\tif (d.parent === container.parent) {\n\t\t\t\t\t\treturn a + 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn a;\n\t\t\t\t}, 0);\n\t\t\t\treturn rowTop + (positionIndex * (this.height + this.gutter));\n\t\t\t},\n\t\t\tleft(container) {\n\t\t\t\tif (container.parent.meta.defaultLayoutPosition) {\n\t\t\t\t\treturn container.parent.meta.defaultLayoutPosition.left;\n\t\t\t\t}\n\t\t\t\treturn container.parent.position.left;\n\t\t\t},\n\t\t\trenderRelationPath: renderRelationPath,\n\t\t\trenderConnectionPath: renderConnectionPath\n\t\t}\n\t};\n\n\tfunction getConnectionPointEdges() {\n\n\t\t// 1. create a lookup map to find a connection-point by it's key\n\t\tconst connectionPointMap = {};\n\t\tcontainerList.filter(d => d.connectionPoint).reduce((result, container) => {\n\t\t\treturn container.connectionPoint.reduce((result, connectionPoint) => {\n\t\t\t\tresult[connectionPoint.key] = connectionPoint;\n\t\t\t\tconnectionPoint.meta.hasConnection = false;\n\t\t\t\treturn result;\n\t\t\t}, result);\n\t\t}, connectionPointMap);\n\n\t\t// 2. determine position of the connection-point and connection-point-ref (they are the same)\n\t\tconst connectionPointRefList = [];\n\t\tcontainerList.filter(container => container.connection).forEach(container => {\n\t\t\tcontainer.meta.hasConnection = false;\n\t\t\tcontainer.connection.forEach(cpRef => {\n\t\t\t\tconst source = connectionPointMap[cpRef.key];\n\t\t\t\tconst destination = container;\n\t\t\t\tsource.meta.hasConnection = true;\n\t\t\t\tdestination.meta.hasConnection = true;\n\t\t\t\tconst edgeStateMachine = math.upperLowerEdgeLocation;\n\t\t\t\t// angle is used to determine location top, bottom, right, left\n\t\t\t\tconst angle = math.angleBetweenPositions(source.parent.position, destination.position);\n\t\t\t\t// distance is used to determine order of the connection points\n\t\t\t\tconst distance = math.distanceBetweenPositions(source.parent.position, destination.position);\n\t\t\t\tcpRef.location = source.location = edgeStateMachine(angle);\n\t\t\t\tsource.edgeAngle = angle;\n\t\t\t\tif (destination.type === 'vdu') {\n\t\t\t\t\tsource.edgeLength = Math.max(source.edgeLength || 0, distance);\n\t\t\t\t}\n\t\t\t\t// warn assigning same instance (e.g. pass by reference) so that changes will reflect thru\n\t\t\t\tcpRef.position = source.position;\n\t\t\t\tconnectionPointRefList.push(cpRef);\n\t\t\t});\n\t\t});\n\n\t\t// 3. update the connection-point/-ref location based on the angle of the path\n\t\tcontainerList.filter(d => d.connectionPoint).forEach(container => {\n\t\t\t// group the connectors by their location and then update their position coordinates accordingly\n\t\t\tconst connectionPoints = container.connectionPoint.sort((a, b) => b.edgeLength - a.edgeLength);\n\t\t\tconst locationIndexCounters = {};\n\t\t\tconnectionPoints.forEach(connectionPoint => {\n\t\t\t\t// location index is used to calculate the actual position where the path will terminate on the container\n\t\t\t\tconst location = connectionPoint.location;\n\t\t\t\tconst locationIndex = locationIndexCounters[location] || (locationIndexCounters[location] = 0);\n\t\t\t\tconnectionPoint.positionIndex = locationIndex;\n\t\t\t\tif (/left/.test(location)) {\n\t\t\t\t\tconnectionPoint.position.moveLeft(connectionPoint.parent.position.left + 5 + ((connectionPoint.width + 1) * locationIndex));\n\t\t\t\t} else {\n\t\t\t\t\tconnectionPoint.position.moveRight(connectionPoint.parent.position.right - 5 - ((connectionPoint.width + 1) * locationIndex));\n\t\t\t\t}\n\t\t\t\tif (/top/.test(location)) {\n\t\t\t\t\tconnectionPoint.position.moveTop(connectionPoint.parent.position.top - connectionPoint.height);\n\t\t\t\t} else {\n\t\t\t\t\tconnectionPoint.position.moveTop(connectionPoint.parent.position.bottom);\n\t\t\t\t}\n\t\t\t\tlocationIndexCounters[location] = locationIndex + 1;\n\t\t\t});\n\t\t});\n\n\t\treturn connectionPointRefList;\n\n\t}\n\n\tfunction drawConnectionPointsAndPaths(graph, connectionPointRefs) {\n\n\t\tconst paths = graph.paths.selectAll('.connection').data(connectionPointRefs, DescriptorModelFactory.containerIdentity);\n\n\t\tpaths.enter().append('path');\n\n\t\tpaths.attr({\n\t\t\t'data-uid': d => {\n\t\t\t\treturn d.uid;\n\t\t\t},\n\t\t\t'class': d => {\n\t\t\t\treturn 'connection between-' + d.parent.type + '-and-' + d.type;\n\t\t\t},\n\t\t\t'stroke-width': 5,\n\t\t\tstroke: ColorGroups.vld.primary,\n\t\t\tfill: 'transparent',\n\t\t\td: edge => {\n\t\t\t\tconst layout = containerLayoutInfo[edge.parent.type];\n\t\t\t\treturn layout.renderConnectionPath(edge, containerLayoutInfo);\n\t\t\t}\n\t\t}).on('cut', (container) => {\n\n\t\t\tlet success = false;\n\n\t\t\tif (container && container.remove) {\n\t\t\t\tsuccess = container.remove();\n\t\t\t}\n\n\t\t\tif (success) {\n\t\t\t\tCatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());\n\t\t\t} else {\n\t\t\t\td3.event.preventDefault();\n\t\t\t}\n\n\t\t\td3.event.stopPropagation();\n\n\t\t});\n\n\t\tpaths.exit().remove();\n\n\t\tconst symbolSize = props.connectionPointSize;\n\t\tconst connectionPointSymbol = d3.svg.symbol().type('square').size(symbolSize);\n\t\tconst internalConnectionPointSymbolBottom = d3.svg.symbol().type('triangle-down').size(symbolSize);\n\t\tconst internalConnectionPointSymbolTop = d3.svg.symbol().type('triangle-up').size(symbolSize);\n\n\t\tconst connectors = containerList.filter(d => d.connectors).reduce((result, container) => {\n\t\t\treturn container.connectors.reduce((result, connector) => {\n\t\t\t\tresult.add(connector);\n\t\t\t\treturn result;\n\t\t\t}, result);\n\t\t}, new Set());\n\n\t\tconst points = graph.connectorsGroup.selectAll('.connector').data(Array.from(connectors), DescriptorModelFactory.containerIdentity);\n\n\t\tpoints.enter().append('path');\n\n\t\tpoints.attr({\n\t\t\t'data-uid': d => d.uid,\n\t\t\t'data-key': d => d.key,\n\t\t\t'data-cp-number': d => d.meta.cpNumber,\n\t\t\t'class': d => {\n\t\t\t\treturn ClassNames('connector', d.type, d.parent.type, {\n\t\t\t\t\t'-is-connected': d.meta.hasConnection,\n\t\t\t\t\t'-is-not-connected': !d.meta.hasConnection\n\t\t\t\t});\n\t\t\t},\n\t\t\t'data-tip': d => {\n\t\t\t\tconst info = d.displayData;\n\t\t\t\treturn info.name + '<br />' + info.type;\n\t\t\t},\n\t\t\t'data-offset': d => {\n\t\t\t\tif (d.type === 'internal-connection-point') {\n\t\t\t\t\treturn '{\"top\": -7, \"left\": -9}';\n\t\t\t\t}\n\t\t\t\treturn '{\"top\": -5, \"left\": -5}';\n\t\t\t},\n\t\t\ttransform: d => {\n\t\t\t\tconst point = d.position.centerPoint();\n\t\t\t\treturn 'translate(' + point.x + ', ' + point.y + ')';\n\t\t\t},\n\t\t\td: d => {\n\t\t\t\tif (d.type === 'connection-point') {\n\t\t\t\t\treturn connectionPointSymbol();\n\t\t\t\t}\n\t\t\t\tif (/top/.test(d.location)) {\n\t\t\t\t\treturn internalConnectionPointSymbolTop();\n\t\t\t\t}\n\t\t\t\treturn internalConnectionPointSymbolBottom();\n\t\t\t}\n\t\t});\n\n\t\tpoints.exit().remove();\n\n\t\tconst test = new GraphConnectionPointNumber(graph);\n\t\ttest.addContainers(Array.from(connectors));\n\t\ttest.render();\n\t}\n\n\tfunction drawRelationPointsAndPaths (graph, relationEdges) {\n\n\t\tconst paths = graph.paths.selectAll('.relation').data(relationEdges, DescriptorModelFactory.containerIdentity);\n\n\t\tpaths.enter().append('path')\n\t\t\t.attr({\n\t\t\t\t'class': d => {\n\t\t\t\t\treturn ClassNames('relation', d.type, {'-is-selected': d.meta && SelectionManager.isSelected(d) /*d.meta && d.meta.selected*/});\n\t\t\t\t},\n\t\t\t\tstroke: 'red',\n\t\t\t\tfill: 'transparent',\n\t\t\t\t'marker-start': 'url(#relation-marker-end)',\n\t\t\t\t'marker-end': 'url(#relation-marker-end)'\n\t\t\t});\n\n\t\tpaths.attr({\n\t\t\td: d => {\n\t\t\t\tconst src = d;\n\t\t\t\tconst dst = d.parent;\n\t\t\t\tconst layout = containerLayoutInfo[src.type];\n\t\t\t\treturn layout.renderRelationPath(src, dst, containerLayoutInfo);\n\t\t\t}\n\t\t});\n\n\t\tpaths.exit().remove();\n\n\t}\n\n\tfunction updateContainerPosition(graph, container, layout) {\n\t\t// use the provided layout to generate the position coordinates\n\t\tconst position = container.position;\n\t\tposition.top = layout.top(container, containerLayoutInfo) + marginTop;\n\t\tposition.left = layout.left(container, containerLayoutInfo) + marginLeft;\n\t\tposition.width = layout.width;\n\t\tposition.height = layout.height;\n\t\t// cache the default layout position which may be needed by the layout\n\t\t// of children elements that have not been positioned by the user\n\t\tcontainer.meta.defaultLayoutPosition = position.value();\n\t\tconst savedContainerPosition = graph.lookupSavedContainerPosition(container);\n\t\tif (savedContainerPosition) {\n\t\t\t// set the container position with the saved position coordinates\n\t\t\tcontainer.setPosition(savedContainerPosition);\n\t\t}\n\t\tif (container.meta.dropCoordinates) {\n\t\t\tconst rect = graph.svg.node().getBoundingClientRect();\n\t\t\tconst top = container.meta.dropCoordinates.clientY - (position.height / 2) - rect.top;\n\t\t\tconst left = container.meta.dropCoordinates.clientX - (position.width / 2) - rect.left;\n\t\t\tcontainer.position.move(Math.max(props.padding, left), Math.max(props.padding, top));\n\t\t\tgraph.saveContainerPosition(container);\n\t\t\tdelete container.meta.dropCoordinates;\n\t\t}\n\t}\n\n\treturn {\n\n\t\taddContainers(containers) {\n\n\t\t\tconst layout = this;\n\n\t\t\t//containers = containers.filter(d => containerLayouts[d.type]);\n\n\t\t\tconst graphSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\n\t\t\tcontainers.forEach(container => {\n\t\t\t\tcontainerList.push(container);\n\t\t\t});\n\n\t\t\tcontainers.forEach(container => {\n\t\t\t\tconst layout = containerLayoutInfo[container.type];\n\t\t\t\tif (!layout) {\n\t\t\t\t\treturn\n\t\t\t\t\t//throw new ReferenceError('unknown container type: ' + container.type);\n\t\t\t\t}\n\t\t\t\tupdateContainerPosition(graph, container, layout);\n\t\t\t\tlayout.list.push(container);\n\t\t\t\tgraphSize.width = Math.max(graphSize.width, container.position.right, props.width);\n\t\t\t\tgraphSize.height = Math.max(graphSize.height, container.position.bottom, props.height);\n\t\t\t});\n\n\t\t\tgraph.svg.attr({\n\t\t\t\twidth: graphSize.width + props.width,\n\t\t\t\theight: graphSize.height + props.height\n\t\t\t});\n\n\t\t\tconst uiTransientState = {\n\t\t\t\tisDragging: false,\n\t\t\t\tdragStartInfo: [0, 0]\n\t\t\t};\n\n\t\t\t// todo extract drag behavior into class DescriptorGraphDrag\n\n\t\t\tconst drag = this.drag = d3.behavior.drag()\n\t\t\t\t.origin(function(d) { return d; })\n\t\t\t\t.on('drag.graph', function (d) {\n\t\t\t\t\tuiTransientState.isDragging = true;\n\t\t\t\t\tconst mouse = d3.mouse(graph.g.node());\n\t\t\t\t\tconst offset = uiTransientState.dragStartInfo;\n\t\t\t\t\tconst newTopEdge = snapTo(mouse[1] - offset[1]);\n\t\t\t\t\tconst newLeftEdge = snapTo(mouse[0] - offset[0]);\n\t\t\t\t\tif (d.position.left === newLeftEdge && d.position.top === newTopEdge) {\n\t\t\t\t\t\t// do not redraw since we are not moving the container\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\td.position.move(newLeftEdge, newTopEdge);\n\t\t\t\t\tgraph.saveContainerPosition(d);\n\t\t\t\t\td3.select(this).attr({\n\t\t\t\t\t\ttransform: () => {\n\t\t\t\t\t\t\tconst x = d.position.left;\n\t\t\t\t\t\t\tconst y = d.position.top;\n\t\t\t\t\t\t\treturn 'translate(' + x + ', ' + y + ')';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tconst connectionPointRefs = getConnectionPointEdges();\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tdrawConnectionPointsAndPaths(graph, connectionPointRefs);\n\t\t\t\t\t\tlayout.renderers.forEach(d => d.render());\n\t\t\t\t\t});\n\t\t\t\t}).on('dragend.graph', () => {\n\t\t\t\t\t// d3 fires a drag-end event on mouse up, even if just clicking\n\t\t\t\t\tif (uiTransientState.isDragging) {\n\t\t\t\t\t\tuiTransientState.isDragging = false;\n\t\t\t\t\t\tCatalogItemsActions.catalogItemMetaDataChanged(graph.containers[0].model);\n\t\t\t\t\t\td3.select(this).on('.graph', null);\n\t\t\t\t\t}\n\t\t\t\t}).on('dragstart.graph', function (d) {\n\t\t\t\t\t// the x, y offset of the mouse from the container's left, top\n\t\t\t\t\tuiTransientState.dragStartInfo = d3.mouse(this);\n\t\t\t\t});\n\n\t\t\tthis.renderers = [GraphVirtualLink, GraphNetworkService, GraphForwardingGraph, GraphVirtualNetworkFunction, GraphConstituentVnfd, GraphVirtualDeploymentUnit, GraphRecordServicePath].map(layout => {\n\t\t\t\tconst container = new layout(graph, props);\n\t\t\t\tconst layoutInfo = containerLayoutInfo[container.classType && container.classType.type];\n\t\t\t\tif (layoutInfo) {\n\t\t\t\t\tcontainer.props.descriptorWidth = layoutInfo.width;\n\t\t\t\t\tcontainer.props.descriptorHeight = layoutInfo.height;\n\t\t\t\t}\n\t\t\t\tcontainer.dragHandler = drag;\n\t\t\t\tcontainer.addContainers(containerList);\n\t\t\t\treturn container;\n\t\t\t});\n\n\t\t},\n\n\t\trender(graph, updateCallback = () => {}) {\n\t\t\tconst connectionPointRefs = getConnectionPointEdges();\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tdrawConnectionPointsAndPaths(graph, connectionPointRefs);\n\t\t\t\tthis.renderers.forEach(d => d.render());\n\t\t\t\tupdateCallback();\n\t\t\t});\n\t\t}\n\n\t};\n\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/layouts/RelationsAndNetworksLayout.js\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\n\nimport d3 from 'd3'\nimport ClassNames from 'classnames'\nimport ColorGroups from '../ColorGroups'\nimport SelectionManager from '../SelectionManager.js'\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport DescriptorGraphSelection from './DescriptorGraphSelection'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\nimport GraphDescriptorModel from './GraphDescriptorModel'\n\nimport '../../styles/GraphVirtualLink.scss'\n\nconst defaults = {\n\t'type': DescriptorModelFactory.VirtualLink.type,\n\t'className': DescriptorModelFactory.VirtualLink.className,\n\tselector: [DescriptorModelFactory.VirtualLink.className, DescriptorModelFactory.VirtualLink.type, 'descriptor']\n};\n\nexport default class GraphVirtualLink extends GraphDescriptorModel {\n\n\tconstructor(graph, props) {\n\t\tsuper(graph, DescriptorModelFactory.VirtualLink, props);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphVirtualLink.js\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\n\nimport d3 from 'd3'\nimport ColorGroups from '../ColorGroups'\nimport PathBuilder from '../graph/PathBuilder'\nimport SelectionManager from '../SelectionManager.js'\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport DescriptorGraphSelection from './DescriptorGraphSelection'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\n\nimport '../../styles/GraphDescriptorModel.scss'\n\nconst iconTitles = {\n\t'vnffgd': 'fg',\n\t'constituent-vnfd': 'vnf',\n\t'nsd': 'ns',\n\t'vnfd': 'vnf',\n\t'vdud': 'vdu'\n};\n\nexport default class GraphDescriptorModel {\n\n\tconstructor(graph, classType, props = {}) {\n\t\tthis.props = {};\n\t\tthis.graph = graph;\n\t\tthis.classType = classType;\n\t\tthis.containers = [];\n\t\tthis._dragHandler = () => {};\n\t\tif (!classType) {\n\t\t\tthrow TypeError('Expect class type to be provided. Did you forget to pass in a class type, for example, DescriptorModelFactory.VirtualNetworkFunction?');\n\t\t}\n\t\tconst defaults = {type: classType.type, className: classType.className, selector: [classType.className, classType.type, 'descriptor']};\n\t\tthis.props = Object.assign(this.props, defaults, {descriptorBorderRadius: 20, descriptorWidth: 250, descriptorHeight: 55}, props);\n\t\tGraphDescriptorModel.buildRef(classType.type, this.graph.defs);\n\t}\n\n\taddContainers(containers) {\n\t\tthis.containers = containers.filter(d => d instanceof this.classType);\n\t}\n\n\tget dragHandler() {\n\t\treturn this._dragHandler;\n\t}\n\n\tset dragHandler(drag) {\n\t\tthis._dragHandler = drag;\n\t}\n\n\trender() {\n\n\t\tconst g = this.graph.containersGroup;\n\n\t\tconst descriptor = g.selectAll('.' + this.props.selector.join('.')).data(this.containers, DescriptorModelFactory.containerIdentity);\n\n\t\tconst path = new PathBuilder();\n\n\t\tconst descriptorPath = PathBuilder.descriptorPath(this.props.descriptorBorderRadius, this.props.descriptorHeight, this.props.descriptorWidth).toString();\n\n\t\t// ENTER\n\t\tconst box = descriptor.enter().append('g')\n\t\t\t.attr({\n\t\t\t\t'data-uid': d => d.uid,\n\t\t\t\t'data-key': d => d.key,\n\t\t\t\t'class': d => {\n\t\t\t\t\treturn this.props.selector.join(' ');\n\t\t\t\t}\n\t\t\t}).on('cut', (container) => {\n\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (container && container.remove) {\n\t\t\t\t\tsuccess = container.remove();\n\t\t\t\t}\n\n\t\t\t\tif (success) {\n\t\t\t\t\tCatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());\n\t\t\t\t} else {\n\t\t\t\t\td3.event.preventDefault();\n\t\t\t\t}\n\n\t\t\t\td3.event.stopPropagation();\n\n\t\t\t});\n\n\t\tbox.append('path')\n\t\t\t.attr({\n\t\t\t\tclass: d => d.type + '-descriptor-model-background',\n\t\t\t\td: descriptorPath,\n\t\t\t\tfill: d => `url(#${d.type}-descriptor-model-badge-fill)`,\n\t\t\t\tstroke: 'transparent',\n\t\t\t\t'stroke-width': '2px'\n\t\t\t});\n\n\t\tbox.append('path')\n\t\t\t.attr({\n\t\t\t\tclass: d => d.type + '-descriptor-model-border',\n\t\t\t\td: descriptorPath,\n\t\t\t\tfill: 'transparent',\n\t\t\t\tstroke: d => ColorGroups.getColorPairForType(d.type).secondary,\n\t\t\t\t'stroke-width': 1.25\n\t\t\t}).style({opacity: 0.75});\n\n\t\tbox.append('path').attr({\n\t\t\tclass: d => d.type + '-icon icon',\n\t\t\td: d => d.icon.d,\n\t\t\ttransform: d => `translate(${d.icon.translate ? d.icon.translate : '-4, 2'}) rotate(0) scale(${24 / d.icon.width}, ${24 / d.icon.width})`,\n\t\t\tfill: 'white',\n\t\t\tstroke: 'white'\n\t\t});\n\n\t\tbox.append('text')\n\t\t\t.attr({\n\t\t\t\tclass:d => d.type + '-type type',\n\t\t\t\t'font-weight': 100,\n\t\t\t\t'font-size': '12px',\n\t\t\t\t'text-anchor': 'middle',\n\t\t\t\t'text-transform': 'uppercase',\n\t\t\t\tfill: 'white',\n\t\t\t\tstroke: 'white',\n\t\t\t\tx: 13,\n\t\t\t\ty: 49\n\t\t\t}).text(d => iconTitles[d.type] || d.type).style({opacity: 1});\n\n\t\tbox.append('text')\n\t\t\t.attr({\n\t\t\t\tclass: d => d.type + '-title title',\n\t\t\t\t'font-weight': 100,\n\t\t\t\t'font-size': '12px',\n\t\t\t\t'text-anchor': 'middle',\n\t\t\t\tx: (d) => {\n\t\t\t\t\tconst left = 0;\n\t\t\t\t\tconst widthOffset = d.position.width / 2;\n\t\t\t\t\treturn left + widthOffset;\n\t\t\t\t},\n\t\t\t\ty: (d) => {\n\t\t\t\t\tconst top = 0;\n\t\t\t\t\tconst height = d.position.height;\n\t\t\t\t\tconst heightOffset = height / 2;\n\t\t\t\t\tconst textHeightOffset = 12 / 2;\n\t\t\t\t\treturn top + heightOffset + textHeightOffset;\n\t\t\t\t}\n\t\t\t});\n\n\t\t// ENTER & UPDATE\n\t\tdescriptor.attr({\n\t\t\ttransform: d => {\n\t\t\t\tconst x = d.position.left;\n\t\t\t\tconst y = d.position.top;\n\t\t\t\treturn 'translate(' + x + ', ' + y + ')';\n\t\t\t}\n\t\t}).call(this.dragHandler);\n\n\t\tdescriptor.select('text.title')\n\t\t\t.text(d => {\n\t\t\t\treturn d.title;\n\t\t\t});\n\n\t\t// EXIT\n\t\tdescriptor.exit()\n\t\t\t.remove();\n\n\t}\n\n\tstatic buildRef(type, defs) {\n\t\tif (defs.selectAll('#' + type + '-descriptor-model-badge-fill')[0].length === 0) {\n\t\t\tvar vld = defs.append('pattern').attr({\n\t\t\t\tid: type + '-descriptor-model-badge-fill',\n\t\t\t\t//patternUnits: 'userSpaceOnUse',\n\t\t\t\tpatternContentUnits: 'objectBoundingBox',\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\tviewBox: '0 0 1 1',\n\t\t\t\tpreserveAspectRatio: 'none'\n\t\t\t});\n\t\t\tvld.append('rect').attr({\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\tfill: 'white'//ensure transparent layers keep their color\n\t\t\t});\n\t\t\tvld.append('rect').attr({\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\tfill: ColorGroups.getColorPairForType(type).secondary\n\t\t\t}).style({opacity: 1});\n\t\t\tvld.append('rect').attr({\n\t\t\t\ty: 0,\n\t\t\t\tx: 0.22,\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\tfill: ColorGroups.common.background\n\t\t\t});\n\t\t}\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphDescriptorModel.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphDescriptorModel.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphDescriptorModel.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphDescriptorModel.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/GraphDescriptorModel.scss\n ** module id = 478\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/GraphDescriptorModel.scss\n ** module id = 479\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphVirtualLink.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphVirtualLink.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphVirtualLink.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/GraphVirtualLink.scss\n ** module id = 480\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@charset \\\"UTF-8\\\";\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Thin-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-ThinItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Medium-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-MediumItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Black-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BlackItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\nhtml, body {\\n  background: #f1f1f1;\\n  cursor: auto;\\n  font-family: Roboto, Helvetica, Arial, sans-serif;\\n  overflow: hidden;\\n}\\n\\n::-webkit-scrollbar {\\n  display: none;\\n}\\n\\nhtml {\\n  -webkit-box-sizing: border-box;\\n  -moz-box-sizing: border-box;\\n  box-sizing: border-box;\\n}\\n\\n* {\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n  border-collapse: collapse;\\n}\\n\\n*, *:before, *:after {\\n  -webkit-box-sizing: inherit;\\n  -moz-box-sizing: inherit;\\n  box-sizing: inherit;\\n}\\n\\nh1 {\\n  margin: 0;\\n  padding: 3px 6px;\\n  color: #323232;\\n  font-size: 0.75em;\\n  font-weight: normal;\\n  text-align: center;\\n  font-variant-caps: all-small-caps;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n}\\n\\nbutton,\\ninput[type=\\\"image\\\"] {\\n  /*font-variant: small-caps;\\n\\ttext-transform: lowercase;\\n\\ttext-align: center;\\n\\tmargin: 4px 0;\\n\\tborder-radius: 0;\\n\\tborder-collapse: collapse;\\n\\tpadding: 2px 24px;\\n\\toutline: none;\\n\\tbackground-color: transparent;*/\\n  box-shadow: 2px 2px rgba(0, 0, 0, 0.15);\\n  color: #000000;\\n  display: inline-block;\\n  font-size: 12px;\\n  padding: 8px 34px;\\n  text-decoration: none;\\n  text-transform: uppercase;\\n}\\n\\nbutton:hover,\\ninput[type=\\\"image\\\"]:hover {\\n  background-color: #7E9BC1;\\n  color: #ffffff;\\n}\\n\\nbutton:active,\\nbutton:visited,\\ninput[type=\\\"image\\\"]:active, input[type=\\\"image\\\"]:visited {\\n  background-color: #4C5E74;\\n  color: #ffffff;\\n}\\n\\nbutton.-selected,\\ninput[type=\\\"image\\\"].-selected {\\n  background-color: #9fc4f4;\\n}\\n\\ninput[type=\\\"image\\\"] {\\n  width: 28px;\\n  height: 28px;\\n  margin-right: 12px;\\n  border: 0;\\n  border-radius: 4px;\\n  padding: 4px;\\n}\\n\\n.btn-group {\\n  white-space: nowrap;\\n}\\n\\n.btn-group button {\\n  border-right: 1px solid rgba(169, 169, 169, 0.5);\\n}\\n\\n.btn-group button:first-of-type {\\n  border-top-left-radius: 2px;\\n  border-bottom-left-radius: 2px;\\n}\\n\\n.btn-group button:last-of-type {\\n  border-right: none;\\n  border-top-right-radius: 2px;\\n  border-bottom-right-radius: 2px;\\n}\\n\\n.panel {\\n  overflow: hidden;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  background-color: #e5e5e5;\\n}\\n\\n.panel > div {\\n  min-width: 200px;\\n}\\n\\n.panel-header {\\n  /*position: absolute;\\n\\ttop: 0;\\n\\tleft: 0;\\n\\tright: 0;\\n\\theight: 50px;\\n\\tpadding: 8px;\\n\\tbackground-color: $panel-bg-color-contrast;\\n\\tborder-bottom: 1px solid $panel-border-color-light;\\n\\twhite-space: nowrap;*/\\n}\\n\\n.panel-header h1 {\\n  padding: 16px;\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.panel-body {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  top: 111px;\\n  bottom: 0px;\\n  left: 0;\\n  right: 0;\\n}\\n\\n.panel-footer {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 40px;\\n  padding: 0 12px;\\n  background-color: #cbd1d1;\\n  border-top: 1px solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n}\\n\\n.welcome-message {\\n  margin: 20px;\\n  color: #06173c;\\n  font-size: x-large;\\n  font-weight: 200;\\n}\\n\\n.welcome-message .Button {\\n  display: inline-block;\\n}\\n\\n/* react-tooltip overrides */\\n.__react_component_tooltip {\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !important;\\n}\\n\\n/* simple css-only drop-down menu */\\n.menu {\\n  display: inline-flex;\\n  position: relative;\\n  z-index: 2;\\n}\\n\\n.menu > .Button:after {\\n  content: \\\"\\\\2C7\\\";\\n  position: absolute;\\n  right: 4px;\\n  bottom: -13px;\\n  font-size: 20px;\\n}\\n\\n.menu .sub-menu {\\n  display: none;\\n  position: absolute;\\n  top: 36px;\\n  left: -4px;\\n  padding: 4px;\\n  background-color: #f1f1f1;\\n  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\\n  border-radius: 3px;\\n}\\n\\n.menu .sub-menu .Button {\\n  display: block;\\n  text-align: left;\\n}\\n\\n.menu .sub-menu:hover {\\n  display: block;\\n}\\n\\n.menu > .Button:hover .sub-menu {\\n  display: block;\\n}\\n\\n.menu:hover .sub-menu {\\n  display: block;\\n}\\n\\n.descriptor text.badge, .DescriptorGraph .VirtualLink text.badge {\\n  font-weight: 100;\\n  font-size: 12px;\\n  text-anchor: middle;\\n  fill: white;\\n  /* font color */\\n  stroke: white !important;\\n  /* font color */\\n}\\n\\ninput:focus {\\n  color: white;\\n  background: #000 !important;\\n}\\n\\n.hint {\\n  margin: 5px;\\n}\\n\\n.DescriptorGraph {\\n  /* colors are defined in ColorGroups and assigned in the graph code. */\\n}\\n\\n.DescriptorGraph .VirtualLink path.icon {\\n  pointer-events: none;\\n}\\n\\n.DescriptorGraph .VirtualLink.-is-selected circle.badge,\\n.DescriptorGraph .VirtualLink.-selected circle.badge {\\n  stroke: red;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.-is-drag-over circle.badge {\\n  stroke: red;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/GraphVirtualLink.scss\n ** module id = 481\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Thin-webfont.woff\n ** module id = 482\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-ThinItalic-webfont.woff\n ** module id = 483\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Light-webfont.woff\n ** module id = 484\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-LightItalic-webfont.woff\n ** module id = 485\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Regular-webfont.woff\n ** module id = 486\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,d09GRgABAAAAAHGYABMAAAAA02wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABqAAAABwAAAAcX89bT0dERUYAAAHEAAAAKQAAACwC9QHUR1BPUwAAAfAAAAaRAAAOvJoIrnNHU1VCAAAIhAAAAEwAAABiIPEmr09TLzIAAAjQAAAAVwAAAGC4BvwPY21hcAAACSgAAAGIAAAB4tENdWRjdnQgAAAKsAAAAGAAAABgE9YXcGZwZ20AAAsQAAABsQAAAmVTtC+nZ2FzcAAADMQAAAAIAAAACAAAABBnbHlmAAAMzAAAW7EAALBUhvMLl2hlYWQAAGiAAAAAMgAAADYDI5k8aGhlYQAAaLQAAAAiAAAAJA82BUxobXR4AABo2AAAAnsAAAOsjEJSL2xvY2EAAGtUAAABzgAAAdhLEnUabWF4cAAAbSQAAAAgAAAAIAIIAYluYW1lAABtRAAAAZkAAAMjc5cgbnBvc3QAAG7gAAAB9gAAAu57ZTG1cHJlcAAAcNgAAAC3AAABQ4bH8f53ZWJmAABxkAAAAAYAAAAG9tJSewAAAAEAAAAAzD2izwAAAADE8BEuAAAAAM6hp1F42mNgZGBg4ANiFQYQYGJgZmBkeAbEz4GQieEFwysgmwUswwAAU2MEygAAAHjapZd5bJRVFMXPN9PSodDpzLSOgBuKbAq44FJBajSyu0SBiiAaTEyMC1FjSFyif1iwIkIEUVGUKorK0mikLAJSoHVBVEDRIhYCbkM7iLjFP0yvv+9NnU5ZisXv5Hzz5r7t3vOWuSNPUq7OVbECVw65arTCd028f5K6KAu7zOTXZ5a9O2+7b5JCfskxSwE+A8oNVskLDnFtL9Jk8LBm6Xkt1DK9p2pvqjddy7xZ3jxvubfZq/f+DoQDwwLXBG4PvBdIBP4MRoJx2IcezVhIzxSWNSMQpl0kEHZz+PA0Xh2UrQEq1EDFNEhxlcMa6KnAuiqobrZRY+2AxttuvuXZj7rcftdELJ6ewBbQCPuZ2nqUiFhcMdjdatSv8S8VMe5g26Wh1qBhcDgcCUfBMbCE0W6k5zhLaAJ8jH6lcAqcCh+HZXABY7wGX4cL4RvwTbiIMRbDJXAprICVcDlcAVfCVXANc6yF78N1sIq5NsBq6r7B3zq42/yYx9t6936NuMYqTITz1U5Ftl0D7HsNtKQGWZ3KYQ3MpuZtavZj3YJ1C9YtyiGuSsb4UJMaV+oR68UoV+stm6HV9gqrnIcqlytKq72aqAJnycfSEUsDljDIpc5vF7bPqYmhcT21taxEveszySoY+VNGLmfk9YxcpV32hfP9Bzzux5pcAufBl+DLcD4spC7CmkeavIixNgnWJsHaJFibBOuScDMs4nMxXAKXwgqnV0K19N0Bd8Jv3VhDUWUYHA5HwjFwEVwMl8ClsAJWw6BGEOtYdWXnRfFlFLZKuByugCvhKujRLg99I1bKjipllUpZpVJWqdRFlyS6JNEliS5JdEmi83tdRG0HlCxQd/VUL/XWWTqHndlfF+hCaovY6wPZ58W6jBmuVQm+jMOXCbpFj6lUUzRVj6tM0/SkpuspzdBszdGzeo4zNZezUaUNnI5aFNhJ9IHcHv6pzZkWqtXpOoWTPsfK7DOrsaRtZGe04bESHedjZenS7/APe9QO2Fu22l6l/BlaRO1jNJz5H0b6ASbgx4fYfztmz+/a4G/DYXPWw+1N3/eka16wett3WO/9KfIUpm0HuEdaf2JH8pYTnXqilKK+J375kPnq9T8e+9H2uQj3ZNj2cY7/LS9Il6rSpcns3ubW6xr32ya7zu61qH1pDx1jvsms+W9HXLH81LraDv9L4xrb42tmReme79hMe8lmw+moEcEUoU/EXrGVVm2f0OIRe5h3D9e6k0XsF3vXlSttm33J57aW89r39kcL305z750Zlu2221emSZ1w5hq36DnFvasP1Ta1l+yn5t7W4MaKujXdmm65LaPXq7bC1lkt/IB9EOX+jNE+Zjs4s3sz2vXl/pFttnLiTO3CvKb5GlJzN3vbtHOOtiZrW6k7eLyninV2fe3XI43ZUvk27dhfW6lr9R6wX457zmRrCqXGPXx0d49E0ndC8hhnfsoRzsNBd1aOugb2tXvPOZrPrfnduk5t18qKrY9daf1hT3ZUDqYcfh9zbKTdZ1NtFi3yrSMn+0F3vm/l+1a7I/NeST2N7Az7CC5N76Of/lWz2avUL4C9bk/bWu7htZzwfWk9mz5tE1ztn43Gu933J9qiUPMd2ML6QCsK1KVLOw49C2RrF7MXImQAMeDx698dWw8QJA/oya90L5BNPtCbDKGP+qJePxAiOzhH7ckQziWXP0/nY+8PsskXLiCTKAIddQkIkTkM4A4YCMK6FOSTRwxizmIQ1WAQ0xBQoKGgUMPBCboKxHWdruc9Cpyo0aCAzKNEncg9xqmzbgJdyEEmUL4ZnEQuUob/00AWmcgMfJ7Jf4IcspHZ+PYMyCEvmUt5nubjWzmIaIHexIdFoFCLVcHsft4fV6VWMW8V6Kz1oIAsZgPlGhDRN8BTHfC0G3hOzXbAQ4EOvH1l48QYpY+vb7xJX1/ZkM4GIadmF6ddiEzrQt4Xg5Ocgu2dgrlOwQ5OwY5OwROdgnlOwU5OwSDKDSfmkSDLqZbtVGvnVMvWGJClG0CObgRhp2C+U/Bkp2C+UzCie0DnDB1DTq+QXgQhp1quUy3PqRZEswpG9vXKdnq10xqtY3xftXynV742gpCqQZbTLk9f6Wtm8fNBz+kYd3lhSs24UzPO/J2cmspQM+B0DKJib8bqw15rj07F2AajQGe3d052e+cUVBitU91+OcNF241Yb9aZLraeRDaX3TyPSAa5SK5wkQwjjlW62uWro5yvJXhZh26+TxP+ActuZz4AAAB42mNgZGBg4GIwYLBjYHJx8wlh4MtJLMljkGJgAYoz/P/PAJJHZjPmZKYnMnCAWGDMApZlBIowMghBaRaG5wxMDL5AFiODFwBzeQrfeNpjYGZ+xjiBgZWBhXUWqzEDA6M8hGa+yJDGxMDAAMIQ8ICB6X8Ag0I0kKkA4rvn56czMDLw/mZhS/uXxsDAUcwUrMDAON+fkYGBxYp1A1gdEwCyig69AHjaY2BgYGaAYBkGRgYQuAPkMYL5LAwHgLQOgwKQxQNk8TLUMfxnDGasYDrGdEeBS0FEQUpBTkFJQU1BX8FKIV5hjaLSA4bfLP//g83hBepbwBgEVc2gIKAgoSADVW0JV80IVM38/+v/J/8P/y/87/uP4e/rByceHH5w4MH+B3se7Hyw8cGKBy0PLO4fVnjG+gzqQqIBIxvEa2A2E5BgQlfAwMDCysbOwcnFzcPLxy8gKCQsIiomLiEpJS0jKyevoKikrKKqpq6hqaWto6unb2BoZGxiamZuYWllbWNrZ+/g6OTs4urm7uHp5e3j6+cfEBgUHBIaFh4RGRUdExsXn5CYxNDe0dUzZeb8JYuXLl+2YtWa1WvXbVi/cdOWbVu379yxd8++/QzFqWlZ9yoXFeY8Lc9m6JzNUMLAkFEBdl1uLcPK3U0p+SB2Xt395Oa2GYePXLt++86Nm7sYDh1lePLw0fMXDFW37jK09rb0dU+YOKl/2nSGqXPnzWE4drwIqKkaiAGizolRAAAEOgWvAJsApQCSAKAAhQC8AMUAyQDBANwArQCzALkAuwC9AMEAxQDQANgApgCYAIkAxwCdAL8A1ACjAJAAjgCqAMMAywCoALcAlgDOAIsAWABKAGYAUwBWALUARAUReNpdUbtOW0EQ3Q0PA4HE2CA52hSzmZDGe6EFCcTVjWJkO4XlCGk3cpGLcQEfQIFEDdqvGaChpEibBiEXSHxCPiESM2uIojQ7O7NzzpkzS8qRqnfpa89T5ySQwt0GzTb9Tki1swD3pOvrjYy0gwdabGb0ynX7/gsGm9GUO2oA5T1vKQ8ZTTuBWrSn/tH8Cob7/B/zOxi0NNP01DoJ6SEE5ptxS4PvGc26yw/6gtXhYjAwpJim4i4/plL+tzTnasuwtZHRvIMzEfnJNEBTa20Emv7UIdXzcRRLkMumsTaYmLL+JBPBhcl0VVO1zPjawV2ys+hggyrNgQfYw1Z5DB4ODyYU0rckyiwNEfZiq8QIEZMcCjnl3Mn+pED5SBLGvElKO+OGtQbGkdfAoDZPs/88m01tbx3C+FkcwXe/GUs6+MiG2hgRYjtiKYAJREJGVfmGGs+9LAbkUvvPQJSA5fGPf50ItO7YRDyXtXUOMVYIen7b3PLLirtWuc6LQndvqmqo0inN+17OvscDnh4Lw0FjwZvP+/5Kgfo8LK40aA4EQ3o3ev+iteqIq7wXPrIn07+xWgAAAAABAAH//wAPeNrEfQlgE9XW/9zZsu9N0qRrmrbpHpp0IWUp+76pgMgiqIAgq+ICKriAAi4gKKIgior7wkxSERC1oCKI+hQVl+f6fD6tPH0qDxWhw/+cO5M0hSLP9/n9P7TTySTN3HvOuWe/v2FYpg/DsJOFUQzH6JgqmTDhrnEdX/VdRBaFj7vGORZOGZnDywJejuvE8LGucYLXo46AoyjgCPRh85VCcpcyTRj12xN9+DcY+ErmDDjUCBL93nlMHK6VS1xUJsYWiY3EBRZeilEi6cMSOSCzphaJyT/gkDk4IXaJx3MdnLN2WSDlsmhqkQ2kXKrzb+/+4qHJjLvcyEuMPcEzggu+1p7QcaKrnJV5XVWV1MNPmE7V0fqojnNFuTNKXyw976VdL73+OvmU23+sCsf2Im9n3xMzGYExMbcwkiksMdEmvZHR8+VxljNEIhEimcMSe0DmPC3w9bIexmDwtMgWdQyNnQ5/gGOwwvgk0gyfkPjm7Y1Vh/fgVUlvl3TNksEuGZuZBOF1xir4R1JnOECZYx1OSYhJeockxiSDUzLFYNCuehixLkqPL4Yq11VMfi1Usb5iCm//gWQqP/32K7HDkdK3N8PwfwH6ZjF5TD8m7kf6uqNxHRLWFG1iiF9nKZcd2dGozAgtsssbiTQJPL1oy4WLAlw0WHCm+WE5QMrp3aOuYH0Abh7FH12Q/gRd+INv9c4+dOM/s4m48fb7voKfpuy/3LA3+8sNd2z4asPtG/Z+dcNXZN0tZPwKslGZhD8rlE23KFPJOvyB6wxhph/vxBeIG5hyZi0TL8URF0dlXmyJl/LG8kSP0pChPG7HCbiish8u2/142e4wlBOpAph0QCZUPuQS4EcIWBOyyw44dcKp0y574dQDklKJ75Y4nAkTn1ta6I1JDkfCbswvxlOnM653+WOxmOR1SIEYI/t5+CBj8gTgXSBBVPREI3X1dcWhKlLfnTSSqC6X6IJ1xcECUSd6vPDCSmwkWF9Fpu/0z5t28XqnbeLC+MasrL/cG1xXePuyvGbPyKlTrrfbxy1tuisr55Mnc9flrn2SPLVx4cIZ4xdGur3++BP7Mj75zP/DK7c+uHD65Mvqer3yWHy3s7k540Pgq8D88/hBwSu8wlgYB3C2kunCfM/Ey4FWcrWuJc4DdeRsXUtT58JyHljZGU7dJnrq1rUQqWtY7qatkwd/+lSVUQZlVHZmHpHymrd333VoHhXSTLvka5b1cFUHVx/76Vd6Nd8uBZrlKrjaBa4+f2gsvVpjl2qb5RK4GmpmetgZotM7M315+YFQSVVNbZeqE/6R03+ELlK5c7XDKVsdsZic7YYzuy2GLACyRyMeG7GSYEGxi3iJi/KkkahMIO3er2/33j9tWVsXz7/GZ8vecv2C63pyV044dqPRXtOv2/k2m62md+MFVjI49ZFnr1tw3aPt3uQHD136sLRw6NJNm4/9jb+k99EV3CfDz582cOjwyTMGHLtm2NKHpKuHLdu0eeHwC6YPHDZs8kUDgGWg4eqOH+RvAp7lg2R3ZgaoqzGei0wr5FriBmRaHQfsiYWljAOy29IiN4CMujNg0iZfDKSw0A/qICsm1TmaOHtmSVgVxu6kvkqbLpU6vBC1Ep03GEqbfD2KJNDIC5+sp3Soy7j3ji5ha9b+B1ducjnmz519uFMv65Pei0bd8nWXkc9NfPndz1zTr2pc1kM5GprQ/2+G/NDyLhGjcVD/fpPJskXyhAvuOXOzvHXR1OVDhymzet49avlHY/5xfkO3b565bEV1FZGz+lzNPlU3t/f44jH1PcZdAuv6JT6PPEX16RmMxISbWCNj4EEvg3IRk2pU1mm6M3z4jZN0JyMTHuSGHtPVIyilLIKK/KXS0LrC6XAbww+fKf9g4J53KtVcsXgBrBLGVe9k6vOIyHA61unVhYrZO9meZNGzonOlcqSe7TJnTq245l22n4GsY/2TyLyZSonysEVZqzTMn0kmsJXAQ3L8JqWazREn4/dxdfiVbKje63HCVzK60OW3EmOM7Xz5hfXi6ve6s72U67aIyoaLyBdkvIVMJm/Nm0nObd2vzDcoU1u/Pp/g+DayE7n7QT9bmUIGzCgDKswWlrgDMg+0sAP3ec7hjAt6I+giqnu9oHOLvIJLZyIh18bhvzZsGEYKbMpHV95x0QezD/LhdXPIaGXT7HvOUX6aRPKUlgnEife5hFnN1/FbwJLdgLSX9SZQ7kTfIrNCJBJnCGpQxmAol4yROGHwFeHgFa+aOOMB2QAq1WCXORySKWXikmZWMtoTrJEDK2uwJwQD7ypP6PGI1014nUuwgt6krWk6ETQgAV0AjMYlheTiUTtHkdmFyu3jd45nJ8TJI8o5caWW7KM036QoRMd8AnKTnyY3VGiYA02cmTHz5Sg38LWcC8Vg/HX5uwregr/q+uBTypv4HUwX1s8WsE2wCgN0/oRrwR8i8fRLWDN+JToR6th0XXLJ3lzWv24d/G1f+IIK5jX42yrVQ0H3JHVCv+IE50T7InQu+pa8WPLaa+o8ji/mtlJfx8GAa4S85sPaR3UkSsZzlzxw7LaFYuWRd6jtvhH0RQXV8VnM5UzchDd0cJp2z8TBZ4flHI0Rzx8an67HrfojUhbo5r2H1lD+ZNglN+hxPepx5lnUu9YMd1ZKFZ90RXOPskB6ohGnCUYbLGA1ReJSteiNfbuQ7Nd3bK3r21X5+o3nnvuhZPQVsx4pHlUy6opZjxWx5eQcUkJ8ylvKv5RHlPeVFhJu2fvMy9vJE3sTL20DepAesIbOB3oIzJlMnFc9vziLkyOsPb85LDO6FklQtQN/AOka56gHwLGG8qSiAEt1GZ0hb5eEZk4SNAEj9UUk6CI9fKxB+WTnEf7Dq8b/NoL/BGWhDHyiLKCrnxmk8ROIST0KWQ8nejveQ29GdyIrLFkOyCZbi5wNgm+ygCb2ZqImzmRA8xB0zGSLF+1RtJ4k9aouGKorVJWxjngDujIPa791ls059twb7vdsZbNI5l+lHdkZD65UxrPsYt9S1rnisTFzV2+4SXzpyNebr/76FmWSiHI3BvhvhHGWM+NUP0gWYHg5OE43nLhzcJxun6G8yWouzQHbbkWZUD0g1q46OCyMM8750JVhZLOgDtrqkIIxye2U/NSQppyZcnRk6NkJswB3RuTBkoxht7umzp15t8d7ztWbnLpNFy9wZYydNXmtYyvrIYYXt7ycZ79m9pxBjgLln81N75GrhPmLly+59cqLS5dcet2iZXPEJ7748JWJUlXl1jl/+fhDKuOFwIsAyICRsTNPM3EDSoFelQKQhibGbGBhYrwF/VNYsjojuqKOsGQ4ACqsRXamhOByKgTgTbPN6FlzzQleD3onodNrWsloYOGlBY/bu3946Fv4vClhxZdxOObflH9TULQ6nDFGslaRLSwHbrjF2s4PMWs8Zx2SjRKORDXXt8gbcIV0hR4ue9/OZ/Oe7d3cW1nNkZtuEF1kxBzux2MN6xSJjLhPYO9hCxmqj24G3vaAeecxm5h4TpK3VAZdfEvCmmPXlzd5TTl2mL2Xb0H3W7IdSNhtjBWYam1BXxxmLhWDFbTaqvYyss1atRdp0e3IDyLSQpBsdsneLFntkqt5e7cl34+hM86wumDGcEyfcUYVidtdGcmoA4VG4kBgrKrAtBMSFI2QCzU3yrtTJ4JmKL6Z3Zwx9YIZ92V6zrt48sz8e99kH8tuPTqranaP558qLFKUdx9+nVwpXHVNfO3qp/v3d3B5m5ULCypZVvn5iy8V5XWGysJqoImLrssQs4KJZyJVcpP6zsS1NDkLM9GFdQpAj5KwXJpyFf6SrvqyQMlZmxO2LCvwO4THOBzbpgvMY55hiNWWFdK0X7tXKq9NTpi5PibxDkkXS+pBj1dXBQ6VaCPobKlTZ13phFldWUXO+bjP0uIeJef2vvnTPLb3/Wc/3RQoUn54aeen3xYsuHzavZmZUy47Z2UV24V4SJCcEfSt9eUde9VSE1N+eONb5SCJEf7t/X+5c80zZ/QGOXkf1scykBMzs4CJ63F16KLUduByIJIlLFtVKnTr/N1oNaysskJEKcg62xEraMSEqMPgV29PGPRGIAUc20gRhzdRAGTRgKGnqNMb2kjA6KkUqPaQYTldEBwo1/s+7i6f8u73k0p3lk4gdQcF9/r1yl6lUFm/YQMZw+bC2NDXPRd4WQO89DJBJsxEmbgbuZmVdHMrgZuhgNsA3AzhPDqF5Wqwg3IoABrWxsXa3NqTdFB9Gr3TaX+u/+lrx43ylDLHn3t0V5Fv7ezp070Vyrd7d7z7bdaMyy58yuebPWfa5jWZY887+06Pd9y5Y+6EBbq1tOLx2W++9O7zVz0WCm+74oNXP9i35IbbFly7+h624opFy2bNW3qzKpu4Xq2abK7SZJOH2ThwNkUwG1NupsNCxbSdbIYO36fKps4uFTTLbscRKaMZXiT0ugIQzwAe43CeJp4Qbj6j02e4AwVJ8Ux/pfKGzwTeMDHJ5KDLs5HkEhrfoL/P1te12ezidlHRzbXRSwYt2h3k628788WXi4tJQH7zrYr6TsprH/Vd/ZB/0pyJd5b68i5YPGFz8Zoc38fv+Xr3JsaD3xG/8rnyvfIQWPGPc7gtDz47aeC6Pc+9iXTpB8rsE76B5m+mnZy/ITR/I/PwUhehaRzhAKZpEqwo6MvVOD3cPq8jtOV1UsmcPYdWIRU5otp2mrSBn37gW9mof8XNpT4We/wAeH2fwngExsAsZuI6Qu2JLMIADDAAY1jSUcshiXgPcGplk3aPNw49meIUoTaEb5YIuLVEB+uHtyc4Xg+8gpdp6weu4fpJELAXWvpGO9McKNUhxUMZdUolGG7SMeUvwUET8H5mcHHuMNhAxtVIiE7Qub2C7kyPnutV2vr26KHk3VLyj5ml5Mq9LU7R9fe9SPeVZC1v5P5K6e5XPVq+hbqTaCz0YSSd5soS+FkZ4HSB1qH5nC6frN20iWzctEm1Qz3h3nvh3uBcNpKi+tpQUT2xsT1L2LNHD1V0IXa/3qqf8fL3cN9vX1JuLOlbAvfeDQt8L10LucyNTDwLeZ4blbOBxjkRGsTIHr4l7uHQP/H40Y/KC0vZB+Qcl8Znn71FyrZLWXie62qR8zUezPrx7yoPsuySpVnKtUtmCPrMFgz68EitUxZaJz8oLU82KAvGQJVFSk3A/8HupL7NF0Pa784l5PGnpGDW/Su6Fjt35faZt3Cs0zN80tAVzm1VZXvK+PPv3/W6vHzX1XWjx62aM2HJ3DEXz5hy7tFNb72FtF6gdBHHC2tBi/VmrtN8FFtUztW10HO5TmiRqsNNZTomAOFsjzDmWKTCsMxhqqVPWO6raeiN329TZ9fVLnUDOyUckfzNTMKf1bWbKjvJM3WNG8pgnpUxuUcd/DaDv+aQfDhVJxPIZzhqdrX4XrNNUU5Vh04WP8A6A3DuhU/kM4VwvR70ZL2L2i/dgqlsBhlLBpDyyVHl3281jtI33n7OzNF1A4nr7vHzO/Piprzi8LTnS8e/o+xTflZio8d/QgJDn+1hG7BvnPKM8iY7K7vX0MF5uYJhrbtT1szHupFPySOsU+GU8QeUfSMHjxh+uJlwJFYf5VufnX3WN4+TReQJpUxZoyxTBpcHZ5SFydGP74h6gtl5bLbJ8tlHdO2CG8BfB7ZOB9IYTekSau2aRD1DQL2KKN1mNRxw0SiUgSjWgXnRTtVBEnUFuQBHAlyohuu06YtXoq3795Ei8vwYUZB+G0GuUJaz2exSFlbNaLjXdrhXBsSUFchVGgegW02NawVodCAi3jKAGr0yLGUdkG2gN0Ios5hortJkdvehm6jdZaqkiipwQWQ3+B8VdhjWEcltT+S7K1DP45EDP8OdH6hIKXJGDuRrY4+SQMTr8Wag/Hq8Hl0GGrsi5GBdbXGoOBioV8/rQuCljwbHofnVGcOIyb3iwssi+cRQrvzzXeVr0vnix3xGkllyufJEHgmNXe/Wk+K6648L0uSBV1fWXHhHYdbUXsPLw+/tXrd0fm1577K+6666KBToX1RPdQHGm1/Aui5lbmLihUiPbKBHdiEu4+w8Q7nqiDmRHmVhqeSAnAn0yLSjB0Kd8XLN5lUdfi3dH/OAzXODnMPkPaqcJ8/ocraiKcujkVR+AKMUJyzrhNEUKKHZLep51SFFbCRYV1sDtChgdZzoFoFcQJKoFwglhopra9bUxEi3b95feCHh2edIQ+/bb3ovVGsjnQbdc+OGum1sN+WHj/964yR2IuFJgPQkN138SGGx4HZdN2K8cvxl5bfBvS4duYTc9YB44FeydfGTfVS7j3LyK/W/fMxGTUosSSnxISn8mKyTnBEUCkkfkbM0uXjp0PykXPioXFhAIHxULrZ333foAbU64QRvzdHMY2SObhvmSwxGtDNwTPPQE3qDw5n0VQ0Why/dGfBBWCqJKSFyA6VYJhAKRJxg9pFiqsQsar1ztjXUTXlY+ekbonvih7ISS49zdz4vSFuXbenVf7fyjrJrHSFv7e3d9fpxN6A84Nx/hrmbmOnazA3JmYPr0ySoS1Lg6JJMZYReOrQgOW+eztsA8+bV9dA+OYTrgRdUlzOZF4IpQGSh/sCguYV5rX3OZafltd41jX01T5DWK6XrW39ZxyTH1wrjMzCTNG1hiLYNTy/Q4elxeEYaE6db+92HblRHSY29AY19u6ElcGQdDQsHtSSvtdsUdkpe6/prcUTG9a1X43iug/XzK6yfCmYfEw8l109y0cSdNHfhNEG8HigIQSAjBaOoXaT8CFUw5e0XlKNFMkWSWqYxcvjLdmsqC9fU9u4vH7pajfXyQY7ywOsPohwVNmOA4/bkFbald+BVfrAwPb1DV14Tnw2DwZKH3iEZYfUFYPVJ5THZWUADoGToo4pVsEZdgCIuwAyvmg0C1cShZ45r8Lau9WTyvw7MnMRy2+oabr/1l6Kutprhm6ZtKu6lfJ5Hvriop/LzC3+/4Ty2F6kgftLtqhkPejJFnXjV4OHKDmX/gG6XDL+idykZvL712zNueOzKx3ppfBYWUjnUVmBch+lLlddxVhDhvMnIIbslPiobOdXXM1Omm4CkJpA+zIWolUKs0mHRUNdWNEzK7iuHrkNybu/efGg6FQ8TuH0mVo2feD0EUhBFYTgF1414nQOv0GBMl5MoF3BFSdBFJWXnEvb6JTuVT3Ze27oIRKV1Nrv6txHs4taFVH4ngILpRfOBje2tncRGtcQk9Yi51PBxwOlJr5RDTKJkAgnuUj5BO4ffXQmyOAq+24OZQwejpbbM+OUW+HJvWHIfwEQuXZkO9MLxzAy3scBtMrXbaOJllcx2ydQsWewQWENsbEV/DI9UjMw8uGF6B00wgSmWiTumZQxSIhJNCUgDt92U2+nS8ff59u/cX6b8tGPrlL7kFqGuvF+o+5oFfM7RL9/6YObg+bU4h67A9zqYg4W5Iql/LBrXZVYAnnNmusQ5dAqslFwweBhlily29nyFtxKcBdNAZjxyMmemc5BZQs0wAxfUsJ+oYT+yE368BlCfQa4rUPiaFaz3O7b1EnLdx0rTtYuBp0vZBUJrWWs5u7p1NpPUS1yC5jX7auPmNL1JGSsm08WpFGbSVBC7xDRjwYNr5iC+TxMqQrXhTuUYuxCU4G/frtPuI2I+2cG8rN4nodObHYVeTYiwbu6kVHEAVRwpwZddJ1ooVClghuySrbntqh4L0wJGQyJcveWnSzB9lMojwKcTdocNDBUc0wIieJPaK4PRZlftFRGT55q86B0gJLwZ5YVgdpI3WWMxldguL0w1mEVCQO2gCa3WL9sF9vafYQXNu1FonXXtbnHiPEE6ej7h74OF1IPtxh69jr+69eXW5nZ64hqN7jpTUl5QSZygEk5c/MkcokYOE85/e/edh+bSqxiWAjlELNpzEIAbT6jVq5OROYM2FVKPaoDoqBogG8RPYXHuUi4QP4XhP074Ub+N4MeQo4+hj3H98YNCBtgNFxNiHmDiVhw51rWp5SgUaUJBch7AorXksdNgKTdCg1hjJJVoKDn8cLqByHBgFTZVx+WlXDAQOeBoGNFAmGgNwGjKyMkNpWoAYDLgQloWTM73YOGVT1YeZac+1s4g6DhMMeCyrhd1ybVO/VUdmIhV4I8N/eGbm6daaxqUR379/IZJb9lIzfAH1n1dWmMlnUc+cdsnIeqN5ZI+25Zu7tFPOaZ8obywdcmTvQcO7nH5mdf+speI/bpeOfpa8utuzRcTOKoPfKleEUs05Yo1ma1UHZg1r6xNHWRonM5KGf9lacbfgiVu0Ag+0AtWPILxN1t9Kb76QLCljJR7pbrmAc6lOuRgD3UB4DFreW3aEGIsV77+RElcejsZevVTmfr8yFKlSZCuPOeacPSdL1q3sn974PLyokE1w4jK9wDlu4+pZJqYeAbyPT/J9zLke1VYyjwgZ5swWpaLYfSFKb6HNb5HDx9M57sf+F6ZzvdC4HvwRL77g4WV7fjuD1am8b04Gx0De4a1THMMbCAB+RlaFV4qc8iZJ0kC1pt1NB5V5cHdJg+ay5AmD/nLL9i84YXIRfVUKKKaTMQ6EokN/x7+zvx/2p0ni8U1KBVJH71F2AxxSy1zTFv5vtLkyq8FySgpo5JRgpJRRyWjFKhYaqdVnQxXC5bHbBjYBeFyMCwFojTWc0QSnTKy9eVSVTTp3dd3pDvhm6TaZvTqN6pErwKi5ye9emczuPn2hMMJbr2Ub08E8qtc5QL8TaKktBZkrgyPHPMM2M78QIopxJlfUlabYoqcgckOkz8Wk21BOMuk/QAlmAqxIUc6CiLRY6N88OqCwJPaOi0cCKULbxCFl/zrramDiMl366XnB93GLDPhs4RXszhbliEvPF2RF20g/lse8xsCkZuVd4TNM4ct6lS34IFw6ZianhWR5bEKi7GmIDOvsyj2HHBDeVHfij6kdTnnXLyooqh/WQ/VJk4Df+RBkPVG5mom3pD0R/zIIMqVHtQhqXS1JPhKt75c7g7k7h6mHkqlXS4ENuXCaS7QGdlkAZZZwnKtq0XuCW9VYluI4ATRtDjijpJq7NupdUoRpBBQtYklzkBE7ZVArwRIU58MrOl/NZhlrkPKtcWY4JRS0nkoQWHFwwfray5jtxlIr/G3T3nYqSMlnZ94e2x3Yi4gpuYDl48mFna7vrrPLRfc7dAXRJ85MAbeKlR+2PvBbTMIeUSsLJrSqRe55OxA7oBw78Z+0wZeFu3y9LNk/tk3RGJCccGohjPmjSop6FvSte+wqQPmRWJbNpOZI1ZFgXb7Qe/ZaF5kEBMXUesJbTUAmddF1MyqeEAW0nKmybootViq+eKSnW9aZjAAnN+fx+fmKWcox3ZCxONev/63g4JbzQUI4+GeXuzBcqbHfnHWYo2iMc0MS54DEhPBu0pcBG6R7mWDVZWtMBxf+7CQT3dytnfffmioqr0smOrDWpUNMwWc2UZXgYy/qUoSwBRJ7phswY4Pg9rxAV6lrp2HSXl5xys7XzGTyj633fJ5AE6jyjP/2n/l2YS8x/31WFG36gm1I556EE+Vf5Jrx69qgLm+DPQdTePIEjW7F2eS/pMaOJIMGjgyMgNRuMTTBjBXHqlHZ+Xltx61iJ1Y8e3W/IfAtG+fRWbz/VQf/CPwz47A97qZmFr/kKxR+tWyaEYCepK9arQlDd0HmCHcxI1OkdFJnSK4kc4LN0rejgsTHQl+1NyJF7qTmx+fIIp1ZHxz67tPTuaFUmXkk4J0bMCj5DFu67EBT5Gnua2/jeB+mk8WHAPTeLwV5llI/aNizXomK61CNBnCM7T4B+4N3jxogBuTKHi/HOHYUmXv1wfIim9bvyDd//GZMp39lN3fuoft3FrVWsD2an2BrvPv4R5nU1re0FavonMmfFQlqP4AeqEJotPDOmfMLTR5bW4LzV88dKEqE+CBGpo1B3TX8O9/wauy3qBHpWsAD41gsZeJs1i8qiLa7xNrV6pPyQVd33+8WyT/+GvrzAubp4PbHiXsm8fOaD3OWum4g2BDxtNxJ3s8dMnYnVMzCKoE6NQaMG3LUXMu9SSASfaALmjg6lvX5XE9so+9zD6Rt5pfvP7Wo1esU/WfTdnDbhOvpWtY0mEnKSZOMGFPu1DUhL1m0Fva50+ELDV/knWES2DCJK2JBu9Kojob6Upm+55Ufn7Sp+zRbV1/ZNF6vOfPxxezD9H4ciCjijRJxZXESjsksZ0Hq8laXNn86s+mZNcsrE+VwqzMcql6BtAz+POWI1sECZtUyPG7YV696bzOwioEcBsnJLERvA+nTlKMdDhBtkoSq1BV6MBnEWEsDpggC2u6bYJcPYh8fYBc6HuKGJ/ykdnKy8qe9eL1638dAPNbwH7IFVOe5Sf7aYxqathKpQkCQ2ASS/umaGoY1g63gDxy/RK5FxF9X7Mfsu+3lpIHu5JuygSYy5rjU7kMWr30w/cxqn6lJ+mNOsDsGXncpLx1tDfoR/45dhjYNY4pUMfQxBkZO1+e1lhkbmssgkH8+PXldwuvKD8DP848fpD7ih/GlIN+eIeJ56PmKcbbRviWuIuoRe+4yYVpI5PNAF9dX+yyABGjWFqgvVkNYansgFwF5rDKjuGk7AULmufVwcrKh4v5Ycwx5YGZ7JKqcj2lLq5abJeh7qIPwppae4KvxfRGHR45JiH4/LWqI8LjaV2bI1JVhiVaO5jYfIdsjcBvnVNyYexcDNQOYk1Stnu1okwXonoZoVQ/ieotiuCieIM1dfXgMFLDmnIYG7FAMS6fCK9vc4vZZeePXGZ5ls0gfNPGc/saplkElnCv8kLvp85e06+a7BUy8s4849GqkhcvuJd0euihGYGsWGENuaCXuPD5Sf3mlFS1/tKtxl/rr24M9J9IxnQbW1Lq95T5S87t8eqVqu8YBb/ELGYyGUwRc0TTihnRuJ12BYEvLiIbCtAXL051eYHI5gKpjaC4Qyljq7nbpAoEEjw/Ngc0f0Yz9oC/kyppZTeDA30EDB3G0/NoPJ1hT3AZmGCy2hMWqxlO4IobrySK8BiH87TacFEMtFocPohBdg8DYTmzxZ2VXZTWVGsA62nJaHdRbeog2DubCfzKdchiAbqPBZh6d2l5DmxpUF0gWlQK6VxaTTnlEEVJ553zYivO2jyylrj4yPfPjVpRFh2VOXPU5Xfm887MqsUDruokZrY2x7o9NevWsya6jxybdNa9JNR/1DMb3WMHj+l15fihVBeeD3L/Dch9KfPkKeoMpF2dAX0MzIx6IqnkqLWt2hA4fKWmssDpZoH0nixwut3N2PhPGCQhHNNT6ak6hEzcaZnQOJ9XiI6j3hE3YSEiWYkwZWqVCBetq7evRIiah12frETQ6Gemroj4Pnvy/MFEx27mi6MXLHvApzP5Sm8bvcH6FJuh/LDp3fP6sfqyf5HKuaMvLSwW/Jn9I73/dl9Zn4YxvWaSK88WV79zz8VrG0A+zwP5XKfJ5w9qD6BkjMZttJsCY8V0+XQdkL1AJ6+daj+jBwJFbVNCm6i2dSQwqNxlN1iXovSAkfaPgITrj8A5zd5v7/76oYeptCZJCo54QpcL8UwiD4/tKRyHayirOpRQ7Cs0uHPz0iR0C1xLu0IZYPIiA2wFlOxZJlrwRIr7sanZi5mUejW0DGmaAks/WjHzYr7+0ItnLS2/fKey52Fd11Ujnx7TQPbbsjst6X9xeKp/+rD5GwpZvZt4ib9vIzvsyDfTujfec+GN/YYN7HpW12lk+EByvMeQD7eq+mAKyOYBkM1cpoyZwcR9jJa8p3SGSKUp3+zDHqR8lM7ysJRzAL1cWL00RtHbW+QK+F1oxek485Ly5Pao8uSDiXliktkhu3MgkivJx8xpYSxNuDBmC6SCZ6ze0tpWvTeg5RoKxDm6YhKWXh3d3ZjReqlYWHPtmHWx+m4vXPP6tKEHOfI8L+aUzR25gdVX/EDKbph4c333q6rLL+x7fpdO18aGkLvm3NuwW/QXBwbVDCGPqr7JcjB5N4uV4Otv0DSgNxrncMK8KxqVWaFFJp5IRLKFZT1KWib1ILxpzr2WOqMyJTSDAELQK6jSgkZF3X/jtSdcXie89OCRYyBio4EuLzhdnjb74kX/k+WQXjZOrXzrtfDWFayPqn3uqUYs7L9b/tw9OfdkF+67J7dHUY29yjdoiiv7jZw3nuMeXb18a9xsuJMXp09avvrYGOBvZ2Uw3xv4m89UE6/WUxuCdeTDRhF/NO7GaVeJEGpC8Il55Qj23WFeQI6mypt71Mk6sLNODoBGr4YFtO3QQLUU44cFBBFXVvP2Lm+21NF1Q/t9/Nh4+Nqhe+gVhz3hdLgwDwDv+dT31Gy7CSxFoiwLriTK8RiHz6UtLvietFfwuTTrUI4rTgeLLytQVl6dZhNMeNHnb3851erGqy6trwp+Z1JZTOsmQulrJOo6rFfz+MWutuyOugQ7Dy+9sfeC+7JssZuGPz2uq52v/+XFc24pL9v0XqXy4wd9HtltzYks6T+v05Ssi4bNv79QWX93btHaGwfV1W+4cGnfoW7iIVnDBlx/9N3Pv6zgVvXrOrL79DMGk197DvvrFpTPKPjmAuhAH7NHq/9YrD6s/1Dj7BZT6T4frERfuygUt/0YwSWyGB36cnWlhmmFo61Ke1XK4SXN8NegE7c3+g8PV1lMA1ItOPWBqfahYc7EYxyOaaTnYswzaI1tmRrNE8lz1cCwNLiTLLiPi2lvcHUQnKRsLIdG9sreD467a1CY2JftXGb2hmb0vqn+PjCs9w0cdlGf2Y1DW8eyj3apbAx2Hd7r2Jcg071AcXUB+rTvwYoTQgsO6IiCVy4Yk454WllJS4FLBJMqSDJMFuA5rQyF2/VgaQF8quQEITe21vT6YOcHw0t2lvANR3cLw/fuZdjjRcpgtg+Mx8a4mEshCiS0MosJG16kBSdwqyV7GLdvOQwtkhNGlRGWHAdkJ+bYtL4sXF12PHfBGNztcxp06cESc9K9czLm4Ak9JpuuVAHGrAD1ZXBvyF8rLJ0s9WMyvt35beGLt2d1YnNCu0LKhPWC7pzz+duPzoo/bhCPv/IKylsNyFsZjN/CXJ9ed8JmNiw5CRa1oMOZaS86MQCVI6cpQCW3U/1eAQqIHksrQQknlaC4IFcD0vHMZWTc56xyBrF++f7lk8XMY/PJ44Lia42TQ4oFx98mDwNT0nDaeuK89GXAqXEfYdv2SULo2AturuwRM498o9oNoJPYFXRpFfO5Vn9yZRRU0foTkIquTskcxUy2lAUECtMBVJlorEIHYKFrNAinBaaWRHFBENZowNYiFaib9Oxw0WX3wsUM+KOMMBWFTu3F0QpfhgnvxvDhN9s2OkgutEBM3OmupKkB9XfKDYbVKgUdUllMKsAgXs7ArlNDFhhrlwPsDSOXoQ0yYIxDHDSNANKuUw2Pumrd7VetmOFut4hrPnjS0vjw5HELM3pIF63sX+G4btf1dmdw6pmrA2T5ruttrsLJQ+aXb+Qbrhsw9Pzzxl94af+5/Ua3LmCXn9XQPbfrquksS1rPYJcPre9e0HNoH1jkTFIPskBvH7My2Ynii6YR+1Sq0PKfqkKNoqAEM5sZKbMKTH17olkdVIkh0RjZTetdNFGUJM9JhOGiHzzl6PXIpLsHhW3Ldy6zuItn97upZgPfsObMs6f1mt19aOso9pHenbrmdx7V/9j3oMsmg7/LwRyxFtYnWQtL+l+FXAe1MNp6VAq/abWKt55QrUp3rMRUtQpzwN52wc0croTkvfPa5IFGrlT54p19kwe8biLZVYuvfDKLM+aEr7vqiSzW4fmNVN5zyYYuPT1Hlffumbu+a+++DeeCx/7lY55enSf2nf33R7GP7XNlEm+EOaDP/ldGiyUxk5BiFDjsmCzJiFK3HdhFBVxjl6ctwnS1RZgp7oCAg7/e2PlnPZX39LCyLYJ0ZRSBknHjMQ7naYbKnQoft5gtrrQwkZzwmjI+F+xWQrRnFkAEpMWLxtSi4Egb15NRI3dS1AgsAq98zejNI+sgaPzuubNvrpy+zD/tjCvuDfCOnOrFvS+pUiYJH83o3lONGn872qux9d/sE439n9voHtl/Qt+rh2m9WOcBXcMaXb9jtBgIN+yoBkaLhcC2mMIQI3UUEaWFQeHDb3cUBmlkFrD8q8d2LMnQ3EH8Y7InzCYa/5hOjn/gHaR0Ht1mYHYnIx3swtEb2l6nhT6yDZWP0RHnc9UQqCCLRubo+erSAiFMh7k6qLGlBUIjl5UXPqy8t/OCzosHPj2mC8ZBi3vMqJqTPWXg/HuTcVCvxlm/FZN/VUfVOKjbyO4zBvZiS2M9P92q6hnODnS2MRdo9sOWrmVMeliFdiq2WCSzpbQMqpj2smqjDSO4oQZ+0jUJIxOTlqFtU626kKYxzJ1vPSMjbOp+Ua85pev4hlXDR+v4Z8XBfY61Uj04EmK0bTC+RmZhei2J/Ge1JCxM1LpaMAGWi/5FoYk26+aa2mpJkhM9tYTDX92ABdC0UtIW4swNFEa6txWTtFhUzXKpqay2NRFMxmw60SuqxSQdVudUBo5lt7HhhjHjFprYnOL58TN7Ed7z/eOPjx8gctu4YMWYsXPB2yL+gqu2ndGTcJn/jm8/fwgZKLqcQ0o6kdF9bNZwfmle+aAu473+5c+cP2RKdq5ot9ZXdCYTethtlf5gbvmQbud6fWueuujMqTlAt5XHD7K7hUYmh9nBxD1IN5uI7hflLe2ooRgA+pxIag8ob1D35+aGJf8B2eSijRPJPaB5Gru3HuqjsptDXYQb8QwQ/WXbE2x2BztC4XoOXocA0JCNASAr6A3ZOW0BoMmvbrPiHBgr86DIXTQY9GjJKgQZUDdepaivSyUHXCtz7q3dWftcznOLdWZPtbeni+TMqJneuZCYFkM8SATl6OrWOUF/vj2bGISlTu+gTiMq6thVKFeXg+3pyTeAfX1Y1doo97QqbxA17Z2sfflpYV7AMoaQqVfDDcFON+zaLHRNJOtfmnVtrDy8WyVSu/qXFn6oEQYsNvQHwV9Rf7ctmIyYbLPDbwcuHAPoC0emWn+HgMyrpZ+AJskkSW3Nsmt2XptBbIHJ56yKrN8JNrjHg+etH1RFdrCLWq89r7FzdlcyZhhnOLr7jrNGz+s/byBdV2vBv7DB/NPqYKR9Hcx16jrY2t1zONFHxr/S+rdVfEOr0IP0ZI8e3Y3fu5lhBAW+t30djPx3dTB6TNbBNjf7ebGKjFjXSMQaEmxW+PUNojhYaV4PQxgxj72MlVpH3EiWstLR3eztEpFbZzHkeAvot19gPO3rYOR36mCEwzoYcQU50J4P/evTm4n1C2Xq4U/WKN+wQdarXExWtra0fkLuVi6E79+hDOar6Hy7Ah0Jna/k0vIJHrp30ehWJ2s0UGefkXmXuqHH4IgT1kKnzNUXqwlxDokMt6cWtk/UOtpYMz2/1/0f9BZEsvr91vO7S/Pd/ZRx64k4v+vFfGHr2VcRruho/qwHTKrfqIf5fknnW5PWxysQtVG2bcYGbX8jD7Eg+E6S4FQjkHoSoiUub0Cnz2afYVv/lccq/tY+LBvLu4mzCffceOygoNW5Rih3cDliZyafuZvuSmFxr14gLBek+lg/V5dBDpb1aB+rtRleJIQcEZSDx56weXDfnhuPeD0Xr8fhmObDCLE4vK9t5XtWEK02tycnt20z84lX1DwH3dXoRFlqJEjW7qQ+jyBeAt1cBt4hzSrhTqkRBuuEy52B7OdfEF3T57oDzunnDIjZA57aSQ1PX5YdcA5k87qMWTjnTfnrGnZ2sOmGN2dvLA9vnPzG8qcLL6//1xNvXLqA0qJO+Yl8lay/ndjX6WmLwzypOAzI89VJVXI22QpI1EIWqSMZ65V/Kj+JLxzB/tjjTyl3s1eK3ZgAcycj+cKyB2leEMbASoOheTeln03Ncg74ik6M8RI8ZwJSG/GIpHblYHYuG49xeCuN4MZYHC7jmQsIzvFGk9OVVNlI8BOvqAT3YLoTJUiHCCl0Ox9SN1SvUjtqYzGDB9QPnTV9jifgmDtpRKMj4K47t8tT87ICroGTBYsw8XJHIGfHDvHnwsSSN+beV1q+cfqby6XgZUDmNy+7InBm/jWz35C+qWGR3teSVfwbXBD091gGHBTZwEOMEFbbQ2lU1OTzMFl8OQZGZlLeZKGvUEPLZh/GMna0MwZQtHHG5cPcrcch6zLgN+eMi2Z1VbpUX0VNMHhVp1d1v671vLBw2I29qs4IN8wy3+BtvnrE9b3DZ1R1mWEiH926o3+faNW8Ic4Vr/Qe2KnTjEEYJ7QoN5HXtb1z1zMdbZZLC9hNyZyWunNNcIDBCcsi/FJ3yznaMjU7D81ShUigQiTSUm4yGYt8ZykMUoIhWNhN26qmZnS8L+96uaH0hVLlJgRC4v/25ptA20uPm7jvhWKmgPmJQW8gL9rkNjImIKY13CSoZ5heCsJbB7RenVR6SdTcb2sLZsmpTJYdjreDnQE94AB7uOPQ2dQe5oFw5gnJQgOMNpGDR7yej9fjcEyTTz4Wh/e1ogO42bzO4czJT0c3aH9FbSnJVXNyokO2gjmF6AAYb9a2ylvR+Bgz/TEthnS2g/ih4ktLPirKTzF7qS7wz+cqd1Utut6zxTGVFnyyzsR6z9Os88vVVbs63bGI1ZcdIAU5n/2j4K3l0278231lT75/5dni4j3ur36qIAHs2Qb7O054BWj8aBJngu4OiFu0Lf9NOj1jsYD6hrAf+xNkMTsSSTgZi76cUh7iYrujjcap0qOAeTI5R38E4noBXiVEwYit7HjEhe/LyaQLP1Mt/Rozc5J61GDM9LVb1rId1EDcFShQ8Uii9VFc20FwyTS4HQ0DCfdKYBtaQFeZZ6gc4c68PW9FRfnRhJQoZnf4xo0/62Z/Jbk2T7nB52ooYh/NX2d5adqa9cT64ccHHhUWXbR2sfLT+jUTN8bWQdxXfPwr4Sb+R7qTuA8Tz6NxXxBIEIIFXgnGi0/fQZwHEaufycaIVap0JHQuH8FTizOhN9qd1HFvJBQvpz5U71VXc71XRxGbki2MWP1EDjN0EyFT/EDAnuEe0zh10/nDpXFn3dn1kVlPFzhd7jMbLtg07sxtE89e3+XO10of2ngbySoKbbp3tfLV3FVDEpNm7Bh228031XRu7HznLfcOffaCaU2Dbrr5mi7dejUuZa/c00rM23YfUw6rdnMG+EgR2q+/RfORMjSULiOidLkRkIu1aygILk8k0sQLeBETbGDEZc6GXWBqW38GuKX6DIx8dGZQJWFZb25r6f/g0D/oCnNTrZBB89tuUAluTs0c2DNsLkzkwRGve/A69wzL2ezpRZoMvUNNAuH+ccmgbhLH/1RHCZmvYrvMyCdj/Mqj+STn8Ccvkz0ft35PcvKV+/1kIhwbdjaQovVL17Nvtl7BLm+NwKnyV1KEuvG48hPr03DhVjLtgOBOSl+fvJn4pA3EqTT/76rEDrDinkElyevagaKgokTXm9y7816yduda5Scu89g33B7251Yjjv1XxcGvhXUcZfoijoEXV28eh3tE1c1S/VSEDlip/bXhrf3pwVTLU3azXIU7xZoT/ipsSc7CYxyOafrOH2Oa9P6sbE2/pZ2n8BtkzoJ6LA/400RYR0NvKvm6RtIeuSy1xT61cpPoZakN94Re8dIdtfBHsED07HP5t18z72mXa1Zi/5OFrovH1AQzgiTnwOvvVrDbfXOuu+oxh3vK9vceD2ZcMqa20FWkfPPBy0fJLM/kZ0t75/Y51+qcubmsX17vMX0Fdt3VC86ZNLFH43b5vJtLIssnSS9++aqwcO2VYy4a16XPls2TbwpFlp737Na3uAEXTexm8Zndk3tNmtLDnGl1nw+0JiH+G+5NTU46a16WAKvEiP0xWpOksUWTmybRzOjA4htQbmiZkadaDOsDuKechPL3538JP/w3e+AfdgItPn5QeEJ4GXxnL1OLO//pjl+brkXd5+zWtTRFyw0crM4oXCuPYtRcXmUob8oupFezdWrLceBAU57qbmgdxI3lh59Vea5CrJUIFDYtkekLlagFpOQZZWleANRuQbgTNU6F5TD2/E6xtt3ALB5dLAMqC66AykrBo51ssICli2vITohkdKRfda3SqBxUflG2PVpJ2H98SK4tL1eOf/WRcs06V/Zba1esymJX2nqPPPNypyuj3+gR59lvZd3b77ztdvZD0p9sUoYoe5WtyljyDImBR3ofmQ3f6SQTlduV5isSb228Q7jgrJVz51+59OzzxHvueh90+QG2ibtQw0Bby2igOwIttxbqWqTSsFQSbeLUndTY4FRBEw8eC0WzoWtlw087VbqFaAdTBn9EcoFVC8HSDWGxuSSkdTC5MkLJDiY4LWlTXh7MDuups1eYi4g+WWD99Rz2V1s0F69Lcvt4mKi4ahz2KxXX1LdDk4MPHPDG111lsoZq6kcY1rP2phsuX+hvNAn84xxXOq//hRe+aCytK53r817VfTx312UX1/TuUd/JIk67+rYlyu6akZXuan+n7gtndKrsEpzTG3Ocs5i7uHXcMyDNNhUNAKPO5O9ZhCPnrVReWb/y0tQZmyNayA3Kxcol5IbkGdiTh8gV3H6ugBHBq9DQAZIoXzxuyNdRJAbM4mB/CC+o6lxtCwa1/VCAM9v67aphFz40RLmfiP9DDC2eWQLr6EltHUWYLsTT0UqqjtI1gwiG1XQlVUcM5XJmCVg7Xxf6lk9FL5QyDzRF1OXULdVV+HUbYKEUsSMyYRKAUyqhmyDksjy6OaJx/9Fqms4tsScKS4KIEoPH7Y0X/TKWXi+zJ8rLKuF6BR4F+LZEdaQLvI7iMQ7vpeniilgc/jztQmGM2RIsDFVUlpWnCvBmH1wpqaisjnZJXU2LlKLVQP/831nOWSSQREHBiAkb+immRzkBY0Q1czlZgovaQ/R0UXeni3o7LGoCi/oaXNR//6ty3b3LiH7Z7RmmIT1jJSYDmDh2jWDQ6c2RfrfVDV7WdZzR1O2cy0+ztu9oPZc7c8nCHhPysi4a2Lmsh9vuOStUN7in8jR5lzR2HtIZsb1EIZfbRfVyLqOpYaEldZLWT4noFET0sg95hdzVqzHPTzK5F9l/g45QdW5KPOI2zFgYdMkOFNTmKHA+TZsnOIPNhXUK+NIkGOIJeDEk0/P4lLGXuL2bLphwxRpzTXX5GSZTdVXlKL754js2TJu3Yu1FDX0H1jUMGIJrsS8jcL/xh2AONmZ1UuJx5GZblHa2yqIhEonzAooqbzFALBSJC3SXr6CDV/oIzZMj4IilJWHRY1em1aLW3dqy5Y3Vhz+iQmoFv9yKWCMWe8Jg0dMisV7tDLThdS4hGtS+eLUC30gotkcKRq9vHqfPa+3hI+f2eqoXGehTnoXfwvr17LZ1ZL0yZZ1yAdlA1/Ej7HquUXiV8TOD6awyQfHqw7JddxL2GRDZpZpM3Cjjwt16osUe6xAAzdUOAK0NjdIb0D3iJ4MH1xuMRbWdzzLcw9q2LL1iocd53vIHWNLfz66/nohdBpfXdulZLU6/8fpLRk+dtVS8Hsa5m13JnSnsBksxltFgz3TpsGdgLWQBrgillORYiDeHZauuDQTN0wEIGha/KPyZ43TwZ8k5qLEBiNJudqOxvqHreIOlttfVDv3V9YOMhrruVYN097G2+IJrV7jNIxsbas2Zz98ydx13iVhd1zXcq/bsUJdIVX11SJwyd8HMrmMzfRN7XnHpZciHVn4HG4f58UyF1jvMaL3DQhLZ0AikF7GTOc1bAdfTS1rf+ZxVPuR3EKOoHGPI8W+VSXw93wDxwxtq1RR3xjmTfexq7tpkjkajWHf0qDuAmVQZNa1jBtsrQTqxiQFjdnPabuA9h+5Qd0dr3rS2RxKTdpyHpUk72rHqOaExJs4Z3TStrf5OpbVh5WByF6vKOlpVxm1mOqu6pYk4aIKZAz87CTuYTHAXhzgPKW9eSEr7n3fWosqNOz942hy9ZnD3CXnjsZLYuorsu3pIf67g6O6JDQ2BIiUMtH4anLkvKM5ckbqHRgPbNKX2zeDeZ0GkGStGBZQJkKArWMA+XU7yPyZm5ZOd0wbve437+ONffxvB6omerqVd7FzyONcHdERI1RDGlnagkI4kspGjJWUZo7pdZS+UsXPffZfGfsf3K2eAPWQYO9NF3TMh63TYINNEqB9E8e5AHCxmxgLi4EQG0f4EI4qzXkdrspguVt36+qgqr6Eqa7exRmP9iNhyT+duNveDS5WRU6uro0Hd0hrTmSOmXoQ5M8Kyd9P+dQExBqmmZeHeJEK3PmgQm7JgSd+rnGq3FSTSzMsCf0TAvUUMKPY0cFZZSPXxgT52BeuLOMIuvjSLFDwAt1x5o/fYu6hjD7IJ7iYN4/JSRoO2FLCEKzuE9giXWo9KCuGSVxEuk601GsIl/wcRLl2/gxN80Ju3f83Nd+R48/+y9qY1u10Nw/rOdHidXYb2m2HnyWUb4i+suuxe6flV46fMHHXZOVNnnan1lIMPNwN8OD2ixNZj+l4XRXzP1EnDupUvs4RTNm5pO72LrCArlatEi3JV2xl+H0/sDCNMBd+JYwxMBmjtn5m4C1e4MxrXI70yXIiWKTmiskfXIlu9YJM8GRR7CfS4ZInIOj2F0xQ1OM0suknCYKGglu2ZygNTBWCqAZmqb07lEiVXlWSpklx22ZlzBHdryZnY4O60J6xOC6x8Bx7h7USGC1NJXhdNJcV5QyZ1f4yC3gLr2pXhzWzn+sB9UDOLOqqZM1xql4nHITMm0AsiyI8P9xeoIGdFELFwVJCSyIu6YH3IG3WFdMROMZy9qnzFLeTwo9Mu8V+S+3Duc+w73QTrNorSDM4rlTuFmcoGW49cf9ddSwVSzYKW5EgO0PgpjcaFzHombsR1WIAmERWz32nUg/vph9dOijbu9CAEaXu6FqXoWnwauuIGckTckxFj5CQ6IPRGgjF5EWtcFo3aMjqZDOTUFpfkUIIUqgQh7t8zwO2J0zqtY3MMVgoWrOgCv6GcCTMNTA/mIBOPoRx2juI+lPqo3BXEr6YbiF/XBqRRV/DepWjklGZacsPibmfRidQzZbh7tc9mS7EqKVolxexyZ5TAqF3ujhLY2Z6o6RwFkavHI7ydaIh1h5fd8MgxUndY+dGa+s6xhm7d0wWvnUvQtQFoXFENNC51SI2xNBch7q+sisX+oJtgAA4VnSii7/4B34EwlHtk4EmCzM37Xa+itYnysuBE+WaZTOVyzs93oZhtNzPxbKw15ETlLCOE3hHwp2U7BIj2TAqk72qP2JZEacOSnZt2ZNpasJzptrUBt03/USsxZWNZDz8JSljGrVyEHqnNd+fQUjYjZ9kxP0VhQrwqVltURW5LJinUvBNYssysjSu7hJw783pffPUEh3f4eUNWuLayecrxR5/ezAple8osy5oX1Z49bvWc8dfNOxtB28T7d73Ol7z9NsOpeGK6AoonZmO6nxJRTLKFqaOugYo5kjvHrLFTgIuBIg+eCDC2Hvd1pYOMsQuVnynuOx3HP3R5dBx2ptvvIJs5UoNwaoOQLTRP0eEwqCN44jhyqGPYbiRkruolJseS0A2gY8n43bG4U2PxJMdic55yLFx9URSi0pDuxPE8JhLvJduEe6Y92H5M9/i/+953xx3JMR3VjaRjymOWnJpPvjBivyaynT6IpGyCioprppk1cJulPLvM41BdNDnsJuVNHvoGYuXKfJ7DuYUlgsFky8Z6AOeQnb606Ug+B6KQOdWdJ+2mRhd4W7kPV/2Js3zFtvjsTrdVF/bWX2BfMqr74k5FvXTt5/vspBvP7RnOP++aCb0qGZ7O+UedRZNNVxKJuqNZm8OSPSpbjIhHQDulNba4k2yxO36HLWpm88TxvqYlOtuPcaOa9WS08V2nu4WODzFcR556fO5wU5aOyQAGBMJNNnpGpMLUMIu0YSZsjrwAbSPseKSnCNlPHHnUeeOoIefZXUtGDrvgMmO4tGiAwVBRWjyo/doLjJ0576zxU2ePrGroWtGpSyPFF7yLYXTXQAyA9L6PiZtxPky0PaiZ1W5GGCnwpax6CIIiTYLenEI5ywgnO9EbOx1+j1olM92la7bLBgdYJR78IwdYpRNansz2hMWMtXWHme58kZxglRD5zGxRUd1SWCM0EeeipGnDQQu4AgYScIWm8aO5VXmtCwezRXmtX4xib8s7tqWzwirHyRJy11wRociq1rf+tI6cqzzAOtitHOj9NcpA/hPwr3OYKmapitXZVEx5pPraZq5Fqgo35WmRRph2p2AxudOJzV2q123XH1G36BMN3yd1RlW8zoBlU4RIRzUPS04uKonFZHMx8F/v8mS2QfpFnFpuGsH8nG1qnyEnxjEart9vWexzxhspqF/ZmvVtkH7Kv0n2iZFOEuRP+e4D4d5nKbzf28ovKrbfnGM/nRgGaRgiP4OtwNU48/fR7jRzcWK3458AeIfL4WTQO6U/NS0a8p2ugO4dVsebRy3KadH5HOEUUPqfOFgXWJ8ORntcM0DaeEW3ZnySYx5ALc9pxwy+oefPH3PSSnUw7liaoUqOvadmpDht7BZNW19+Ggk5UWWnNrD8mVNRNXsHM8lMKffkPPpqip2lmHMDQc6xXnb2Sahzki58Yt+JlhkSIycCi9CNQDQxJfExdQOLoItpm5sw1g2qiHRRzTGigpscA3c2yC4HEfLADpDvDB3tVDF2dHd124w+dVfqEam3XZzyg1ISmLx3Mcggx5g7mD8Cqndwb+upZg76Wt0jYo5JrFMWTW3zT0qaOpqe7bygNLnC8UwGueKopZ10Mkf4MOJXC8Z0TMMThmf53eGpRBLTWKNJjjqy89M8gTQ5GQvxsJ5ibWXBmKitxMdLqCkiL0g7YcxYkLFkRSnig8xmYgNCWromCaEIFtJLLSQ+ksRrlzncUJzK5TjpHkr1uSQCGkrWjE9tsOARM9+ZVi/WwPHIMQmd3unSCiosp9ObLVany5uZdUJBRXtGWSCCT/phSgkWTxAKlS0nGJKNzbv3WrJIIeV1Khiq0nnJeBUPtXzHzufPO5J3hF27nl2krFR+oqCo7FqFQ1zU94lRyVmv4ZAtBH8VvdX3OkSa69hTbYOew+6zNqc12SaFwVWay/ongNLJZhNmDwwgBW7si+H0Np/qgiWx6jS3NxvdXvDv6f7k9vh1pAP390RMO9KjQ/83HehOHJ/uAFOUjVXHDwqirp7KWF7bE26SCGiZYkvyqXMd5v+0J9zsO/Tg//wJN4yKls+4kk+4YXGaiNehoZYRT1RFsVN+Plx+L8UrK3sM4cq+AvWWhCxTViitKogdhFz8u8cRqWw/c/zX3dx+LRbU5lxD55x/ijm3tcv+H8yZmvXTTZpsoNr1tPNmX1FVb3LeE+i8C08x76JwKnH2f8DrpMI+3dzfT6ny00//x5SeV+c/nc4/zOzqYP6YJisAnVFRUAo6I0+gPW1S9oGmsKoownYMpZqKVf1Q/b9HKDlMoeYQ6a/IkeAz80qpyijFlEg4JhU4pOzYaWjZgco4HVmf60CDnH5dmdsrFV6jc4GmU4L4DIiTKZ0dlvKjcg7Y1EAEQ1Uk7P+Z2KnG+HTk2aKZ6dPL3GHNhhOmP/MFn8MvwGc7uMDq02ckgj7vT+b9a81BMvd85ebv7vhWWU0mkqFk+CLlGTJ4kSIriUVkgLIVdVXw+APCDOE7xscUMdXYhUef4VIqqjlxOSBSeIQkLkKSSlb1SVxyEZCpMI14FbhPV3bqsdGXeRYD3cKiijYUypOuqJ0RpW4KSiAFHAlizammeJRq8sCLrWsu9dEHaqxI0UiLQzqnJ48Q7MmG0JJuR2TwkWVhEny2W2l2NEam/XTmqtj02x6PFfuiDcotRwdfX3PFLcQlspuLL+q16rfimt6B8Q33EL6kxkZs4rn/HvWPGwhHssmImvDNX476bCFQ/u+KXFF2H3vuimrC3VFcqhx9STmqzA8ECL+bCMOWdKL4nncghh7IooNxM8u1/YpiCkXPiBDWEObQLSFtyEJGfM6YuhWGUnXzIU8H+4Y03Dx1fyJ6BWYKm2cwazG5dkaXs5Hu4bQ5M9TeCLppKB2WmcWwE1HzCpelYea9c4hlwLSpsHnSxhRmHhHrkn68Or88mJ8HpaOj+dE688mTy/xTJ9cEk3N5UDRMDjnDHTvFLNGwdTTNrdSWnTxRoTQtblDnOgDm6mduPdVcszqaa/afPle3V50ruGodzzRpyjqYLfkpZb46mPGolL1S52uhsutDXJgOpdeJvQSyCxSpN0L3WJw8/aw/dfrPoBx7tPmrIKgdU0DVqh0R4G1Nk3Yw/XOS+U9WxTHU5TIGxnoKJEPbqZEM7f+rSIZZLAhyOprhZ1qom4ZpyItpstsXDONY+gwLD9pDGmGaUxFmk8lC8xb4gDXOTUH0gacU9FDtETEDQ81t0WZbN8htanxnT3Bm7P4w0aOFHj1mFRzfZPGkKm5E3denQVpEPDqRp+1rWlEt1BeCii7/3vd2Yany90/+3X3Coas3ezKnLP2RFSTlrz9ufe0z5VXyzsZZC+7iwLZVHT/Iu0VECZiqzSikobZBcCoFw+rOthI6gZAKENB+a7IKdBGyS8X4WNli2rlQnCQ6YhDh9uugI242ZKjo5G2PGBIZNU0d0mBG6pi2xw1xVR+EiUFeuSngf8DkJPqswo+fGvBA9qCC2Z3HXWJ3Kr/mOmRbRv/uY9fnfsA3fPfPzZuue6d+nHJwefy+spz7csKThp5LvLedc2DQ5CmP3YnbJ2Etjjt+kPtY+Jz2zIbxeYGZbc8NxqodOenBlU1caa4dGFnShhTYSW2kdbWkXMcUFKDWSOv47xpp7VUUtSRXfTKx3iFZ2qD/2j1HkmuD/GvXQotRlgb4lzGyDe/v/ucKplmMggr2d8etn9m7J5H+5qNdQrS/KdMp0t+LT7b+0m1aLQX5k28bOhzR/fgpaKUo7Xib8AmlXSfc1/vf0K46RbvIn0q7uL1Sbej+H1CPmrU/RD7SSTV4p6EgNyYZu1H5E0VKwxrcm/Tf0LA2RcO6P5WGTfaqcCRKI5T/iQwmTeYfouRFbbb0dMRckix3ajJZKDopPRuZw/8NPaVYWI5AsNg1EgPTExZU1IOKA02NarDYaJf9+Jh7F23vq4W4sU6NG3v+acRvrMAosRCiRL8jrg93pfslQaQjMSrSpZmUGbSvHtghx3D/emNMijikij/KnA7CyT/Ep2EdxJan5dh9J+SreMo3v7BP08NR5pn/inMVYalTVK4En6kalkVNalnU/smqpVN1R3z4o8tC9aP+ELUHJh2s01F4GXW3eE2/DKJ0rWd6My/+V3StDTd1UcvQPcNNYa0M3SdF3r5/KnmfsYdruzT2VBMj/yMKn6Ls/Yco/vkpauKnNZKGk8vkoJ/yjx8Uo/wwppLpzPRkZjPxcvSviqJyNYfdQpQd6CMCR6TGSFNDVjlyojYqNwgtFC2kl/rUbGuL3Ft7ana8PKyKY3U5EKkgJmU55ABWhvUN2rYbye5Q0T1O3nxDN2k6ERczTQmETjKECJGJf5YfOLT/bYenzzmjl9sSbOa/t0xaXTiwadIOqSKzdUbutNvOWT20qH7X4ss3h/t8s/aOOz6z9zunx5M15X+ZfBe7gyN7RP+QKyaCQn/0wVEXXzJnqFO8/cmhAwcOVX757IonXuwSvql8+AXjRsyOrxw+ZkznD+YRs5h33e1PUD97pjKQ+wLo1lGtnZyq1q63pGrtjVWH97WrtWf9bq1d/5/U2lX4qw72gdE4yXVirV1Drn0pl93cbhezhlq7q/mkSjtFsf3iQaFtR/Pqd0jn1tKTauwcMwfW+evCFxBR5jIFsNJpFytSRSVPNgQgXoML0VW96LyDE1+IO3rN2BZqR2gM7bHbdcxJ4sCmuI/epIaQ+mRBRuulnunXJPFR38ZqxvO8a+TckRvMmLanEKnKzx9d9fDLKjpqmFwm+hesfZQ9kMzX45gPCp/SMQdPP2Y1l/hHx0zLlv/BoF9Ws+6nHDbZq0V9Gq1FHR136PTjVp9Y/EfHnSpy/gdjZ9vS5qce/2HNS+Lp+H8WXqfZhwKmGLv32s8gH2aQpc4gi0OcB0Q694JVLQQFFArLJRTRxEw3E5xyIvhs3uRk8MUp5yGCPXs7NReyGjOxJ0+D+3bPntab1akcwUwCi88wI38HnwHru2echM3ZcbG9Q8jNjivtrqgJs3ddP9j1wRUg0RSEc18yPwf3Zn8S9pxUZyf/SZ293b3b1dnV3c9egjdtVLehwG35F1J9HnjfncKPtMY+qoP7/m6N/aQ5txWx46LJHGubd1L4cBw3pKSLjuXbVB4Lx3Jc2KLV189vGw3dUW5Q0Tb0kbbB/W6F/XcGl6qw06GpbhOO7OHklmIc1/ep+voQ8CWfEL4Dn6eKmc9org7IcUVYTb2E6b6xZBPWM4dqUk5LSbOcre0Pz6b7w7Pp/vDsE/aHJ/xZyY3EyTM1t8FVaINFR0XNnoMFEEJFVQQTGoiF4HHaaK2C1cwrSwFOhnQida8NuCbEC+Vlyt/qCZfTq3Bsz7nhH+u/GFQayqhRdrz54kcHs2ddO/cvwQyDa/GMWa+Q/YeIpU89P+3hxg1TV3iKbJs8fcNLpl61QGnac75yFILQ7H237Pz6icm1DUPf1fZOMHxniI0ws/O+hvZrNLmi7XAuEbYsEJb9EAAV+gMQAHmFVLLHBZxzpSDpEhks0Zc3hdSoiE3BACLCeQ5ERblqVHRSdojih2Kdfbb2GEgEAKZJSiZuMDtplk79nY5qJ5tCIKU2L8WRNzriol/FkQ/g2yEMlNTniCUR7yhUppo26ijGSWJn3lG2fOey3CEUOfOuDkIZiqb51jsIpXnXHMTRFPwn1dpRnx4RPj+x1p7Upplcu1p7Y8nhRzoohKUe3aEVwrL+8F4bTQuLacKl7bWhdlvF4NxbTCE4X9v7Tc4Eir+ZfS7Cb56HJptCcCqvfo8AnKTz94kPv3zMI33890e5bWq+B+bJE+GTE+vr7eaZBkf1/3+eNF/z+xMlPtXOn2qu7JOpfm6Vr6J4Yl293Xzb6ur/F3xN+Qi/O+ez2tyDU077g7QcCvLZA3pCrafv6GDe/1U9/X+DQHJRGAJGk+NUlfTfpV4HauH3CVnfUR39lCQ9dGL9HOlqBn/lpPp5OmVPVT//PxEv1dT+PlEiyer5KQnxMbXMHDOdaeLDfFzzF2Yw7dDTaX1Hj5ulJVNUNhjxQYzUY0BEP1NLQjQaQNTwcWgIzZWGQ4MPmKbA5qY0Z2LHoZHpgOqImEAdUviZXsxtLG5dVPpiaVbJiyXsqB07lIn79nHRfftQ9gcfX8B347dpdfnmZF1eQ8JVH1jfVpdv3PXbzFRdXmyWi0y0Lt/40m/z0+ryLhMF4Gqs/5mlEAi8PSHworqnz+lygIcBL9MwbuEaYgj/oTq+TPDpMwGHnINbrfQQ91tjWiEf2NlWyFcZnV7Ih7g1hStcHCaDVwzs7KUMj00tm7Hw7m4VGZTtkTFFU8bqM0Wy2dezBNjOneOuzUcpMLE2cen7A79dgezP8T/wzZCPr0cRcLvWsY2rKgl7q8f790c9ygqLBQRi8NXlLPoiyxAPFNaCi/Fi5cCi1c3o05TFFCKoVvvNTC9+Ivin2ULLZsk6qO/EFpMOcUA1F4PhDBoOqKHd43scGeozDkW3F10Ms1O2eujeD5FuVzqhFKrtlsYAAfFAi3q1QwNdQ8ZiHYUigm69IoUG+g/+t2T8oM5/D8w/k3n6dPP3nWb+/j9h/pIDZy+LGXTucasbcx+yCXdIerynpwNa3o4IwTrVgshJpOC+S8U0Ki1+BFpk47Naf58WOaehRe6fQIu4AzsdVHpkU3o0WT1efxbuGaUUUZ8Q+vsUSdrmDsVjSFt142Qh8aXZYpU2W+g6yWK2dUAdNwZbvqicASozM9KeWNkddQ3k/OcUElTvnEtRKr1roB2pjI4togWIlOmj/QNO2Z/1H5BItS8dUqg8mek+mT451J6wKhYsrCE34+8IDTYrhQab/V+hwVKZPhUkLDuRynWHyLDitKQPyVLsCCJmwhiDxKXh1fvAmhiI+kBihIxw0050xMctpGGWG/uV1f12CJ5Q1H7D8/bubx7anNoQmtMsW8ATMGmIa7jFgaVHDo+IMie6BRX3xGwxqVdceCWRQY8eegziMQ5/nhbnsvRxaPApFZoU8aKDMUmMxeF76BPSzITlxP/X2vXHNnHd8Xv3y2eff5zjOLbjOE5im/wkjn0U4vCjaF0rUamlJe1YU9Fmgo7RVC2ryNo1rOvG6NJJSBNSNzTGWmmINX+s9WG30HRT41BooRoSUtcxdYOxomURUyuUTRMqcfa+77272MEOMBrJL3e5vDvf9/t9733f933f5+N0+WrrGiKx0jRxVP0SBYckG+tofongWxFmfC01FjvaPNA98UPq+rUPBgtP9+25742xNIG539Pl7zdx7pdspjD36NV+YQqdmz2xvK94aI5A3T9RHGRY95P/vfcOskeT2sxbJPYV4dZTBLlsWDfqcPOpT19jRI2WEUWZER1WoD+8KUNidl7NltCzzNYrW9M+GtjgAS/N9qJ0HPcECe63jDnWg23Jb4L1A6ah4TC5NVuE6bzq9os0/wQg+xdS6pm+ZFBZANDv6XZnoxpAbTcqVyTIo3fA3jQtp3oA3NINpQAI/EGLawytdQD7tdsTLCUkY1sGaJZmXaBk3x0JEpr5mhTkddfqXvTwZytf+qqwumzTzdWjG7+75pPP/tO961c925ZNpbYs++lUB78W9aB6tNJpZxtxHCq6H4kXP1YU8Uc2+9QZOjcfnrskHxTv5ZrxTKYXuOsB4RK6y4RA4NnB7846dKMLny5P51OeKMgrBfLKJI0+Jq8jM7eXyqsFCyNJFg9akubiAT2iDlkiSrnIPF7Dj8cPoyvFwHp9K6gcqi66LPDAE2YAdVjUUdtHTx7sXH9q68RYR2h2R2TwBw++sjK1tvD89te67jk98l7hcuLBXc8cbRHjG3/4zJFm/nMB/V4Krv/2/QexZ4441Dr06De2FWf+NDJWICHVrZsGt6C+fx35I3bO8mf/cehbcv3Iy2MgM5qf5eTsHOSo/bJChhZglrt1PBZOZz3YS6+pnq7l+9LStQwbeGkOwuNTgYLW3HlTmrylWPtvStO3ltP2hNDd4kVhr3SJU7hOwq8q6XmegQTZYeDMixSfyWFClhMdWgM7uns+MHrRGrLxfV3iBeFtaQaP2es5YGaS8UxZk11YMIJEdroS7Cc6U/ZpEJHOO+hMGbYd230WwKTmIj2MIcgMh6bSfhHkqhS2+qJs8lmKL8eVw8fdwrVpflTihRi+FliIWVeCVDfdJlxu40f37yey4fhRWV20DgEt49Lin1O0EuKOC1d54IySuCaoA0pSRBNAB5CcgAXWxh6I3Qvb8cTfH3khLlw9irYUf3aYo/eYZfdILLwHT0LShOFV4Mk6AOmxYLp4fGfrZOvfhFm08b1C8RDgCZ2YQwjYTEvuY1/sPmQSLfQ92VNY+tEcsl0+X5wi/j9+J2Ez+T4q10OsT9bZlyLYZiRUnrdTAwQ31052FcmZjPWWesm7Plv2xtZ7w3NmhSH2nHXlzyEP4a14vMll6WLf3xDlDKMHzNrB/FgbUDKmdHTfvIw+LZOUKS9+7uScl9+A6PNvq/D8ai85/ywqQfqsFc+1FhLnT+5M4PJzdOfk0aKB7hnHJdFxgQ/wDwgXcK+V5LJqMi8S3bBfjEQsrzgBTxvIwwyFM7VUDlRUcNZ8f+CBh7zO2u893D/A/3XVpqGnv7bq0a3bsdVCvmc/d6p8T6EhKrBTzzFtSABaR+GlHQT93/S/KVAVdcTNPWlWBEMmnQCJnZdGMigGtM383Nn2bts5/PkQf06RH8Bl5/bxOwimZR1nIrGKFLvPTlsEw7d8oQKqJa4fxfVrCJ5SI8dWrfI2Wh/mCzZLRBbWUrQirhLIfwDPVTZj/6Qd9XGEbBnyGqIUZtvB00BXnkNLHIC3HGJ4yw3t6XReEskfhaCJ/eeHDY8dSZOIds2JmZ+QWUk7dkyUCQlWadxAAez+TSFHXZYmfKUFX0kkrgAepZRt13J8OyD9CaSUoRxf8/7MHojB5GxwSohU/A21wDtIyhCU465EYRMJ1DRpueamFuw0J7RcPBHDLjKuVhKowRdLzvB/gF/8pq22JdYcN70iDVi3a/3BUENLrL2pOZ7oXvBDXQavxCZK2M5XABUndRRMKk4G+kz9BRv1FAYad4d3R3cLy9CqvyzbntGTj92283SziI5Fi6vD6FhjcXXTjtH0U7ozM5z58FwnurB/dL8Hicjndb+i+c6MefH5Lya93gMeDSXOcDyKCz8X/yllsS0FEGPcztkdLnc8oOc5kmthiDZQTBCA3fISHcEk0nXkA/QsQIha8h46npmBmZMzL1OsJrlbytoA2KyNAJsBL+fzJjWuhMd/0Qi0Yf3VTYwXxH//mmrWgTWrThj+9iug8fkaGq7hwjU8HfhebotZUs1qWs6rubC2cFlCTrxWlWRF9Wh4xloXKJuuqKLN7lBdbriycLISUKBL4kkSjeH04d8eYLpgA1WMpIz7AjCp9bUKQCOI4hp6TPvxwMDA6aGn7pI/3Tb00B3yH5Lr5LukRzZsKGbQ+8UMHyru5NGLs1PoPr74OmBKQPuBIHGv2Atjbcrb7IXjLz4A3jb89yjhkA0D5xlZtwsEw7BuB0yyOdEXqsc6KieTFQnAGyOTBbUEcXMO48OwRlA962G3bLokGHAty2zJhOAW6WaNcBASZzx+2Cdj1IcI9ewNc9ACDOeWdw5EDgSXXDrSN7LuKx1PZL75XG3wWOTYO2jw7ORZ4bW9w5O/a4q86m98/PHhvVe/DgvCNM72EpbdJ0x2H18ruwUsvGrSCNXreq5WVdxkKfS6MryOANlE65YFmA0SdsAwCLFWJSsdTHiLiA33+9Xoe9E+wjd5DYsvI6AUQG7yu0RuSU5Ht1PJ5QPBZI8eZwzGb4q+hs5UmlleDtWFuuMBML5sqw5kxrjbJzmY5eJL4sOkBqvvho4PdQ2Wh4w0PoylrTzNasL8jglDHJnAN8l23LCJ4jq5UDACTAxQ4sq5zmQHPu2GElISayIdZuyCKCHUEClHEyYKCRJCOYiRJr3YlVBpTFDvwdbd1Lq0y1KM4YwT58lQY5lFLbu6xVdV3fh1mkK5Rqu2DaJj24il495KOs6BjitoOG5q2FCl6cOxVDqdvill/z+avrG29GVq+rACqgZd55iqsz012aWZrO7F6u6K0U1/N63cxdrl+ZtssBVb8P8AopegLAAAAHjaY2BkYGAA4il/X0+P57f5yiDPwQAC5xYuD4TR/1X/CbK3sfcwMDFwADEQAAB6Dg0JAAB42mNgZGDgKP67loGBvee/6r8j7G0MKQyiDMjgNQCjQAeRAAB42m2TT0hUURTGv3vueW9sIWaGuKiM1IxADUYGSYXSTMkWKTGUkWQoJFaCWCC0sFGyycIMtVzlQhHCP7vahGLmYCD9UVFyZYSLKQmnhdRiup03jjCUD35899z7zuG8871L6zgFedQasK20CxXkwySPopgLUW+1YJ3H4VEXMU0d6KNH5oEuwgAXo0m1mUFKRD4loERnmEE+jntcqE5I3lHhgpAudApPhGWh2onVJk6rP2ZJf0Ql56NLb+Ck7kfAHkMLb5o5/gQvT0itkGidUAOvtQ93rSp46Qgucway2IcC3gOv3Sdnsm+lwseLUf0tOV24xrWYt/ZKnQW8tfuxwtMmzC/wgz1IoyQk6EPYpCTTrzPRoptML9UhxOnSUxncDFwVrdFh1NEA/FyKPGdfbaBIhU2GXkWus7Y7kBt5vwy1XGZWnRwahlv/xHkaQZfEt/UcnlojGNdzJii8ljiOenBOBeGhHjNqJaPVmb0KmiAfQLP0nWVV4DB3o0F9MYafm196VmVan9Gmr2BJd+MGZ2PImb3stesOZdN7lcJx4oMHw7oAAWpGWPr5pl9ijCy8UWtmnpIV6UZ8l3y3taJ22xVqv92JRT2JlMjcd8AVb56JF70RH2JwfIjFSkBV1Ifuf5G+SkXTxIueWCJe3EQJ30G2zP3STtiVOCheXBcfGmNRIRTEwvU4G/Wh8T/KUS9aLtyPxfGCq2VGoq4ctNlTuOX0pIfUGT2o4nUAcD0EtpXaxaOvQtEWCIn6RBvkzLkHUawcBO1EBdWHmS1MgD5ghpaFCfOOejElnpc4uVSKViHVqSvfWcWvVDrnydot/9Nj+O0F+F3H4P8LzvvyYQB42mNgYNCBwyqGO4xmjCeYFjErMccwtzCvYX7AYseSwFLHsohlF6sWaxrrLjYdthXsRux7OCQ4Gjh5OEM413Ge4HzDxcZVx23EncH9iaeG5xevF+8kPju+VXw3+K34p/GfEggSWCfoJLhKyE9YQXif8A+RPJFZIo9ERUQLRBeI3hLjEfMSKxLrEVslniOhJrFHskTynVSKtJ30ORkxmTKZa7JcsofkTOSmyTvJf1NwU3ikWKT4SUlOKU1pmtI9ZRHlWcrnVIJUVqmsUmVQ3aRmp7ZB3UJ9moaPRo2miuYWzRtaTFoK2hLaZtpV2s90rHRW6VzQTdDt0V2n+0ZPR2+a3j79AgMmgweGUYbzDJ8Y6RmtMPphnGR8x6TA5ISpkmmD6RMzNbMUszVmP8zbLLQsllgqWC6wCrG6ZfXLepYNl02DzQ/bCtt7dh52++xj7P85LHNsctJz+uY8yUXJpcblhquF6xzXW25ibjFuK9xN3B94hHic8fTw/OJV4nXMu8r7l0+DL5/vHN93ftv8RfzXBXgE7Al4EWiEAzoE+gXGBJYFTgjcFHgt8FeQXlBe0JKga8FyQGgXnBKcEuISyhIqELouzCvcJkILAFFJmWgAAAABAAAA6wBGAAUAAAAAAAIAAQACABYAAAEAAT8AAAAAeNpdkU1LAkEYx/+jZkgWFGnQaU+dbF0tCQyiiApBPJglQR12dU1J3VjHopPn6FN1K/oAHfoInfoG/Xd2fN1hZn7P+7PPAEiJCASCb/YMdSFHFYUcQ2rCcd5pWkUsQekIW5oFva40R2i50Ryd4RjXmJeQwZ3mOCNeNS/jGG+aE0jiS/MKNvGtOYkd/Gpexa1Y17yGmuhp3sC2eNf8gbT40fwJS/yNqp7jSc8oSbvbaRh112l5fTnCOTz0IWGgCZu3TWpQ94gX+OjgHm1lvaDOo9SFSykPCzmeJkZqX1PrY0D/IJtBm8ltKa997sNJzB69q/RyuCW3wZgBz6CuZA6bfbjo8fbxQJ2H1kJ1c06atwSd93DKnn2VV/K0VUdhzaBLSX3QZZm2BjV9yi6rGhiSm8on6KWt/vSEk7DpF0rzMRlqFv88mImlZiYZWUSW61ktk3mmuUz6++w7y85ncw6oKaPEfzhDBZc8d3XO+amV1FuFsXXGOZzT+CVzyr/GOkNKFeqfeBs4ULYCu8rzHYp8mcL0Xf4Bm9BuWQAAAHjabdBHbFNBEMbx/ySOnTi990Lv4Pdsp9BtbEPovbdAEtshJMHBQGgB0atASNxAoVwA0atAwAEQvYki4MCZLg6BKzh6y42VVj99s9rRaIiCP+2RW0c1/ztfQaIkWkxEYyIGMxZiicNKPAkkkkQyKaSSRjoZZJJFNjnkkkc+BRRSRDEldKIzXehKN7rTg570ojd96Es/+jMAGxo6dhw4KaWMcioYyCAGM4ShDGM4LtyMwIMXHyMZRSWjGcNYxjGeCUxkEpOZwlSmMZ0ZzGQWs5nDXOYxnwUspEpiOMZmtnCTg3xiK3vZxSFOcFzM7OQDmzggFollj8SxnTt8FCuHOckv2vnNUU7zkPucYRGL2RfZ1WNqeMAjnvOEpzzjM7W84gUvOYufn+znLa95QyCywe/soI4gS1hKPQ200cgymgjRTJjlrGAlX1jFalpYwzrWco0jtLKeDWzkGz+4zjnOc4N3vJd4SZBESZJkSZFUSZN0yZBMyZJsyeECF7nCVe5yicvcYxunJJdb3JY8yWe3FEihFEmxlJj99S1NAc0SbgjabDaPEe1GdNmUHkO3rlTvbqeyokM98l+pKXWlXelQOpWlyjJlufJfP5ehpvpqmrU26A+HaqqrmgNGSfcZOn0mbzjU2BG8ag6f25gjoq60Kx1/AbYSozsAAHjaRc09D8FQGAXg3n6XVkvLJmq+EiKEwahduoipTexWg5gtRn7LW5P4c5xwvbbznJzkPMTrQuKqFeRuylqIW1XntiyHFFUFJVuEc9UnW+5KjYw0I0OuyUyzu3HQ5QcWYP5gA9ZRwQHslYILOCMFD3BThQbgDb4Q1FQfPtrmWJe1kZ/AAPT/bIHBnhmCrSUzAsMFs51mTy0SpsZNB4P2nBmDnRkzAeMpswsmE2YP7DIrSuQbgAdZ/QAAAVJ79tEAAA==\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Italic-webfont.woff\n ** module id = 487\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Medium-webfont.woff\n ** module id = 488\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-MediumItalic-webfont.woff\n ** module id = 489\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Bold-webfont.woff\n ** module id = 490\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-BoldItalic-webfont.woff\n ** module id = 491\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-Black-webfont.woff\n ** module id = 492\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/Roboto-BlackItalic-webfont.woff\n ** module id = 493\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/RobotoCondensed-Light-webfont.woff\n ** module id = 494\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/RobotoCondensed-LightItalic-webfont.woff\n ** module id = 495\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/RobotoCondensed-Regular-webfont.woff\n ** module id = 496\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/RobotoCondensed-Italic-webfont.woff\n ** module id = 497\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/RobotoCondensed-Bold-webfont.woff\n ** module id = 498\n ** module chunks = 0\n **/","module.exports = \"data:application/font-woff;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/assets/RobotoCondensed-BoldItalic-webfont.woff\n ** module id = 499\n ** module chunks = 0\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\n\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport GraphDescriptorModel from './GraphDescriptorModel'\n\nexport default class GraphNetworkService extends GraphDescriptorModel{\n\n\tconstructor(graph, props) {\n\t\tsuper(graph, DescriptorModelFactory.NetworkService, props);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphNetworkService.js\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\n\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport GraphDescriptorModel from './GraphDescriptorModel'\n\nexport default class GraphForwardingGraph extends GraphDescriptorModel {\n\n\tconstructor(graph, props) {\n\t\tsuper(graph, DescriptorModelFactory.ForwardingGraph, props);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphForwardingGraph.js\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\n\nimport d3 from 'd3'\nimport SelectionManager from '../SelectionManager.js'\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport DescriptorGraphSelection from './DescriptorGraphSelection'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\nimport GraphVirtualNetworkFunction from './GraphVirtualNetworkFunction'\nimport GraphDescriptorModel from './GraphDescriptorModel'\n\nexport default class GraphConstituentVnfd extends GraphDescriptorModel {\n\n\tconstructor(graph, props) {\n\t\tsuper(graph, DescriptorModelFactory.ConstituentVnfd, props);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphConstituentVnfd.js\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport GraphDescriptorModel from './GraphDescriptorModel'\n\nexport default class GraphVirtualNetworkFunction extends GraphDescriptorModel {\n\n\tconstructor(graph, props) {\n\t\tsuper(graph, DescriptorModelFactory.VirtualNetworkFunction, props);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphVirtualNetworkFunction.js\n **/","/**\n * Created by onvelocity on 2/11/16.\n */\n'use strict';\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\nimport GraphDescriptorModel from './GraphDescriptorModel'\n\nexport default class GraphVirtualDeploymentUnit extends GraphDescriptorModel {\n\n\tconstructor(graph, props) {\n\t\tsuper(graph, DescriptorModelFactory.VirtualDeploymentUnit, props);\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphVirtualDeploymentUnit.js\n **/","/**\n * Created by onvelocity on 2/10/16.\n */\n\nimport math from './math'\nimport PathBuilder from './PathBuilder'\nimport DescriptorModelFactory from '../model/DescriptorModelFactory'\n\nimport '../../styles/GraphRecordServicePaths.scss'\n\nexport default class GraphRecordServicePath {\n\n\tconstructor(graph, props) {\n\t\tthis.graph = graph;\n\t\tthis.props = props;\n\t\tthis.containers = [];\n\t\tthis.networkMap = new WeakMap();\n\t\tthis.networkMap.set(this, {networkMap: {}});\n\n\t}\n\n\tgetNetwork(key) {\n\t\treturn this.networkMap.get(this).networkMap[key];\n\t}\n\n\tputNetwork(item) {\n\t\tthis.networkMap.get(this).networkMap[item.key + item.type] = item;\n\t}\n\n\taddContainers(containers) {\n\n\t\tcontainers.filter(d => {\n\t\t\tif (DescriptorModelFactory.isRecordServicePath(d)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (DescriptorModelFactory.isRspConnectionPointRef(d)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (DescriptorModelFactory.isConnectionPoint(d)) {\n\t\t\t\tthis.putNetwork(d);\n\t\t\t}\n\t\t\tif (DescriptorModelFactory.isVnfdConnectionPointRef(d)) {\n\t\t\t\tthis.putNetwork(d)\n\t\t\t}\n\t\t}).forEach(d => this.containers.push(d));\n\n\t}\n\n\trender() {\n\n\t\tconst pathsGroup = this.graph.forwardingGraphPaths;\n\n\t\tconst path = pathsGroup.selectAll('.rsp-path').data(this.containers, DescriptorModelFactory.containerIdentity);\n\n\t\tpath.enter().append('path');\n\n\t\tpath.attr({\n\t\t\t'class': 'rsp-path',\n\t\t\t'stroke': rsp => rsp.parent.colors.primary,\n\t\t\td: (rsp, rspIndex) => {\n\n\t\t\t\tif (!rsp.meta.showPath) {\n\t\t\t\t\treturn '';\n\t\t\t\t}\n\n\t\t\t\tconst cpList = rsp.connectionPoints.filter(d => d);\n\t\t\t\tconst cpCount = rsp.connectionPoints.length - 1;\n\n\t\t\t\tconst path = new PathBuilder();\n\n\t\t\t\tconst pathOffset = 20 * rspIndex;\n\n\t\t\t\treturn rsp.connectionPoints.reduce((r, cpRef, cpRefIndex) => {\n\n\t\t\t\t\tconst cp = this.getNetwork(cpRef.key + 'connection-point');\n\t\t\t\t\tconst point = cp.position.centerPoint();\n\t\t\t\t\tconst vnfdCpRef = this.getNetwork(cp.key + 'vnfd-connection-point-ref');\n\n\t\t\t\t\tif (path.length === 0) {\n\t\t\t\t\t\tpath.M(point.x, point.y, {container: cp});\n\t\t\t\t\t} else if (cpRefIndex === 1) {\n\n\t\t\t\t\t\tconst last = path.last();\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//const previousContainer = path.findPrevious(d => d.info.container);\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//let distance = 200;\n\n\t\t\t\t\t\t//if (previousContainer) {\n\t\t\t\t\t\t//\tdistance = math.distanceBetweenPositions(previousContainer.info.container.position, cp.position);\n\t\t\t\t\t\t//}\n\n\t\t\t\t\t\tif (last.cmd === 'M') {\n\t\t\t\t\t\t\tpath.C(last.x + 100 + pathOffset, last.y - 100 - pathOffset, point.x - 100 - pathOffset, point.y - 100 - pathOffset, point.x, point.y);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpath.S(point.x - 100, point.y - 100, point.x, point.y);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t//const last = path.last();\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//const previousContainer = path.findPrevious(d => d.info.container);\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//let distance = 200;\n\n\t\t\t\t\t\t//if (previousContainer) {\n\t\t\t\t\t\t//\tdistance = math.distanceBetweenPositions(previousContainer.info.container.position, cp.position);\n\t\t\t\t\t\t//}\n\n\t\t\t\t\t\tpath.S(point.x - 100 - pathOffset, point.y - 100 - pathOffset, point.x, point.y);\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\tif (cpRefIndex < cpCount && vnfdCpRef) {\n\n\t\t\t\t\t\tconst nextVnfdCpRef = this.getNetwork(cpList[cpRefIndex + 1].key + 'vnfd-connection-point-ref');\n\n\t\t\t\t\t\tif (nextVnfdCpRef) {\n\n\t\t\t\t\t\t\tconst cpsOnSameVnfd = nextVnfdCpRef && nextVnfdCpRef.key === vnfdCpRef.key;\n\t\t\t\t\t\t\tconst cpsOnSameVld = nextVnfdCpRef.parent.key === vnfdCpRef.parent.key;\n\n\t\t\t\t\t\t\tif (cpsOnSameVld) {\n\n\t\t\t\t\t\t\t\tconst vldCenter = vnfdCpRef.parent.position.centerPoint();\n\n\t\t\t\t\t\t\t\tconst last = path.last();\n\n\t\t\t\t\t\t\t\tif (last.cmd === 'M') {\n\t\t\t\t\t\t\t\t\tpath.C(last.x, last.y + 40 + pathOffset, vldCenter.x, vldCenter.y - 40 - pathOffset, vldCenter.x, vldCenter.y);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tpath.S(vldCenter.x, vldCenter.y - 40 - pathOffset, vldCenter.x, vldCenter.y);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t//const distance = math.distanceBetweenPositions(cp.position, vnfdCpRef.parent.position);\n\n\t\t\t\t\t\t\t} else if (cpsOnSameVnfd) {\n\n\t\t\t\t\t\t\t\tconst last = path.last();\n\n\t\t\t\t\t\t\t\tconst vldCenter = vnfdCpRef.parent.position.centerPoint();\n\n\t\t\t\t\t\t\t\tif (last.cmd === 'M') {\n\t\t\t\t\t\t\t\t\tpath.C(last.x, last.y + 40, vldCenter.x, vldCenter.y - 40, vldCenter.x, vldCenter.y);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tpath.S(vldCenter.x, vldCenter.y - 40, vldCenter.x, vldCenter.y);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn path.toString();\n\n\t\t\t\t}, '')\n\t\t\t}\n\n\t\t});\n\n\t\tpath.exit().remove();\n\n\t}\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/graph/GraphRecordServicePath.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphRecordServicePaths.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphRecordServicePaths.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./GraphRecordServicePaths.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/GraphRecordServicePaths.scss\n ** module id = 506\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".forwarding-graph-paths path.rsp-path {\\n  fill: transparent;\\n  stroke-width: 2px;\\n  shape-rendering: geometricPrecision;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/GraphRecordServicePaths.scss\n ** module id = 507\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport d3 from 'd3'\nimport alt from '../alt'\nimport UID from '../libraries/UniqueId'\nimport DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'\nimport PanelResizeAction from '../actions/PanelResizeAction'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport CanvasEditorActions from '../actions/CanvasEditorActions'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport CatalogFilterActions from '../actions/CatalogFilterActions'\nimport CanvasPanelTrayActions from '../actions/CanvasPanelTrayActions'\nimport SelectionManager from '../libraries/SelectionManager'\nimport CatalogDataStore from '../stores/CatalogDataStore'\n\n/* the top and bottom positions are managed by css; requires div to be display: absolute*/\nconst defaults = {\n\tleft: 300,\n\tright: 300,\n\tbottom: 25,\n\tshowMore: false,\n\tzoom: 100,\n\tfilterCatalogBy: 'nsd',\n\tdefaultPanelTrayOpenZoom: (() => {\n\t\tlet zoom = parseFloat(window.localStorage.getItem('panel-tray-zoom-default'));\n\t\tif (isNaN(zoom)) {\n\t\t\tzoom = 75;\n\t\t}\n\t\tzoom = Math.min(100, zoom);\n\t\tzoom = Math.max(25, zoom);\n\t\twindow.localStorage.setItem('panel-tray-zoom-default', zoom);\n\t\treturn zoom;\n\t})()\n};\n\nconst autoZoomCanvasScale = d3.scale.linear().domain([0, 300]).range([100, 50]).clamp(true);\n\nclass ComposerAppStore {\n\n\tconstructor() {\n\t\t// the catalog item currently being edited in the composer\n\t\tthis.item = null;\n\t\t// the left and right sides of the canvas area\n\t\tthis.layout = {\n\t\t\tleft: defaults.left,\n\t\t\tright: defaults.right,\n\t\t\tbottom: defaults.bottom\n\t\t};\n\t\tthis.zoom = defaults.zoom;\n\t\tthis.showMore = defaults.showMore;\n\t\tthis.filterCatalogByTypeValue = defaults.filterCatalogBy;\n\t\t// transient ui state\n\t\tthis.drag = null;\n\t\tthis.message = '';\n\t\tthis.messageType = '';\n\t\tthis.showJSONViewer = false;\n\t\tthis.showClassifiers = {};\n\t\tthis.editPathsMode = false;\n\t\tthis.bindListeners({\n\t\t\tonResize: PanelResizeAction.RESIZE,\n\t\t\teditCatalogItem: CatalogItemsActions.EDIT_CATALOG_ITEM,\n\t\t\tcatalogItemMetaDataChanged: CatalogItemsActions.CATALOG_ITEM_META_DATA_CHANGED,\n\t\t\tcatalogItemDescriptorChanged: CatalogItemsActions.CATALOG_ITEM_DESCRIPTOR_CHANGED,\n\t\t\ttoggleShowMoreInfo: CanvasEditorActions.TOGGLE_SHOW_MORE_INFO,\n\t\t\tshowMoreInfo: CanvasEditorActions.SHOW_MORE_INFO,\n\t\t\tshowLessInfo: CanvasEditorActions.SHOW_LESS_INFO,\n\t\t\tapplyDefaultLayout: CanvasEditorActions.APPLY_DEFAULT_LAYOUT,\n\t\t\taddVirtualLinkDescriptor: CanvasEditorActions.ADD_VIRTUAL_LINK_DESCRIPTOR,\n\t\t\taddForwardingGraphDescriptor: CanvasEditorActions.ADD_FORWARDING_GRAPH_DESCRIPTOR,\n\t\t\tselectModel: ComposerAppActions.SELECT_MODEL,\n\t\t\toutlineModel: ComposerAppActions.OUTLINE_MODEL,\n\t\t\tshowError: ComposerAppActions.SHOW_ERROR,\n\t\t\tclearError: ComposerAppActions.CLEAR_ERROR,\n\t\t\tsetDragState: ComposerAppActions.SET_DRAG_STATE,\n\t\t\tfilterCatalogByType: CatalogFilterActions.FILTER_BY_TYPE,\n\t\t\tsetCanvasZoom: CanvasEditorActions.SET_CANVAS_ZOOM,\n\t\t\tshowJsonViewer: ComposerAppActions.SHOW_JSON_VIEWER,\n\t\t\tcloseJsonViewer: ComposerAppActions.CLOSE_JSON_VIEWER,\n\t\t\ttoggleCanvasPanelTray: CanvasPanelTrayActions.TOGGLE_OPEN_CLOSE,\n\t\t\topenCanvasPanelTray: CanvasPanelTrayActions.OPEN,\n\t\t\tcloseCanvasPanelTray: CanvasPanelTrayActions.CLOSE\n\t\t});\n\t}\n\n\tonResize(e) {\n\t\tif (e.type === 'resize-manager.resize.catalog-panel') {\n\t\t\tconst layout = Object.assign({}, this.layout);\n\t\t\tlayout.left = Math.max(0, layout.left - e.moved.x);\n\t\t\tif (layout.left !== this.layout.left) {\n\t\t\t\tthis.setState({layout: layout});\n\t\t\t}\n\t\t} else if (e.type === 'resize-manager.resize.details-panel') {\n\t\t\tconst layout = Object.assign({}, this.layout);\n\t\t\tlayout.right = Math.max(0, layout.right + e.moved.x);\n\t\t\tif (layout.right !== this.layout.right) {\n\t\t\t\tthis.setState({layout: layout});\n\t\t\t}\n\t\t} else if (/^resize-manager\\.resize\\.canvas-panel-tray/.test(e.type)) {\n\t\t\tconst layout = Object.assign({}, this.layout);\n\t\t\tlayout.bottom = Math.max(25, layout.bottom + e.moved.y);\n\t\t\tif (layout.bottom !== this.layout.bottom) {\n\t\t\t\tconst zoom = autoZoomCanvasScale(layout.bottom) ;\n\t\t\t\tif (this.zoom !== zoom) {\n\t\t\t\t\tthis.setState({layout: layout, zoom: zoom});\n\t\t\t\t} else {\n\t\t\t\t\tthis.setState({layout: layout});\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (e.type !== 'resize') {\n\t\t\tconsole.log('no resize handler for ', e.type, '. Do you need to add a handler in ComposerAppStore::onResize()?')\n\t\t}\n\t}\n\n\tupdateItem(item) {\n\t\tif(!document.body.classList.contains('resizing')) {\n\t\t\tthis.setState({item: _.cloneDeep(item)});\n\t\t}\n\t}\n\n\teditCatalogItem(item) {\n\t\tif (item && item.meta) {\n\t\t\titem.meta.isOpenForEdit = true;\n\t\t}\n\t\tSelectionManager.select(item);\n\t\tthis.updateItem(item);\n\t}\n\n\tcatalogItemMetaDataChanged(item) {\n\t\tif (item && item.meta) {\n\t\t\titem.meta.modified = true;\n\t\t}\n\t\tthis.updateItem(item);\n\t}\n\n\tcatalogItemDescriptorChanged(itemDescriptor) {\n\t\tthis.catalogItemMetaDataChanged(itemDescriptor.model);\n\t}\n\n\tshowMoreInfo() {\n\t\tthis.setState({showMore: true});\n\t}\n\n\tshowLessInfo() {\n\t\tthis.setState({showMore: false});\n\t}\n\n\tshowError(data) {\n\t\tthis.setState({message: data.errorMessage, messageType: 'error'});\n\t}\n\n\tclearError() {\n\t\tthis.setState({message: '', messageType: ''});\n\t}\n\n\ttoggleShowMoreInfo() {\n\t\tthis.setState({showMore: !this.showMore});\n\t}\n\n\tapplyDefaultLayout() {\n\t\tif (this.item && this.item.meta && this.item.meta.containerPositionMap) {\n\t\t\tif (!_.isEmpty(this.item.meta.containerPositionMap)) {\n\t\t\t\tthis.item.meta.containerPositionMap = {};\n\t\t\t\tCatalogItemsActions.catalogItemMetaDataChanged.defer(this.item);\n\t\t\t}\n\t\t}\n\t}\n\n\taddVirtualLinkDescriptor(dropCoordinates = null) {\n\t\tif (this.item && this.item.meta.type === 'nsd') {\n\t\t\tconst nsdc = DescriptorModelFactory.newNetworkService(this.item);\n\t\t\tconst vldc = nsdc.createVld();\n\t\t\tvldc.meta.dropCoordinates = dropCoordinates;\n\t\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\t\tSelectionManager.addSelection(vldc);\n\t\t\tthis.updateItem(nsdc.model);\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged.defer(nsdc);\n\t\t}\n\t}\n\n\taddForwardingGraphDescriptor(dropCoordinates = null) {\n\t\tif (this.item && this.item.meta.type === 'nsd') {\n\t\t\tconst nsdc = DescriptorModelFactory.newNetworkService(this.item);\n\t\t\tconst fg = nsdc.createVnffgd();\n\t\t\tfg.meta.dropCoordinates = dropCoordinates;\n\t\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\t\tSelectionManager.addSelection(fg);\n\t\t\tthis.updateItem(nsdc.model);\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged.defer(nsdc);\n\t\t}\n\t}\n\n\tselectModel(container) {\n\t\tif (SelectionManager.select(container)) {\n\t\t\tconst model = DescriptorModelFactory.isContainer(container) ? container.getRoot().model : container;\n\t\t\tthis.catalogItemMetaDataChanged(model);\n\t\t}\n\t}\n\n\toutlineModel(obj) {\n\t\tconst uid = UID.from(obj);\n\t\trequestAnimationFrame(() => {\n\t\t\tSelectionManager.outline(Array.from(document.querySelectorAll(`[data-uid=\"${uid}\"]`)));\n\t\t});\n\t}\n\n\tclearSelection() {\n\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\tthis.catalogItemMetaDataChanged(this.item);\n\t}\n\n\tsetDragState(dragState) {\n\t\tthis.setState({drag: dragState});\n\t}\n\n\tfilterCatalogByType(typeValue) {\n\t\tthis.setState({filterCatalogByTypeValue: typeValue})\n\t}\n\n\tsetCanvasZoom(zoom) {\n\t\tthis.setState({zoom: zoom});\n\t}\n\n\tshowJsonViewer() {\n\t\tthis.setState({showJSONViewer: true});\n\t}\n\n\tcloseJsonViewer() {\n\t\tthis.setState({showJSONViewer: false});\n\t}\n\n\ttoggleCanvasPanelTray() {\n\t\tconst layout = this.layout;\n\t\tif (layout.bottom > 25) {\n\t\t\tthis.closeCanvasPanelTray();\n\t\t} else {\n\t\t\tthis.openCanvasPanelTray();\n\t\t}\n\t}\n\n\topenCanvasPanelTray() {\n\t\tconst layout = {\n\t\t\tleft: this.layout.left,\n\t\t\tright: this.layout.right,\n\t\t\tbottom: 300\n\t\t};\n\t\tconst zoom = defaults.defaultPanelTrayOpenZoom;\n\t\tif (this.zoom !== zoom) {\n\t\t\tthis.setState({layout: layout, zoom: zoom, restoreZoom: this.zoom});\n\t\t} else {\n\t\t\tthis.setState({layout: layout});\n\t\t}\n\t}\n\n\tcloseCanvasPanelTray() {\n\t\tconst layout = {\n\t\t\tleft: this.layout.left,\n\t\t\tright: this.layout.right,\n\t\t\tbottom: 25\n\t\t};\n\t\tconst zoom = this.restoreZoom || autoZoomCanvasScale(layout.bottom);\n\t\tif (this.zoom !== zoom) {\n\t\t\tthis.setState({layout: layout, zoom: zoom, restoreZoom: null});\n\t\t} else {\n\t\t\tthis.setState({layout: layout, restoreZoom: null});\n\t\t}\n\t}\n\n}\n\nexport default alt.createStore(ComposerAppStore, 'ComposerAppStore');\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/stores/ComposerAppStore.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/11/15.\n */\nimport alt from '../alt';\nimport changeCase from 'change-case'\n\n/*\n This class manages Composer Layout State\n */\n\nconst cleanNameRegExp = /(-is-tray-open|panel-)/i;\n\nclass PanelResizeAction {\n\n\tresize(e) {\n\n\t\t/* we expect two types of resize events:\n\t\t * window resize - invoked by window\n\t\t * resize-manager resize - invoked by ResizeManager\n\t\t *\n\t\t * normalize the data needed by the Composer Layout or ignore invalid ones\n\t\t *\n\t\t * */\n\n\t\tif (!e) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (e.detail && e.detail.side) {\n\t\t\t// a ResizeManager event\n\t\t\tthis.dispatch(PanelResizeAction.buildResizeManagerInfo(e))\n\t\t} else {\n\t\t\t// a window event\n\t\t\tthis.dispatch(PanelResizeAction.buildWindowResizeInfo(e));\n\t\t}\n\n\t}\n\n\tstatic buildWindowResizeInfo(e) {\n\t\treturn e;\n\t}\n\n\tstatic buildResizeManagerInfo(e) {\n\t\tconst info = Object.assign({originalEvent: e}, e.detail);\n\t\tconst name = changeCase.paramCase(info.target.className.replace(cleanNameRegExp, ''));\n\t\tinfo.type = 'resize-manager.resize.' + name;\n\t\treturn info;\n\t}\n\n}\n\nexport default alt.createActions(PanelResizeAction);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/PanelResizeAction.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/14/15.\n */\nimport alt from '../alt';\n\nclass CanvasEditorActions {\n\n\tconstructor() {\n\t\tthis.generateActions('showMoreInfo', 'showLessInfo', 'toggleShowMoreInfo', 'applyDefaultLayout', 'addVirtualLinkDescriptor', 'addForwardingGraphDescriptor', 'setCanvasZoom');\n\t}\n\n}\n\nexport default alt.createActions(CanvasEditorActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CanvasEditorActions.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/11/15.\n */\nimport alt from '../alt';\n\nclass CatalogFilterActions {\n\n\tconstructor() {\n\t\tthis.generateActions('filterByType');\n\t}\n\n}\n\nexport default alt.createActions(CatalogFilterActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CatalogFilterActions.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 2/4/16.\n */\nimport alt from '../alt';\n\nclass CanvasPanelTrayActions {\n\n\tconstructor() {\n\t\tthis.generateActions('open', 'close', 'toggleOpenClose');\n\t}\n\n}\n\nexport default alt.createActions(CanvasPanelTrayActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CanvasPanelTrayActions.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport cc from 'change-case'\nimport alt from '../alt'\nimport UID from '../libraries/UniqueId'\nimport guid from '../libraries/guid'\nimport React from 'react'\nimport DescriptorModel from '../libraries/model/DescriptorModel'\nimport DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'\nimport CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'\nimport CatalogDataSourceActions from '../actions/CatalogDataSourceActions'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport ModalOverlayActions from '../actions/ModalOverlayActions'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport CatalogDataSource from '../sources/CatalogDataSource'\nimport ComposerAppStore from '../stores/ComposerAppStore'\nimport SelectionManager from '../libraries/SelectionManager'\n\nconst defaults = {\n\tcatalogs: []\n};\n\nconst areCatalogItemsMetaDataEqual = function (a, b) {\n\tconst metaProps = ['id', 'name', 'short-name', 'description', 'vendor', 'version'];\n\tconst aMetaData = _.pick(a, metaProps);\n\tconst bMetaData = _.pick(b, metaProps);\n\treturn _.isEqual(aMetaData, bMetaData);\n};\n\nclass CatalogDataStore {\n\n\tconstructor() {\n\t\tthis.catalogs = defaults.catalogs;\n\t\tthis.isLoading = true;\n\t\tthis.requiresSave = false;\n\t\tthis.snapshots = {};\n\t\tthis.registerAsync(CatalogDataSource);\n\t\tthis.bindActions(CatalogDataSourceActions);\n\t\tthis.bindActions(CatalogItemsActions);\n\t}\n\n\tgetCatalogs() {\n\t\treturn this.catalogs || (this.catalogs = []);\n\t}\n\n\tgetAllSelectedCatalogItems() {\n\t\treturn this.getCatalogs().reduce((r, d) => {\n\t\t\td.descriptors.forEach(d => {\n\t\t\t\tif (SelectionManager.isSelected(d) /*d.meta.selected*/) {\n\t\t\t\t\tr.push(d);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn r;\n\t\t}, []);\n\t}\n\n\tgetFirstSelectedCatalogItem() {\n\t\treturn this.getCatalogs().reduce((r, catalog) => {\n\t\t\treturn r.concat(catalog.descriptors.filter(d => SelectionManager.isSelected(d) /*d.meta.selected*/));\n\t\t}, [])[0];\n\t}\n\n\tgetCatalogItemById(id) {\n\t\treturn this.getCatalogs().reduce((r, catalog) => {\n\t\t\treturn r.concat(catalog.descriptors.filter(d => d.id === id));\n\t\t}, [])[0];\n\t}\n\n\tgetCatalogItemByUid(uid) {\n\t\treturn this.getCatalogs().reduce((r, catalog) => {\n\t\t\treturn r.concat(catalog.descriptors.filter(d => UID.from(d) === uid));\n\t\t}, [])[0];\n\t}\n\n\tremoveCatalogItem(deleteItem = {}) {\n\t\tthis.getCatalogs().map(catalog => {\n\t\t\tcatalog.descriptors = catalog.descriptors.filter(d => d.id !== deleteItem.id);\n\t\t\treturn catalog;\n\t\t});\n\t}\n\n\taddNewItemToCatalog(newItem) {\n\t\tconst id = guid();\n\t\tconst type = newItem.meta.type;\n\t\tnewItem.id = id;\n\t\tthis.getCatalogs().filter(d => d.type === type).forEach(catalog => {\n\t\t\tcatalog.descriptors.push(newItem);\n\t\t});\n\t\t// update indexes and integrate new model into catalog\n\t\tthis.updateCatalogIndexes(this.getCatalogs());\n\t\treturn this.getCatalogItemById(id);\n\t}\n\n\tupdateCatalogIndexes(catalogs) {\n\t\t// associate catalog identity with individual descriptors so we can\n\t\t// update the catalog when any given descriptor is updated also add\n\t\t// vnfd model to the nsd object to make it easier to render an nsd\n\t\tconst vnfdLookup = {};\n\t\tconst updatedCatalogs = catalogs.map(catalog => {\n\t\t\tcatalog.descriptors.map(descriptor => {\n\t\t\t\tif (typeof descriptor.meta === 'string') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdescriptor.meta = JSON.parse(descriptor.meta);\n\t\t\t\t\t} catch (ignore) {\n\t\t\t\t\t\tconsole.warn('Unable to deserialize the meta property.');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst meta = descriptor.meta || (descriptor.meta = {});\n\t\t\t\tmeta.catalogId = catalog.id;\n\t\t\t\tmeta.catalogName = catalog.name;\n\t\t\t\tmeta.type = catalog.type;\n\t\t\t\tif (!UID.hasUniqueId(meta)) {\n\t\t\t\t\tUID.assignUniqueId(meta);\n\t\t\t\t}\n\t\t\t\tif (catalog.type === 'vnfd') {\n\t\t\t\t\tvnfdLookup[descriptor.id] = descriptor;\n\t\t\t\t}\n\t\t\t\treturn descriptor;\n\t\t\t});\n\t\t\treturn catalog;\n\t\t});\n\t\tupdatedCatalogs.filter(d => d.type === 'nsd').forEach(catalog =>  {\n\t\t\tcatalog.descriptors = catalog.descriptors.map(descriptor => {\n\t\t\t\tif (descriptor['constituent-vnfd']) {\n\t\t\t\t\tdescriptor.vnfd = descriptor['constituent-vnfd'].map(d => {\n\t\t\t\t\t\tconst vnfdId = d['vnfd-id-ref'];\n\t\t\t\t\t\tconst vnfd = vnfdLookup[vnfdId];\n\t\t\t\t\t\tif (!vnfd) {\n\t\t\t\t\t\t\tthrow new ReferenceError('no VNFD found in the VNFD Catalog for the constituent-vnfd: ' + d);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// create an instance of this vnfd to carry transient ui state properties\n\t\t\t\t\t\tconst instance = _.cloneDeep(vnfd);\n\t\t\t\t\t\tinstance.meta['member-vnf-index'] = d['member-vnf-index'];\n\t\t\t\t\t\tinstance['vnf-configuration'] = d['vnf-configuration'];\n\t\t\t\t\t\treturn instance;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn descriptor;\n\t\t\t});\n\t\t});\n\t\treturn updatedCatalogs;\n\t}\n\n\tupdateCatalogItem(item) {\n\t\t// replace the given item in the catalog\n\t\tconst catalogs = this.getCatalogs().map(catalog => {\n\t\t\tif (catalog.id === item.meta.catalogId) {\n\t\t\t\tcatalog.descriptors = catalog.descriptors.map(d => {\n\t\t\t\t\tif (d.id === item.id) {\n\t\t\t\t\t\treturn item;\n\t\t\t\t\t}\n\t\t\t\t\treturn d;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn catalog;\n\t\t});\n\t\tthis.setState({catalogs: catalogs});\n\t}\n\n\tmergeEditsIntoLatestFromServer(catalogsFromServer = []) {\n\n\t\t// if the UI has modified items use them instead of the server items\n\n\t\tconst currentData = this.getCatalogs();\n\n\t\tconst modifiedItemsMap = currentData.reduce((result, catalog) => {\n\t\t\treturn result.concat(catalog.descriptors.filter(d => d.meta.modified));\n\t\t}, []).reduce((r, d) => {\n\t\t\tr[d.meta.catalogId + '/' + d.id] = d;\n\t\t\treturn r;\n\t\t}, {});\n\n\t\tconst itemMetaMap = currentData.reduce((result, catalog) => {\n\t\t\treturn result.concat(catalog.descriptors.filter(d => d.meta));\n\t\t}, []).reduce((r, d) => {\n\t\t\tr[d.meta.catalogId + '/' + d.id] = d.meta;\n\t\t\treturn r;\n\t\t}, {});\n\n\t\tconst newItemsMap = currentData.reduce((result, catalog) => {\n\t\t\tresult[catalog.id] = catalog.descriptors.filter(d => d.meta.isNew);\n\t\t\treturn result;\n\t\t}, {});\n\n\t\tcatalogsFromServer.forEach(catalog => {\n\t\t\tcatalog.descriptors = catalog.descriptors.map(d => {\n\t\t\t\tconst key = d.meta.catalogId + '/' + d.id;\n\t\t\t\tif (modifiedItemsMap[key]) {\n\t\t\t\t\t// use local modified item instead of the server item\n\t\t\t\t\treturn modifiedItemsMap[key];\n\t\t\t\t}\n\t\t\t\tif (itemMetaMap[key]) {\n\t\t\t\t\tObject.assign(d.meta, itemMetaMap[key]);\n\t\t\t\t}\n\t\t\t\treturn d;\n\t\t\t});\n\t\t\tif (newItemsMap[catalog.id]) {\n\t\t\t\tcatalog.descriptors = catalog.descriptors.concat(newItemsMap[catalog.id]);\n\t\t\t}\n\t\t});\n\n\t\treturn catalogsFromServer;\n\n\t}\n\n\tloadCatalogsSuccess(context) {\n\t\tconst fromServer = this.updateCatalogIndexes(context.data);\n\t\tconst catalogs = this.mergeEditsIntoLatestFromServer(fromServer);\n\t\tthis.setState({\n\t\t\tcatalogs: catalogs,\n\t\t\tisLoading: false\n\t\t});\n\t}\n\n\tdeleteCatalogItemSuccess (response) {\n\t\tlet catalogType = response.catalogType;\n\t\tlet itemId = response.itemId;\n\t\tconst catalogs = this.getCatalogs().map(catalog => {\n\t\t\tif (catalog.type === catalogType) {\n\t\t\t\tcatalog.descriptors = catalog.descriptors.filter(d => d.id !== itemId);\n\t\t\t}\n\t\t\treturn catalog;\n\t\t});\n\n\t\tthis.setState({catalogs: catalogs});\n\t}\n\n\tdeleteCatalogItemError (data) {\n\t\tconsole.log('Unable to delete', data.catalogType, 'id:', data.itemId, 'Error:', data.error.responseText);\n\t\tComposerAppActions.showError.defer({\n\t\t\terrorMessage: 'Unable to delete ' + data.catalogType + ' id: ' + data.itemId + '. Check if it is in use'\n\t\t});\n\t}\n\n\tselectCatalogItem(item = {}) {\n\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t\tconst catalogs = this.getCatalogs().map(catalog => {\n\t\t\tcatalog.descriptors = catalog.descriptors.map(d => {\n\t\t\t\t// deselect other items and select this one\n\t\t\t\tSelectionManager.updateSelection(d, d.id === item.id);\n\t\t\t\treturn d;\n\t\t\t});\n\t\t\treturn catalog;\n\t\t});\n\t\tthis.setState({catalogs: catalogs});\n\t}\n\n\tcatalogItemMetaDataChanged(item) {\n\t\tlet requiresSave = false;\n\t\tconst catalogs = this.getCatalogs().map(catalog => {\n\t\t\tif (catalog.id === item.meta.catalogId) {\n\t\t\t\tcatalog.descriptors = catalog.descriptors.map(d => {\n\t\t\t\t\tif (d.id === item.id) {\n\t\t\t\t\t\t// compare just the catalog meta data (id, name, short-name, description, etc.)\n\t\t\t\t\t\tconst modified = !areCatalogItemsMetaDataEqual(d, item);\n\t\t\t\t\t\titem.meta.modified = modified;\n\t\t\t\t\t\tif (modified) {\n\t\t\t\t\t\t\trequiresSave = true;\n\t\t\t\t\t\t\tthis.addSnapshot(item);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn item;\n\t\t\t\t\t}\n\t\t\t\t\treturn d;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn catalog;\n\t\t});\n\t\tif (requiresSave) {\n\t\t\tthis.setState({catalogs: catalogs, requiresSave: true});\n\t\t}\n\t}\n\n\tcatalogItemDescriptorChanged(itemDescriptor) {\n\t\t// when a descriptor object is modified in the canvas we have to update the catalog\n\t\tconst catalogId = itemDescriptor.meta.catalogId;\n\t\tconst catalogs = this.getCatalogs().map(catalog => {\n\t\t\tif (catalog.id === catalogId) {\n\t\t\t\t// find the catalog\n\t\t\t\tconst descriptorId = itemDescriptor.id;\n\t\t\t\t// replace the old descriptor with the updated one\n\t\t\t\tcatalog.descriptors = catalog.descriptors.map(d => {\n\t\t\t\t\tif (d.id === descriptorId) {\n\t\t\t\t\t\titemDescriptor.model.meta.modified = true;\n\t\t\t\t\t\tthis.addSnapshot(itemDescriptor.model);\n\t\t\t\t\t\treturn itemDescriptor.model;\n\t\t\t\t\t}\n\t\t\t\t\treturn d;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn catalog;\n\t\t});\n\t\tthis.setState({catalogs: catalogs, requiresSave: true})\n\t}\n\n\tdeleteSelectedCatalogItem() {\n\t\tSelectionManager.getSelections().forEach(selectedId => {\n\t\t\tconst item = this.getCatalogItemByUid(selectedId);\n\t\t\tif (item) {\n\t\t\t\tthis.deleteCatalogItem(item);\n\t\t\t}\n\t\t});\n\t\tSelectionManager.clearSelectionAndRemoveOutline();\n\t}\n\n\tdeleteCatalogItem(item) {\n\t\tconst snapshot = JSON.stringify(item);\n\t\tfunction confirmDeleteCancel(event) {\n\t\t\tundo();\n\t\t\tevent.preventDefault();\n\t\t\tModalOverlayActions.hideModalOverlay();\n\t\t}\n\t\tconst remove = () => {\n\t\t\t// item is deleted or does not exist on server, so remove from ui\n\t\t\tthis.removeCatalogItem(item);\n\t\t\tthis.setState({catalogs: this.getCatalogs()});\n\t\t\tconst activeItem = ComposerAppStore.getState().item;\n\t\t\tif (activeItem && activeItem.id === item.id) {\n\t\t\t\tCatalogItemsActions.editCatalogItem.defer(null);\n\t\t\t}\n\t\t\tModalOverlayActions.hideModalOverlay();\n\t\t};\n\t\tconst undo = () => {\n\t\t\t// item failed to delete on server so revert ui\n\t\t\tconst revertTo = JSON.parse(snapshot);\n\t\t\tthis.updateCatalogItem(revertTo);\n\t\t\tconst activeItem = ComposerAppStore.getState().item;\n\t\t\tif (activeItem && activeItem.id === revertTo.id) {\n\t\t\t\tSelectionManager.select(activeItem);\n\t\t\t\tCatalogItemsActions.editCatalogItem.defer(revertTo);\n\t\t\t\tSelectionManager.refreshOutline();\n\t\t\t}\n\t\t};\n\t\tif (item) {\n\t\t\tif (item.meta.isNew) {\n\t\t\t\tCatalogDataStore.confirmDelete(remove, confirmDeleteCancel);\n\t\t\t} else {\n\t\t\t\tif (item.meta['instance-ref-count'] > 0) {\n\t\t\t\t\tconsole.log('cannot delete NSD with references to instantiated Network Services');\n\t\t\t\t\tComposerAppActions.showError.defer({\n\t\t\t\t\t\terrorMessage: 'Cannot delete NSD with references to instantiated Network Services'\n\t\t\t\t\t});\n\t\t\t\t\tundo();\n\t\t\t\t} else {\n\t\t\t\t\tconst confirmDeleteOK = event => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\titem.meta.deleted = true;\n\t\t\t\t\t\tthis.setState({catalogs: this.getCatalogs()});\n\t\t\t\t\t\tModalOverlayActions.showModalOverlay.defer();\n\t\t\t\t\t\tthis.getInstance().deleteCatalogItem(item.meta.type, item.id)\n\t\t\t\t\t\t\t.then(remove, undo)\n\t\t\t\t\t\t\t.then(ModalOverlayActions.hideModalOverlay, ModalOverlayActions.hideModalOverlay)\n\t\t\t\t\t\t\t.catch(function() {\n\t\t\t\t\t\t\t\tconsole.log('overcoming ES6 unhandled rejection red herring');\n\t\t\t\t\t\t\t});\n\t\t\t\t\t};\n\t\t\t\t\tCatalogDataStore.confirmDelete(confirmDeleteOK, confirmDeleteCancel);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic confirmDelete(onClickYes, onClickCancel) {\n\t\tModalOverlayActions.showModalOverlay.defer((\n\t\t\t<div className=\"actions panel\">\n\t\t\t\t<div className=\"panel-header\">\n\t\t\t\t\t<h1>Delete the selected catalog item?</h1>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"panel-body\">\n\t\t\t\t\t<a className=\"action confirm-yes primary-action Button\" onClick={onClickYes}>Yes, delete selected catalog item</a>\n\t\t\t\t\t<a className=\"action cancel secondary-action Button\" onClick={onClickCancel}>No, cancel</a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t));\n\t}\n\n\tcreateCatalogItem(type = 'nsd') {\n\t\tconst model = DescriptorModelMetaFactory.createModelInstanceForType(type);\n\t\tif (model) {\n\t\t\tconst newItem = this.addNewItemToCatalog(model);\n\t\t\tthis.selectCatalogItem(newItem);\n\t\t\tnewItem.meta.isNew = true;\n\t\t\tnewItem.meta.modified = true;\n\t\t\tnewItem.meta['instance-ref-count'] = 0;\n\t\t\t// open the new model for editing in the canvas/details panels\n\t\t\tCatalogItemsActions.editCatalogItem.defer(newItem);\n\t\t}\n\t}\n\n\tduplicateSelectedCatalogItem() {\n\t\tconst item = this.getFirstSelectedCatalogItem();\n\t\tif (item) {\n\t\t\tconst newItem = _.cloneDeep(item);\n\t\t\tnewItem.name = newItem.name + ' Copy';\n\t\t\tconst nsd = this.addNewItemToCatalog(newItem);\n\t\t\tthis.selectCatalogItem(nsd);\n\t\t\tnsd.meta.isNew = true;\n\t\t\tnsd.meta.modified = true;\n\t\t\tnsd.meta['instance-ref-count'] = 0;\n\t\t\t// note duplicated items get a new id, map the layout position\n\t\t\t// of the old id to the new id in order to preserve the layout\n\t\t\tif (nsd.meta.containerPositionMap) {\n\t\t\t\tnsd.meta.containerPositionMap[nsd.id] = nsd.meta.containerPositionMap[item.id];\n\t\t\t\tdelete nsd.meta.containerPositionMap[item.id];\n\t\t\t}\n\t\t\tCatalogItemsActions.editCatalogItem.defer(nsd);\n\t\t}\n\t}\n\n\taddSnapshot(item) {\n\t\tif (item) {\n\t\t\tif (!this.snapshots[item.id]) {\n\t\t\t\tthis.snapshots[item.id] = [];\n\t\t\t}\n\t\t\tthis.snapshots[item.id].push(JSON.stringify(item));\n\t\t}\n\t}\n\n\tresetSnapshots(item) {\n\t\tif (item) {\n\t\t\tthis.snapshots[item.id] = [];\n\t\t\tthis.addSnapshot(item);\n\t\t}\n\t}\n\n\teditCatalogItem(item) {\n\t\tif (item) {\n\t\t\tthis.addSnapshot(item);\n\t\t\t// replace the given item in the catalog\n\t\t\tconst catalogs = this.getCatalogs().map(catalog => {\n\t\t\t\tcatalog.descriptors = catalog.descriptors.map(d => {\n\t\t\t\t\t// note only one item can be \"open\" at a time\n\t\t\t\t\t// so remove the flag from all the other items\n\t\t\t\t\td.meta.isOpenForEdit = (d.id === item.id);\n\t\t\t\t\tif (d.meta.isOpenForEdit) {\n\t\t\t\t\t\treturn item;\n\t\t\t\t\t}\n\t\t\t\t\treturn d;\n\t\t\t\t});\n\t\t\t\treturn catalog;\n\t\t\t});\n\t\t\tthis.setState({catalogs: catalogs});\n\t\t}\n\t}\n\n\tcancelCatalogItemChanges() {\n\t\tconst activeItem = ComposerAppStore.getState().item;\n\t\tif (activeItem) {\n\t\t\tconst snapshots = this.snapshots[activeItem.id];\n\t\t\tif (snapshots.length) {\n\t\t\t\tconst revertTo = JSON.parse(snapshots[0]);\n\t\t\t\tthis.updateCatalogItem(revertTo);\n\t\t\t\t// TODO should the cancel action clear the undo/redo stack back to the beginning?\n\t\t\t\tthis.resetSnapshots(revertTo);\n\t\t\t\tthis.setState({requiresSave: false});\n\t\t\t\tCatalogItemsActions.editCatalogItem.defer(revertTo);\n\t\t\t}\n\t\t}\n\t}\n\n\tsaveCatalogItem() {\n\t\tconst activeItem = ComposerAppStore.getState().item;\n\t\tif (activeItem) {\n\t\t\tconst success = () => {\n\t\t\t\tdelete activeItem.meta.isNew;\n\t\t\t\tdelete activeItem.meta.modified;\n\t\t\t\tthis.updateCatalogItem(activeItem);\n\t\t\t\t// TODO should the save action clear the undo/redo stack back to the beginning?\n\t\t\t\tthis.resetSnapshots(activeItem);\n\t\t\t\tModalOverlayActions.hideModalOverlay.defer();\n\t\t\t\tCatalogItemsActions.editCatalogItem.defer(activeItem);\n\t\t\t};\n\t\t\tconst failure = () => {\n\t\t\t\tModalOverlayActions.hideModalOverlay.defer();\n\t\t\t\tCatalogItemsActions.editCatalogItem.defer(activeItem);\n\t\t\t};\n\t\t\tconst exception = () => {\n\t\t\t\tconsole.warn('unable to save catalog item', activeItem);\n\t\t\t\tModalOverlayActions.hideModalOverlay.defer();\n\t\t\t\tCatalogItemsActions.editCatalogItem.defer(activeItem);\n\t\t\t};\n\t\t\tModalOverlayActions.showModalOverlay.defer();\n\t\t\tthis.getInstance().saveCatalogItem(activeItem).then(success, failure).catch(exception);\n\t\t}\n\t}\n\n\texportSelectedCatalogItems(draggedItem) {\n\t\tif (draggedItem) {\n\t\t\t// if item is given make sure it is also selected\n\t\t\t//draggedItem.meta.selected = true;\n\t\t\tSelectionManager.addSelection(draggedItem);\n\t\t\tthis.updateCatalogItem(draggedItem);\n\t\t}\n\t\t// collect the selected items and delegate to the catalog package manager action creator\n\t\tconst selectedItems = this.getAllSelectedCatalogItems();\n\t\tif (selectedItems.length) {\n\t\t\tCatalogPackageManagerActions.downloadCatalogPackage.defer(selectedItems);\n\t\t}\n\t}\n\n}\n\nexport default alt.createStore(CatalogDataStore, 'CatalogDataStore');\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/stores/CatalogDataStore.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\nimport alt from '../alt';\n\nclass CatalogPackageManagerActions {\n\n\tconstructor() {\n\t\tthis.generateActions('downloadCatalogPackage', 'downloadCatalogPackageStatusUpdated', 'downloadCatalogPackageError', 'uploadCatalogPackage', 'uploadCatalogPackageStatusUpdated', 'uploadCatalogPackageError', 'removeCatalogPackage');\n\t}\n\n}\n\nexport default alt.createActions(CatalogPackageManagerActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CatalogPackageManagerActions.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/14/15.\n */\nimport alt from '../alt';\n\nclass ModalOverlayActions {\n\n\tconstructor() {\n\t\tthis.generateActions('showModalOverlay', 'hideModalOverlay');\n\t}\n\n}\n\nexport default alt.createActions(ModalOverlayActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/ModalOverlayActions.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItemCanvasEditor.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItemCanvasEditor.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItemCanvasEditor.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogItemCanvasEditor.scss\n ** module id = 516\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogItemCanvasEditor {\\n  position: relative;\\n}\\n\\n.CatalogItemCanvasEditor .DescriptorModel {\\n  position: absolute;\\n  height: 100%;\\n  width: 100%;\\n  margin: 0;\\n  top: 0;\\n  left: 0;\\n  overflow: auto;\\n}\\n\\n.CatalogItemCanvasEditor path.relation {\\n  stroke: #333333;\\n  stroke-width: 1;\\n  stroke-dasharray: 2, 2;\\n  stroke-linejoin: round;\\n}\\n\\n.CatalogItemCanvasEditor #relation-marker-end {\\n  fill: #EAEAEA;\\n  stroke: #EAEAEA;\\n  stroke-width: 1;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogItemCanvasEditor.scss\n ** module id = 517\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DescriptorGraph.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DescriptorGraph.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DescriptorGraph.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/DescriptorGraph.scss\n ** module id = 518\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.DescriptorGraph {\\n  background-color: transparent;\\n  border: 1px solid transparent;\\n  -webkit-user-select: none;\\n  -moz-user-select: none;\\n  user-select: none;\\n}\\n\\n.DescriptorGraph text:hover {\\n  cursor: default;\\n}\\n\\n.DescriptorGraph text {\\n  fill: #231010;\\n  stroke: #231010;\\n  font-size: 14px;\\n}\\n\\n.DescriptorGraph path {\\n  stroke-linejoin: round;\\n}\\n\\n.DescriptorGraph path.relation {\\n  display: none;\\n}\\n\\n.DescriptorGraph .grid line {\\n  stroke: #CBD1D1;\\n  stroke-width: 0.5px;\\n  shape-rendering: geometricPrecision;\\n}\\n\\n.DescriptorGraph .descriptor .nsd {\\n  stroke: #0688F5;\\n}\\n\\n.DescriptorGraph .descriptor .constituent-vnfd {\\n  stroke: #6800F3;\\n}\\n\\n.DescriptorGraph .descriptor .pnfd {\\n  stroke: orange;\\n}\\n\\n.DescriptorGraph .descriptor .vdu {\\n  stroke: #1536A2;\\n}\\n\\n.DescriptorGraph .selection-indicator {\\n  stroke-dasharray: 2, 2;\\n}\\n\\n.DescriptorGraph .connector.-is-not-connected {\\n  fill: white !important;\\n}\\n\\n.DescriptorGraph .connector.-is-connected {\\n  fill: #9fc4f4 !important;\\n}\\n\\n.DescriptorGraph .connection,\\n.DescriptorGraph .new-connection {\\n  /* note colors are also defined in ColorGroups.js */\\n  stroke-width: 5px;\\n}\\n\\n.DescriptorGraph .connection.-selected,\\n.DescriptorGraph .new-connection.-selected {\\n  stroke-width: 7px;\\n  stroke: red;\\n}\\n\\n.DescriptorGraph .connection-point:hover {\\n  cursor: pointer;\\n}\\n\\n.DescriptorGraph .connection-point.nsd {\\n  stroke: #0688F5;\\n  fill: #0688F5;\\n}\\n\\n.DescriptorGraph .connection-point.constituent-vnfd {\\n  stroke: #6800F3;\\n  fill: #6800F3;\\n}\\n\\n.DescriptorGraph .connection-point.-is-highlight {\\n  stroke: red !important;\\n}\\n\\n.DescriptorGraph .connection-point-number {\\n  text-shadow: 0 0 10px #E5E5E5;\\n}\\n\\n.DescriptorGraph .connection-point-number.-is-highlight {\\n  fill: red;\\n  stroke: red;\\n}\\n\\n.DescriptorGraph .internal-connection-point {\\n  stroke: #1536A2;\\n  fill: #1536A2;\\n}\\n\\n.DescriptorGraph .relation-marker-end {\\n  stroke: transparent;\\n  fill: transparent;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point {\\n  cursor: no-drop;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point text {\\n  fill: rgba(35, 16, 16, 0.25);\\n  stroke: rgba(35, 16, 16, 0.25);\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point rect {\\n  stroke: #fafafa;\\n  fill: #fafafa;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .nsd {\\n  stroke: #b3cee6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .vnfd {\\n  stroke: #c8b3e6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .constituent-vnfd {\\n  stroke: #c8b3e6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .pnfd {\\n  stroke: #e6d4b3;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .vdu {\\n  stroke: #b3bee6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .connection {\\n  stroke: #e6b3b3;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .connection-point.nsd {\\n  stroke: #b3cee6;\\n  fill: #b3cee6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .connection-point.constituent-vnfd {\\n  stroke: #c8b3e6;\\n  fill: #c8b3e6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .internal-connection-point {\\n  stroke: #b3bee6;\\n  fill: #b3bee6;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target {\\n  cursor: pointer;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target text {\\n  fill: #231010;\\n  stroke: #231010;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target rect {\\n  stroke: white;\\n  fill: white;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target .nsd {\\n  stroke: #0688F5;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target .constituent-vnfd {\\n  stroke: #6800F3;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target .pnfd {\\n  stroke: orange;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target .vdu {\\n  stroke: #1536A2;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.connection {\\n  stroke: #800000;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.connection-point.nsd {\\n  stroke: #0688F5;\\n  fill: #0688F5;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.connection-point.constituent-vnfd {\\n  stroke: #6800F3;\\n  fill: #6800F3;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.connection-point.-is-drag-over {\\n  stroke-width: 2px;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.internal-connection-point {\\n  stroke: #1536A2;\\n  fill: #1536A2;\\n}\\n\\n.DescriptorGraph.-is-dragging-connection-point .-is-valid-drop-target.-is-drag-over rect {\\n  stroke-width: 2px;\\n}\\n\\n.DescriptorGraph .forwarding-graph-paths {\\n  pointer-events: none;\\n}\\n\\n.DescriptorGraph text {\\n  pointer-events: none;\\n}\\n\\n.DescriptorGraph text.type {\\n  text-transform: uppercase;\\n  stroke: white;\\n  fill: white;\\n}\\n\\n.DescriptorGraph text.vld-type {\\n  display: none;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/DescriptorGraph.scss\n ** module id = 519\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react'\nimport Range from './Range'\nimport numeral from 'numeral'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CanvasEditorActions from '../actions/CanvasEditorActions'\nimport SelectionManager from '../libraries/SelectionManager'\n\nimport '../styles/CanvasZoom.scss'\n\nconst CanvasZoom = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState: function () {\n\t\treturn {};\n\t},\n\tgetDefaultProps: function () {\n\t\treturn {\n\t\t\tmin: 25,\n\t\t\tmax: 200,\n\t\t\tzoom: 100,\n\t\t\tdefaultZoom: 100\n\t\t};\n\t},\n\tcomponentWillMount: function () {\n\t},\n\tcomponentDidMount: function () {\n\t},\n\tcomponentDidUpdate: function () {\n\t},\n\tcomponentWillUnmount: function () {\n\t},\n\trender() {\n\t\tconst zoom = this.props.zoom || this.props.defaultZoom\n\t\tconst displayValue = numeral(zoom).format('0.0') + '%';\n\t\treturn (\n\t\t\t<div ref=\"canvasZoom\" className=\"CanvasZoom\" style={this.props.style}\n\t\t\t\t onMouseOver={this.pauseSelectionManager}\n\t\t\t\t onMouseOut={this.resumeSelectionManager}\n\t\t\t\t onMouseLeave={this.resumeSelectionManager}>\n\t\t\t\t<Range\n\t\t\t\t\t   value={zoom} min={this.props.min} max={this.props.max}\n\t\t\t\t\t   title=\"Zoom the canvas. Double Click to reset to 100%.\"\n\t\t\t\t\t   onChange={this.onChange} onDoubleClick={this.onDblClick} />\n\t\t\t\t<span>{displayValue}</span>\n\t\t\t</div>\n\t\t);\n\t},\n\tonChange(event) {\n\t\tconst zoom = event.target.value;\n\t\tCanvasEditorActions.setCanvasZoom(zoom);\n\t},\n\tonDblClick() {\n\t\tconst zoom = this.props.defaultZoom;\n\t\tCanvasEditorActions.setCanvasZoom(zoom);\n\t},\n\tpauseSelectionManager() {\n\t\tSelectionManager.pause();\n\t},\n\tresumeSelectionManager() {\n\t\tSelectionManager.resume();\n\t}\n});\n\nexport default CanvasZoom;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CanvasZoom.js\n **/","/**\n * Created by onvelocity on 2/3/16.\n */\n'use strict';\n\nvar React = require('react');\nvar ReactDOM = require('react-dom');\nvar _extends = Object.assign;\n\n/**\n * WORKAROUND FOR: https://github.com/facebook/react/issues/554\n * COPIED FROM: https://github.com/mapbox/react-range\n */\n\nvar Range = React.createClass({\n\tdisplayName: 'Range',\n\tpropTypes: {\n\t\tonChange: React.PropTypes.func,\n\t\tonClick: React.PropTypes.func,\n\t\tonKeyDown: React.PropTypes.func,\n\t\tonMouseMove: React.PropTypes.func\n\t},\n\tgetDefaultProps: function() {\n\t\treturn {\n\t\t\ttype: 'range',\n\t\t\tonChange: function(){},\n\t\t\tonClick: function(){},\n\t\t\tonKeyDown: function(){},\n\t\t\tonMouseMove: function(){}\n\t\t};\n\t},\n\tonRangeChange: function(e) {\n\t\tthis.props.onMouseMove(e);\n\t\tif (e.buttons !== 1 && e.which !== 1) return;\n\t\tthis.props.onChange(e);\n\t},\n\tonRangeClick: function(e) {\n\t\tthis.props.onClick(e);\n\t\tthis.props.onChange(e);\n\t},\n\tonRangeKeyDown: function(e) {\n\t\tthis.props.onKeyDown(e);\n\t\tthis.props.onChange(e);\n\t},\n\tcomponentWillReceiveProps: function(props) {\n\t\tReactDOM.findDOMNode(this).value = props.value;\n\t},\n\trender: function() {\n\t\tvar props = _extends({}, this.props, {\n\t\t\tdefaultValue: this.props.value,\n\t\t\tonClick: this.onRangeClick,\n\t\t\tonKeyDown: this.onRangeKeyDown,\n\t\t\tonMouseMove: this.onRangeChange,\n\t\t\tonChange: function() {}\n\t\t});\n\t\tdelete props.value;\n\t\treturn React.createElement(\n\t\t\t'input',\n\t\t\tprops\n\t\t);\n\t}\n});\n\nmodule.exports = Range;\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/Range.js\n **/","/*!\n * numeral.js\n * version : 1.5.3\n * author : Adam Draper\n * license : MIT\n * http://adamwdraper.github.com/Numeral-js/\n */\n\n(function () {\n\n    /************************************\n        Constants\n    ************************************/\n\n    var numeral,\n        VERSION = '1.5.3',\n        // internal storage for language config files\n        languages = {},\n        currentLanguage = 'en',\n        zeroFormat = null,\n        defaultFormat = '0,0',\n        // check for nodeJS\n        hasModule = (typeof module !== 'undefined' && module.exports);\n\n\n    /************************************\n        Constructors\n    ************************************/\n\n\n    // Numeral prototype object\n    function Numeral (number) {\n        this._value = number;\n    }\n\n    /**\n     * Implementation of toFixed() that treats floats more like decimals\n     *\n     * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present\n     * problems for accounting- and finance-related software.\n     */\n    function toFixed (value, precision, roundingFunction, optionals) {\n        var power = Math.pow(10, precision),\n            optionalsRegExp,\n            output;\n            \n        //roundingFunction = (roundingFunction !== undefined ? roundingFunction : Math.round);\n        // Multiply up by precision, round accurately, then divide and use native toFixed():\n        output = (roundingFunction(value * power) / power).toFixed(precision);\n\n        if (optionals) {\n            optionalsRegExp = new RegExp('0{1,' + optionals + '}$');\n            output = output.replace(optionalsRegExp, '');\n        }\n\n        return output;\n    }\n\n    /************************************\n        Formatting\n    ************************************/\n\n    // determine what type of formatting we need to do\n    function formatNumeral (n, format, roundingFunction) {\n        var output;\n\n        // figure out what kind of format we are dealing with\n        if (format.indexOf('$') > -1) { // currency!!!!!\n            output = formatCurrency(n, format, roundingFunction);\n        } else if (format.indexOf('%') > -1) { // percentage\n            output = formatPercentage(n, format, roundingFunction);\n        } else if (format.indexOf(':') > -1) { // time\n            output = formatTime(n, format);\n        } else { // plain ol' numbers or bytes\n            output = formatNumber(n._value, format, roundingFunction);\n        }\n\n        // return string\n        return output;\n    }\n\n    // revert to number\n    function unformatNumeral (n, string) {\n        var stringOriginal = string,\n            thousandRegExp,\n            millionRegExp,\n            billionRegExp,\n            trillionRegExp,\n            suffixes = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],\n            bytesMultiplier = false,\n            power;\n\n        if (string.indexOf(':') > -1) {\n            n._value = unformatTime(string);\n        } else {\n            if (string === zeroFormat) {\n                n._value = 0;\n            } else {\n                if (languages[currentLanguage].delimiters.decimal !== '.') {\n                    string = string.replace(/\\./g,'').replace(languages[currentLanguage].delimiters.decimal, '.');\n                }\n\n                // see if abbreviations are there so that we can multiply to the correct number\n                thousandRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.thousand + '(?:\\\\)|(\\\\' + languages[currentLanguage].currency.symbol + ')?(?:\\\\))?)?$');\n                millionRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.million + '(?:\\\\)|(\\\\' + languages[currentLanguage].currency.symbol + ')?(?:\\\\))?)?$');\n                billionRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.billion + '(?:\\\\)|(\\\\' + languages[currentLanguage].currency.symbol + ')?(?:\\\\))?)?$');\n                trillionRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.trillion + '(?:\\\\)|(\\\\' + languages[currentLanguage].currency.symbol + ')?(?:\\\\))?)?$');\n\n                // see if bytes are there so that we can multiply to the correct number\n                for (power = 0; power <= suffixes.length; power++) {\n                    bytesMultiplier = (string.indexOf(suffixes[power]) > -1) ? Math.pow(1024, power + 1) : false;\n\n                    if (bytesMultiplier) {\n                        break;\n                    }\n                }\n\n                // do some math to create our number\n                n._value = ((bytesMultiplier) ? bytesMultiplier : 1) * ((stringOriginal.match(thousandRegExp)) ? Math.pow(10, 3) : 1) * ((stringOriginal.match(millionRegExp)) ? Math.pow(10, 6) : 1) * ((stringOriginal.match(billionRegExp)) ? Math.pow(10, 9) : 1) * ((stringOriginal.match(trillionRegExp)) ? Math.pow(10, 12) : 1) * ((string.indexOf('%') > -1) ? 0.01 : 1) * (((string.split('-').length + Math.min(string.split('(').length-1, string.split(')').length-1)) % 2)? 1: -1) * Number(string.replace(/[^0-9\\.]+/g, ''));\n\n                // round if we are talking about bytes\n                n._value = (bytesMultiplier) ? Math.ceil(n._value) : n._value;\n            }\n        }\n        return n._value;\n    }\n\n    function formatCurrency (n, format, roundingFunction) {\n        var symbolIndex = format.indexOf('$'),\n            openParenIndex = format.indexOf('('),\n            minusSignIndex = format.indexOf('-'),\n            space = '',\n            spliceIndex,\n            output;\n\n        // check for space before or after currency\n        if (format.indexOf(' $') > -1) {\n            space = ' ';\n            format = format.replace(' $', '');\n        } else if (format.indexOf('$ ') > -1) {\n            space = ' ';\n            format = format.replace('$ ', '');\n        } else {\n            format = format.replace('$', '');\n        }\n\n        // format the number\n        output = formatNumber(n._value, format, roundingFunction);\n\n        // position the symbol\n        if (symbolIndex <= 1) {\n            if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {\n                output = output.split('');\n                spliceIndex = 1;\n                if (symbolIndex < openParenIndex || symbolIndex < minusSignIndex){\n                    // the symbol appears before the \"(\" or \"-\"\n                    spliceIndex = 0;\n                }\n                output.splice(spliceIndex, 0, languages[currentLanguage].currency.symbol + space);\n                output = output.join('');\n            } else {\n                output = languages[currentLanguage].currency.symbol + space + output;\n            }\n        } else {\n            if (output.indexOf(')') > -1) {\n                output = output.split('');\n                output.splice(-1, 0, space + languages[currentLanguage].currency.symbol);\n                output = output.join('');\n            } else {\n                output = output + space + languages[currentLanguage].currency.symbol;\n            }\n        }\n\n        return output;\n    }\n\n    function formatPercentage (n, format, roundingFunction) {\n        var space = '',\n            output,\n            value = n._value * 100;\n\n        // check for space before %\n        if (format.indexOf(' %') > -1) {\n            space = ' ';\n            format = format.replace(' %', '');\n        } else {\n            format = format.replace('%', '');\n        }\n\n        output = formatNumber(value, format, roundingFunction);\n        \n        if (output.indexOf(')') > -1 ) {\n            output = output.split('');\n            output.splice(-1, 0, space + '%');\n            output = output.join('');\n        } else {\n            output = output + space + '%';\n        }\n\n        return output;\n    }\n\n    function formatTime (n) {\n        var hours = Math.floor(n._value/60/60),\n            minutes = Math.floor((n._value - (hours * 60 * 60))/60),\n            seconds = Math.round(n._value - (hours * 60 * 60) - (minutes * 60));\n        return hours + ':' + ((minutes < 10) ? '0' + minutes : minutes) + ':' + ((seconds < 10) ? '0' + seconds : seconds);\n    }\n\n    function unformatTime (string) {\n        var timeArray = string.split(':'),\n            seconds = 0;\n        // turn hours and minutes into seconds and add them all up\n        if (timeArray.length === 3) {\n            // hours\n            seconds = seconds + (Number(timeArray[0]) * 60 * 60);\n            // minutes\n            seconds = seconds + (Number(timeArray[1]) * 60);\n            // seconds\n            seconds = seconds + Number(timeArray[2]);\n        } else if (timeArray.length === 2) {\n            // minutes\n            seconds = seconds + (Number(timeArray[0]) * 60);\n            // seconds\n            seconds = seconds + Number(timeArray[1]);\n        }\n        return Number(seconds);\n    }\n\n    function formatNumber (value, format, roundingFunction) {\n        var negP = false,\n            signed = false,\n            optDec = false,\n            abbr = '',\n            abbrK = false, // force abbreviation to thousands\n            abbrM = false, // force abbreviation to millions\n            abbrB = false, // force abbreviation to billions\n            abbrT = false, // force abbreviation to trillions\n            abbrForce = false, // force abbreviation\n            bytes = '',\n            ord = '',\n            abs = Math.abs(value),\n            suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],\n            min,\n            max,\n            power,\n            w,\n            precision,\n            thousands,\n            d = '',\n            neg = false;\n\n        // check if number is zero and a custom zero format has been set\n        if (value === 0 && zeroFormat !== null) {\n            return zeroFormat;\n        } else {\n            // see if we should use parentheses for negative number or if we should prefix with a sign\n            // if both are present we default to parentheses\n            if (format.indexOf('(') > -1) {\n                negP = true;\n                format = format.slice(1, -1);\n            } else if (format.indexOf('+') > -1) {\n                signed = true;\n                format = format.replace(/\\+/g, '');\n            }\n\n            // see if abbreviation is wanted\n            if (format.indexOf('a') > -1) {\n                // check if abbreviation is specified\n                abbrK = format.indexOf('aK') >= 0;\n                abbrM = format.indexOf('aM') >= 0;\n                abbrB = format.indexOf('aB') >= 0;\n                abbrT = format.indexOf('aT') >= 0;\n                abbrForce = abbrK || abbrM || abbrB || abbrT;\n\n                // check for space before abbreviation\n                if (format.indexOf(' a') > -1) {\n                    abbr = ' ';\n                    format = format.replace(' a', '');\n                } else {\n                    format = format.replace('a', '');\n                }\n\n                if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {\n                    // trillion\n                    abbr = abbr + languages[currentLanguage].abbreviations.trillion;\n                    value = value / Math.pow(10, 12);\n                } else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {\n                    // billion\n                    abbr = abbr + languages[currentLanguage].abbreviations.billion;\n                    value = value / Math.pow(10, 9);\n                } else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {\n                    // million\n                    abbr = abbr + languages[currentLanguage].abbreviations.million;\n                    value = value / Math.pow(10, 6);\n                } else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {\n                    // thousand\n                    abbr = abbr + languages[currentLanguage].abbreviations.thousand;\n                    value = value / Math.pow(10, 3);\n                }\n            }\n\n            // see if we are formatting bytes\n            if (format.indexOf('b') > -1) {\n                // check for space before\n                if (format.indexOf(' b') > -1) {\n                    bytes = ' ';\n                    format = format.replace(' b', '');\n                } else {\n                    format = format.replace('b', '');\n                }\n\n                for (power = 0; power <= suffixes.length; power++) {\n                    min = Math.pow(1024, power);\n                    max = Math.pow(1024, power+1);\n\n                    if (value >= min && value < max) {\n                        bytes = bytes + suffixes[power];\n                        if (min > 0) {\n                            value = value / min;\n                        }\n                        break;\n                    }\n                }\n            }\n\n            // see if ordinal is wanted\n            if (format.indexOf('o') > -1) {\n                // check for space before\n                if (format.indexOf(' o') > -1) {\n                    ord = ' ';\n                    format = format.replace(' o', '');\n                } else {\n                    format = format.replace('o', '');\n                }\n\n                ord = ord + languages[currentLanguage].ordinal(value);\n            }\n\n            if (format.indexOf('[.]') > -1) {\n                optDec = true;\n                format = format.replace('[.]', '.');\n            }\n\n            w = value.toString().split('.')[0];\n            precision = format.split('.')[1];\n            thousands = format.indexOf(',');\n\n            if (precision) {\n                if (precision.indexOf('[') > -1) {\n                    precision = precision.replace(']', '');\n                    precision = precision.split('[');\n                    d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);\n                } else {\n                    d = toFixed(value, precision.length, roundingFunction);\n                }\n\n                w = d.split('.')[0];\n\n                if (d.split('.')[1].length) {\n                    d = languages[currentLanguage].delimiters.decimal + d.split('.')[1];\n                } else {\n                    d = '';\n                }\n\n                if (optDec && Number(d.slice(1)) === 0) {\n                    d = '';\n                }\n            } else {\n                w = toFixed(value, null, roundingFunction);\n            }\n\n            // format number\n            if (w.indexOf('-') > -1) {\n                w = w.slice(1);\n                neg = true;\n            }\n\n            if (thousands > -1) {\n                w = w.toString().replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1' + languages[currentLanguage].delimiters.thousands);\n            }\n\n            if (format.indexOf('.') === 0) {\n                w = '';\n            }\n\n            return ((negP && neg) ? '(' : '') + ((!negP && neg) ? '-' : '') + ((!neg && signed) ? '+' : '') + w + d + ((ord) ? ord : '') + ((abbr) ? abbr : '') + ((bytes) ? bytes : '') + ((negP && neg) ? ')' : '');\n        }\n    }\n\n    /************************************\n        Top Level Functions\n    ************************************/\n\n    numeral = function (input) {\n        if (numeral.isNumeral(input)) {\n            input = input.value();\n        } else if (input === 0 || typeof input === 'undefined') {\n            input = 0;\n        } else if (!Number(input)) {\n            input = numeral.fn.unformat(input);\n        }\n\n        return new Numeral(Number(input));\n    };\n\n    // version number\n    numeral.version = VERSION;\n\n    // compare numeral object\n    numeral.isNumeral = function (obj) {\n        return obj instanceof Numeral;\n    };\n\n    // This function will load languages and then set the global language.  If\n    // no arguments are passed in, it will simply return the current global\n    // language key.\n    numeral.language = function (key, values) {\n        if (!key) {\n            return currentLanguage;\n        }\n\n        if (key && !values) {\n            if(!languages[key]) {\n                throw new Error('Unknown language : ' + key);\n            }\n            currentLanguage = key;\n        }\n\n        if (values || !languages[key]) {\n            loadLanguage(key, values);\n        }\n\n        return numeral;\n    };\n    \n    // This function provides access to the loaded language data.  If\n    // no arguments are passed in, it will simply return the current\n    // global language object.\n    numeral.languageData = function (key) {\n        if (!key) {\n            return languages[currentLanguage];\n        }\n        \n        if (!languages[key]) {\n            throw new Error('Unknown language : ' + key);\n        }\n        \n        return languages[key];\n    };\n\n    numeral.language('en', {\n        delimiters: {\n            thousands: ',',\n            decimal: '.'\n        },\n        abbreviations: {\n            thousand: 'k',\n            million: 'm',\n            billion: 'b',\n            trillion: 't'\n        },\n        ordinal: function (number) {\n            var b = number % 10;\n            return (~~ (number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n        },\n        currency: {\n            symbol: '$'\n        }\n    });\n\n    numeral.zeroFormat = function (format) {\n        zeroFormat = typeof(format) === 'string' ? format : null;\n    };\n\n    numeral.defaultFormat = function (format) {\n        defaultFormat = typeof(format) === 'string' ? format : '0.0';\n    };\n\n    /************************************\n        Helpers\n    ************************************/\n\n    function loadLanguage(key, values) {\n        languages[key] = values;\n    }\n\n    /************************************\n        Floating-point helpers\n    ************************************/\n\n    // The floating-point helper functions and implementation\n    // borrows heavily from sinful.js: http://guipn.github.io/sinful.js/\n\n    /**\n     * Array.prototype.reduce for browsers that don't support it\n     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#Compatibility\n     */\n    if ('function' !== typeof Array.prototype.reduce) {\n        Array.prototype.reduce = function (callback, opt_initialValue) {\n            'use strict';\n            \n            if (null === this || 'undefined' === typeof this) {\n                // At the moment all modern browsers, that support strict mode, have\n                // native implementation of Array.prototype.reduce. For instance, IE8\n                // does not support strict mode, so this check is actually useless.\n                throw new TypeError('Array.prototype.reduce called on null or undefined');\n            }\n            \n            if ('function' !== typeof callback) {\n                throw new TypeError(callback + ' is not a function');\n            }\n\n            var index,\n                value,\n                length = this.length >>> 0,\n                isValueSet = false;\n\n            if (1 < arguments.length) {\n                value = opt_initialValue;\n                isValueSet = true;\n            }\n\n            for (index = 0; length > index; ++index) {\n                if (this.hasOwnProperty(index)) {\n                    if (isValueSet) {\n                        value = callback(value, this[index], index, this);\n                    } else {\n                        value = this[index];\n                        isValueSet = true;\n                    }\n                }\n            }\n\n            if (!isValueSet) {\n                throw new TypeError('Reduce of empty array with no initial value');\n            }\n\n            return value;\n        };\n    }\n\n    \n    /**\n     * Computes the multiplier necessary to make x >= 1,\n     * effectively eliminating miscalculations caused by\n     * finite precision.\n     */\n    function multiplier(x) {\n        var parts = x.toString().split('.');\n        if (parts.length < 2) {\n            return 1;\n        }\n        return Math.pow(10, parts[1].length);\n    }\n\n    /**\n     * Given a variable number of arguments, returns the maximum\n     * multiplier that must be used to normalize an operation involving\n     * all of them.\n     */\n    function correctionFactor() {\n        var args = Array.prototype.slice.call(arguments);\n        return args.reduce(function (prev, next) {\n            var mp = multiplier(prev),\n                mn = multiplier(next);\n        return mp > mn ? mp : mn;\n        }, -Infinity);\n    }        \n\n\n    /************************************\n        Numeral Prototype\n    ************************************/\n\n\n    numeral.fn = Numeral.prototype = {\n\n        clone : function () {\n            return numeral(this);\n        },\n\n        format : function (inputString, roundingFunction) {\n            return formatNumeral(this, \n                  inputString ? inputString : defaultFormat, \n                  (roundingFunction !== undefined) ? roundingFunction : Math.round\n              );\n        },\n\n        unformat : function (inputString) {\n            if (Object.prototype.toString.call(inputString) === '[object Number]') { \n                return inputString; \n            }\n            return unformatNumeral(this, inputString ? inputString : defaultFormat);\n        },\n\n        value : function () {\n            return this._value;\n        },\n\n        valueOf : function () {\n            return this._value;\n        },\n\n        set : function (value) {\n            this._value = Number(value);\n            return this;\n        },\n\n        add : function (value) {\n            var corrFactor = correctionFactor.call(null, this._value, value);\n            function cback(accum, curr, currI, O) {\n                return accum + corrFactor * curr;\n            }\n            this._value = [this._value, value].reduce(cback, 0) / corrFactor;\n            return this;\n        },\n\n        subtract : function (value) {\n            var corrFactor = correctionFactor.call(null, this._value, value);\n            function cback(accum, curr, currI, O) {\n                return accum - corrFactor * curr;\n            }\n            this._value = [value].reduce(cback, this._value * corrFactor) / corrFactor;            \n            return this;\n        },\n\n        multiply : function (value) {\n            function cback(accum, curr, currI, O) {\n                var corrFactor = correctionFactor(accum, curr);\n                return (accum * corrFactor) * (curr * corrFactor) /\n                    (corrFactor * corrFactor);\n            }\n            this._value = [this._value, value].reduce(cback, 1);\n            return this;\n        },\n\n        divide : function (value) {\n            function cback(accum, curr, currI, O) {\n                var corrFactor = correctionFactor(accum, curr);\n                return (accum * corrFactor) / (curr * corrFactor);\n            }\n            this._value = [this._value, value].reduce(cback);            \n            return this;\n        },\n\n        difference : function (value) {\n            return Math.abs(numeral(this._value).subtract(value).value());\n        }\n\n    };\n\n    /************************************\n        Exposing Numeral\n    ************************************/\n\n    // CommonJS module is defined\n    if (hasModule) {\n        module.exports = numeral;\n    }\n\n    /*global ender:false */\n    if (typeof ender === 'undefined') {\n        // here, `this` means `window` in the browser, or `global` on the server\n        // add `numeral` as a global object via a string identifier,\n        // for Closure Compiler 'advanced' mode\n        this['numeral'] = numeral;\n    }\n\n    /*global define:false */\n    if (typeof define === 'function' && define.amd) {\n        define([], function () {\n            return numeral;\n        });\n    }\n}).call(this);\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/numeral/numeral.js\n ** module id = 522\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasZoom.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasZoom.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasZoom.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CanvasZoom.scss\n ** module id = 523\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CanvasZoom {\\n  border: 1px dashed transparent;\\n  position: absolute;\\n  bottom: 20px;\\n  left: 20px;\\n  opacity: 0.25;\\n}\\n\\n.CanvasZoom input {\\n  opacity: 0.33;\\n  vertical-align: middle;\\n}\\n\\n.CanvasZoom span {\\n  display: inline-block;\\n  font-family: \\\"Roboto\\\", sans-serif;\\n  font-weight: 100;\\n  width: 100px;\\n  padding-left: 8px;\\n}\\n\\n.CanvasZoom:hover {\\n  opacity: 1;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CanvasZoom.scss\n ** module id = 524\n ** module chunks = 0\n **/","/**\n * Created by onvelocity on 2/4/16.\n */\n'use strict';\nimport React from 'react'\nimport ClassNames from 'classnames'\nimport SelectionManager from '../libraries/SelectionManager'\nimport CanvasPanelTrayActions from '../actions/CanvasPanelTrayActions'\nimport '../styles/CanvasPanelTray.scss'\nexport default function (props) {\n\tconst style = {\n\t\theight: Math.max(0, props.layout.bottom),\n\t\tright: props.layout.right\n\t};\n\tconst classNames = ClassNames('CanvasPanelTray', {'-with-transitions': !document.body.classList.contains('resizing')});\n\tfunction pauseSelectionManager(event) {\n\t\tevent.preventDefault();\n\t\tSelectionManager.pause();\n\t}\n\treturn (\n\t\t<div className={classNames} data-resizable=\"top\" style={style}>\n\t\t\t<h1 onClick={CanvasPanelTrayActions.toggleOpenClose} onMouseDown={pauseSelectionManager} onMouseOver={SelectionManager.pause} onMouseOut={SelectionManager.resume} onMouseLeave={SelectionManager.resume}>Forwarding Graphs</h1>\n\t\t\t<div className=\"tray-body\">\n\t\t\t\t{props.children}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CanvasPanelTray.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasPanelTray.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasPanelTray.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasPanelTray.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CanvasPanelTray.scss\n ** module id = 526\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CanvasPanelTray {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 25px;\\n  min-width: 300px;\\n  background-color: white;\\n}\\n\\n.CanvasPanelTray.-with-transitions {\\n  transition: height 300ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n\\n.CanvasPanelTray h1 {\\n  border-bottom: 1px solid rgba(143, 143, 143, 0.05);\\n  cursor: pointer;\\n  color: #666;\\n  font-size: 12px;\\n  font-style: normal;\\n  line-height: 16px;\\n  height: 25px;\\n  margin: 0;\\n  padding-left: 0;\\n  padding-right: 0;\\n  text-align: center;\\n  text-transform: uppercase;\\n  background-color: #cbd1d1;\\n}\\n\\n.CanvasPanelTray > .tray-body {\\n  position: absolute;\\n  top: 25px;\\n  right: 0;\\n  left: 0;\\n  bottom: 0;\\n  overflow: auto;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CanvasPanelTray.scss\n ** module id = 527\n ** module chunks = 0\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 2/4/16.\n */\n\n'use strict';\n\nimport React from 'react'\nimport Range from './Range'\nimport Button from './Button'\nimport ClassNames from 'classnames'\nimport changeCase from 'change-case'\nimport LayoutRow from './LayoutRow'\nimport SelectionManager from '../libraries/SelectionManager'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport CanvasEditorActions from '../actions/CanvasEditorActions'\nimport DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'\nimport ComposerAppStore from '../stores/ComposerAppStore'\nimport DeletionManager from '../libraries/DeletionManager'\nimport ContentEditableDiv from './ContentEditableDiv'\n\nimport '../styles/ForwardingGraphPathsEditor.scss'\nimport imgNSD from '../images/iconmonstr-network-6-icon.svg'\nimport imgFG from '../images/iconmonstr-infinity-4-icon.svg'\nimport imgRemove from '../images/recycle69.svg'\nimport imgAdd from '../images/iconmonstr-plus-5-icon-256.png'\nimport imgConnection from '../images/connection.svg'\nimport imgClassifier from '../images/iconmonstr-control-panel-4.svg'\nimport imgReorder from '../images/menu51.svg'\n\nfunction onHoverHighlightConnectionPoint(cpNumber, event) {\n\tconst found = Array.from(document.querySelectorAll('[data-cp-number=\"' + cpNumber + '\"]'));\n\tif (event.type === 'mouseenter') {\n\t\tfound.forEach(d => d.classList.add('-is-highlight'));\n\t} else {\n\t\tfound.forEach(d => d.classList.remove('-is-highlight'));\n\t}\n}\n\nfunction onClickSelectAndShowInDetailsPanel(container, event) {\n\tif (event.defaultPrevented) return;\n\tevent.preventDefault();\n\tif (container.isFactory) {\n\t\treturn\n\t}\n\tComposerAppActions.selectModel(container);\n\tComposerAppActions.outlineModel.defer(container);\n}\n\nfunction onCutRemove(cp, event) {\n\tif (event.defaultPrevented) return;\n\tif (cp.remove()) {\n\t\tCatalogItemsActions.catalogItemDescriptorChanged.defer(cp.getRoot());\n\t} else {\n\t\tevent.preventDefault();\n\t}\n\tevent.stopPropagation();\n}\n\nfunction mapCP(cpRef, i) {\n\n\tconst context = this;\n\n\treturn (\n\t\t<div key={cpRef.uid} className=\"rsp\">\n\t\t\t<div className=\"rsp-line\" style={context.stylePrimary}></div>\n\t\t\t<div className={cpRef.className} data-uid={cpRef.uid} data-datum={cpRef} style={context.stylePrimary}\n\t\t\t\t onCut={onCutRemove.bind(null, cpRef)}\n\t\t\t\t onMouseEnter={onHoverHighlightConnectionPoint.bind(null, cpRef.cpNumber)}\n\t\t\t\t onMouseLeave={onHoverHighlightConnectionPoint.bind(null, cpRef.cpNumber)}\n\t\t\t\t onClick={onClickSelectAndShowInDetailsPanel.bind(null, cpRef)}>\n\t\t\t\t<small>{cpRef.cpNumber}</small>\n\t\t\t</div>\n\t\t</div>\n\t);\n\n}\n\nfunction mapConnector(context, rsp, connector, i) {\n\tfunction onClickAddConnectionPointRef(rsp, connector, event) {\n\t\tevent.preventDefault();\n\t\tif (rsp.isFactory) {\n\t\t\tconst newRsp = rsp.createVnfdConnectionPointRef(connector);\n\t\t\tcontext.component.setState({editPathsMode: newRsp.uid});\n\t\t} else {\n\t\t\trsp.createVnfdConnectionPointRef(connector);\n\t\t}\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(rsp.getRoot());\n\t}\n\tconst cpNumber = connector.cpNumber;\n\treturn (\n\t\t<div key={connector.uid} className={connector.className} style={context.styleSecondary}\n\t\t\t onClick={onClickAddConnectionPointRef.bind(null, rsp, connector)}\n\t\t\t onMouseEnter={onHoverHighlightConnectionPoint.bind(null, cpNumber)}\n\t\t\t onMouseLeave={onHoverHighlightConnectionPoint.bind(null, cpNumber)}><small>cp{cpNumber}</small></div>\n\t);\n}\n\nfunction mapNextValidConnectionPoint(context, rsp, cvnfd, i) {\n\n\t//const context = this;\n\n\treturn (\n\t\t<div key={i} className={cvnfd.className}>\n\t\t\t<small className=\"vnfd-title\">{cvnfd.title}</small>\n\t\t\t<div className=\"connectors\">\n\t\t\t\t{cvnfd.connectors.map(mapConnector.bind(null, context, rsp))}\n\t\t\t</div>\n\t\t</div>\n\t);\n\n}\n\nfunction mapRSP(rsp, i) {\n\n\tconst context = this;\n\tcontext.rsp = rsp;\n\n\trsp.meta.showPath = rsp.meta.hasOwnProperty('showPath') ? rsp.meta.showPath : true;\n\n\tfunction onClickAddConnectionPointRef(rsp, event) {\n\t\tevent.preventDefault();\n\t\tconst ref = rsp.createVnfdConnectionPointRef();\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(ref.getRoot());\n\t}\n\n\tfunction onClickRemoveRecordServicePath(rsp, event) {\n\t\tevent.preventDefault();\n\t\tconst root = rsp.getRoot();\n\t\trsp.remove();\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(root);\n\t}\n\n\tfunction onClickCreateRecordServicePath(rsp, event) {\n\t\tevent.preventDefault();\n\t\trsp.create();\n\t\tthis.component.setState({editPathsMode: rsp.uid});\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(rsp.getRoot());\n\t}\n\n\tfunction onClickEnterPathEdithMode(rsp, event) {\n\t\tevent.preventDefault();\n\t\tthis.setState({editPathsMode: rsp.uid});\n\t}\n\n\tfunction onClickExitPathEdithMode(rsp, event) {\n\t\tevent.preventDefault();\n\t\tthis.setState({editPathsMode: false});\n\t}\n\n\tfunction onClickToggleRSPShowPath(rsp, event) {\n\t\t// warn preventing default will undo the user's action\n\t\t//event.preventDefault();\n\t\trsp.meta.showPath = event.target.checked;\n\t\trsp.parent.meta.showPaths = rsp.parent.rsp.filter(rsp => rsp.meta.showPath === true).length === rsp.parent.rsp.length;\n\t\tCatalogItemsActions.catalogItemMetaDataChanged(rsp.getRoot().model);\n\t}\n\n\tfunction onClickToggleHideShowClassifiers(context, rsp, event) {\n\t\tevent.preventDefault();\n\t\tconst state = context.component.state.showClassifiers || {};\n\t\trsp.meta.showClassifiers = state[rsp.uid] = !state[rsp.uid];\n\t\tcontext.component.setState({showClassifiers: state});\n\t\tCatalogItemsActions.catalogItemMetaDataChanged(rsp.getRoot().model);\n\t}\n\n\tfunction onInputUpdateModel(context, attr, name, event) {\n\t\tevent.preventDefault();\n\t\tattr.setFieldValue(name, event.target.value);\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(attr.getRoot());\n\t}\n\n\tfunction onClickMatchAttributeFieldValue(context, attr, name, event) {\n\t\tconst isSelected = SelectionManager.isSelected(attr.parent);\n\t\tif (!isSelected) {\n\t\t\t// let the click through so it selects the row\n\t\t} else {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\tfunction onFocusMatchAttributeField(attr, event) {\n\t\tDeletionManager.removeEventListeners();\n\t\tComposerAppActions.selectModel(attr.parent);\n\t\tComposerAppActions.outlineModel.defer(attr.parent);\n\t}\n\n\tfunction onClickCreateClassifier(rsp, event) {\n\t\tevent.preventDefault();\n\t\trsp.createClassifier();\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(rsp.getRoot());\n\t}\n\n\tfunction mapClassifierMatchAttributes(context, matchAttributes) {\n\t\treturn matchAttributes.fieldNames.map((name, i) => {\n\t\t\treturn (\n\t\t\t\t<td key={i} className={matchAttributes.className}>\n\t\t\t\t\t<div className=\"match-attr-name\">{name}</div>\n\t\t\t\t\t<ContentEditableDiv value={matchAttributes.getFieldValue(name)}\n\t\t\t\t\t\t\t\t\t\tonClick={onClickMatchAttributeFieldValue.bind(null, context, matchAttributes, name)}\n\t\t\t\t\t\t\t\t\t\tonFocus={onFocusMatchAttributeField.bind(null, matchAttributes)}\n\t\t\t\t\t\t\t\t\t\tonBlur={() => DeletionManager.addEventListeners()}\n\t\t\t\t\t\t\t\t\t\tonChange={onInputUpdateModel.bind(null, context, matchAttributes, name)}\n\t\t\t\t\t\t\t\t\t\tclassName=\"match-attr-value\"/>\n\t\t\t\t</td>\n\t\t\t);\n\t\t});\n\t}\n\n\tfunction mapClassifiers(context, rsp, classifier, i) {\n\n\t\treturn (\n\t\t\t<tr key={classifier.uid} data-uid={classifier.uid} data-datum={classifier} onCut={onCutRemove.bind(null, classifier)} className={classifier.className} onClick={onClickSelectAndShowInDetailsPanel.bind(null, classifier)}>\n\t\t\t\t<th key=\"primary-action-column\" className=\"primary-action-column\"><img src={imgReorder}/></th><th key=\"secondary-action-column\" className=\"secondary-action-column\"> </th>\n\t\t\t\t{mapClassifierMatchAttributes(context, classifier.matchAttributes)}\n\t\t\t</tr>\n\t\t);\n\n\t}\n\n\tconst isEditPathsMode = context.component.state.editPathsMode === rsp.uid;\n\n\tconst toggleSelectionOrCreateNewPath = (\n\t\t<div>\n\t\t\t{!rsp.isFactory ? <input type=\"checkbox\" id={'show-path-' + rsp.uid} checked={rsp.meta.showPath} defaultValue=\"true\" onChange={onClickToggleRSPShowPath.bind(null, rsp)} /> : ' '}\n\t\t</div>\n\t);\n\n\tconst toggleClassifiersEditor = (\n\t\t<Button src={imgClassifier} title=\"Show Classifier rules for this RSP\" onClick={onClickToggleHideShowClassifiers.bind(null, context, rsp)} />\n\t);\n\n\tconst attributeNames = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.vnffgd.rsp.classifier.match-attributes');\n\n\tconst showClassifiers = context.component.state.showClassifiers[rsp.uid];\n\n\treturn (\n\t\t<div key={i} className=\"rsp\" data-offset-width=\"table.rsp-classifier\" data-uid={rsp.uid} data-datum={rsp} onClick={onClickSelectAndShowInDetailsPanel.bind(null, rsp)} onCut={onCutRemove.bind(null, rsp)}>\n\t\t\t<div className={ClassNames(rsp.className, {'-is-factory': rsp.isFactory, '-is-edit-paths-mode': isEditPathsMode})}>\n\t\t\t\t<div className=\"header-actions\">\n\t\t\t\t\t{!rsp.isFactory ? <Button className=\"remove-record-service-path\" title=\"Remove\"\n\t\t\t\t\t\t\t\t\t\t\t  onClick={onClickRemoveRecordServicePath.bind(null, rsp)}\n\t\t\t\t\t\t\t\t\t\t\t  src={imgRemove}/> : null}\n\t\t\t\t</div>\n\t\t\t\t<LayoutRow primaryActionColumn={toggleSelectionOrCreateNewPath}\n\t\t\t\t\t\t   secondaryActionColumn={!rsp.isFactory ? toggleClassifiersEditor : null}>\n\t\t\t\t\t<div className=\"connection-points\">\n\t\t\t\t\t\t{rsp.connectionPoints.map(mapCP.bind(context))}\n\t\t\t\t\t\t<div className=\"rsp-create-new-connection-point-line rsp-line\"\n\t\t\t\t\t\t\t style={context.styleSecondary}></div>\n\t\t\t\t\t\t<div className=\"enter-path-edit-mode ConnectionPoint\" style={context.styleSecondary}\n\t\t\t\t\t\t\t onClick={onClickEnterPathEdithMode.bind(context.component, rsp)}>\n\t\t\t\t\t\t\t<small>+CP</small>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"selection\">\n\t\t\t\t\t\t\t<div className=\"select-next-connection-point-list\">\n\t\t\t\t\t\t\t\t{context.containers.filter(d => DescriptorModelFactory.isConstituentVnfd(d)).map(mapNextValidConnectionPoint.bind(null, context, rsp))}\n\t\t\t\t\t\t\t\t<small className=\"Button\"\n\t\t\t\t\t\t\t\t\t   onClick={onClickExitPathEdithMode.bind(context.component, rsp)}>done\n\t\t\t\t\t\t\t\t</small>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{rsp.isFactory && !isEditPathsMode? <small className=\"enter-path-edit-mode-hint hint\">Tap to start creating a new path.</small> : null}\n\t\t\t\t\t</div>\n\t\t\t\t</LayoutRow>\n\t\t\t</div>\n\t\t\t<table className={ClassNames('rsp-classifier', {'-is-show-classifiers': showClassifiers})}>\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th key=\"primary-action-column\" className=\"primary-action-column\"><div className=\"primary-action-column\"></div></th><th key=\"secondary-action-column\" className=\"secondary-action-column\"><div className=\"secondary-action-column\"></div></th>\n\t\t\t\t\t\t{attributeNames.map((name, i) => <th key={i}>{changeCase.title(name)}</th>)}\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{!rsp.isFactory ? rsp.classifier.map(mapClassifiers.bind(null, context, rsp)) : null}\n\t\t\t\t</tbody>\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th colSpan={attributeNames.length + 2}>\n\t\t\t\t\t\t\t<Button className=\"create-new-classifier\" src={imgAdd} width=\"20px\" onClick={onClickCreateClassifier.bind(null, rsp)} label=\"\" />\n\t\t\t\t\t\t\t<small className=\"create-new-classifier action hint\" onClick={onClickCreateClassifier.bind(null, rsp)}>Add new Classifier</small>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\t\t</div>\n\t);\n\n}\n\nfunction mapFG(fg, i) {\n\n\tconst context = this;\n\tcontext.vnffg = fg;\n\n\tconst colors = fg.colors;\n\tconst stylePrimary = {borderColor: colors.primary};\n\tconst styleSecondary = {borderColor: colors.secondary};\n\n\tcontext.stylePrimary = stylePrimary;\n\tcontext.styleSecondary = styleSecondary;\n\n\tfunction onClickRemoveForwardingGraph(fg, event) {\n\t\tevent.preventDefault();\n\t\tconst root = fg.getRoot();\n\t\tfg.remove();\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(root);\n\t}\n\n\tfunction onClickAddRecordServicePath(fg, event) {\n\t\tevent.preventDefault();\n\t\tfg.createRsp();\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(fg.getRoot());\n\t}\n\n\tfunction onClickToggleShowAllFGPaths(fg, event) {\n\t\t//event.preventDefault();\n\t\tfg.meta.showPaths = event.target.checked;\n\t\tfg.rsp.forEach(rsp => rsp.meta.showPath = event.target.checked);\n\t\tCatalogItemsActions.catalogItemMetaDataChanged(fg.getRoot().model);\n\t}\n\n\tif (!fg.meta.hasOwnProperty('showPaths')) {\n\t\tfg.meta.showPaths = true;\n\t\tfg.rsp.forEach(d => d.meta.showPath = true);\n\t}\n\n\tconst toggleSelectAllPaths = (\n\t\t<input type=\"checkbox\" name={'show-path' + fg.uid} checked={fg.meta.showPaths} onChange={onClickToggleShowAllFGPaths.bind(null, fg)} />\n\t);\n\n\tconst srpFactory = DescriptorModelFactory.newRecordServicePathFactory({}, fg);\n\tsrpFactory.uid = fg.uid + i;\n\n\treturn (\n\t\t<div key={i} className={fg.className} data-uid={fg.uid} data-datum={fg} data-offset-width=\"table.rsp-classifier\" onClick={onClickSelectAndShowInDetailsPanel.bind(null, fg)} onCut={onCutRemove.bind(null, fg)}>\n\t\t\t<div key=\"outline-indicator\" data-outline-indicator=\"true\"></div>\n\t\t\t<div className=\"header-actions\">\n\t\t\t\t<Button className=\"remove-forwarding-graph\" title=\"Remove\" onClick={onClickRemoveForwardingGraph.bind(null, fg)} src={imgRemove}/>\n\t\t\t</div>\n\t\t\t<LayoutRow primaryActionColumn={toggleSelectAllPaths} secondaryActionColumn={<img className=\"fg-icon\" src={imgFG} width=\"20px\" />}>\n\t\t\t\t<small>{fg.title}</small>\n\t\t\t</LayoutRow>\n\t\t\t{fg.recordServicePaths.concat(srpFactory).map(mapRSP.bind(context))}\n\t\t</div>\n\t);\n\n}\n\nfunction mapNSD(nsd, i) {\n\n\tconst context = this;\n\tcontext.nsd = nsd;\n\n\tfunction onClickAddForwardingGraph(nsd, event) {\n\t\tevent.preventDefault();\n\t\tnsd.createVnffgd();\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(nsd.getRoot());\n\t}\n\n\tconst forwardingGraphs = nsd.forwardingGraphs.map(mapFG.bind(context));\n\tif (forwardingGraphs.length === 0) {\n\t\tforwardingGraphs.push(\n\t\t\t<div key=\"1\" className=\"welcome-message\">\n\t\t\t\tNo Forwarding Graphs to model.\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div key={i} className={nsd.className}>\n\t\t\t{forwardingGraphs}\n\t\t\t<div className=\"footer-actions\">\n\t\t\t\t<div className=\"row-action-column\">\n\t\t\t\t\t<Button className=\"create-new-forwarding-graph\" src={imgAdd} width=\"20px\" onClick={onClickAddForwardingGraph.bind(null, nsd)} label=\"\" />\n\t\t\t\t\t<small className=\"create-new-forwarding-graph action hint\" onClick={onClickAddForwardingGraph.bind(null, nsd)}>Add new Forwarding Graph</small>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n\n}\n\nconst ForwardingGraphPathsEditor = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState: function () {\n\t\treturn ComposerAppStore.getState();\n\t},\n\tgetDefaultProps: function () {\n\t\treturn {\n\t\t\tcontainers: []\n\t\t};\n\t},\n\tcomponentWillMount: function () {\n\t},\n\tcomponentDidMount: function () {\n\t},\n\tcomponentDidUpdate: function () {\n\t},\n\tcomponentWillUnmount: function () {\n\t},\n\trender() {\n\n\t\tconst containers = this.props.containers;\n\t\tconst context = {\n\t\t\tcomponent: this,\n\t\t\tcontainers: containers\n\t\t};\n\n\t\tconst networkService = containers.filter(d => d.type === 'nsd');\n\t\tif (networkService.length === 0) {\n\t\t\treturn <p className=\"welcome-message\">No <img src={imgNSD} width=\"20px\" /> NSD open in the canvas. Try opening an NSD.</p>;\n\t\t}\n\n\t\treturn (\n\t\t\t<div className=\"ForwardingGraphPathsEditor -with-transitions\" data-offset-parent=\"true\">\n\t\t\t\t<div key=\"outline-indicator\" data-outline-indicator=\"true\"></div>\n\t\t\t\t{containers.filter(d => d.type === 'nsd').map(mapNSD.bind(context))}\n\t\t\t</div>\n\t\t);\n\n\t}\n});\n\nexport default ForwardingGraphPathsEditor;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/ForwardingGraphPathsEditor.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 12/1/15.\n */\n'use strict';\n\nimport guid from '../libraries/guid'\nimport React from 'react'\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport SelectionManager from '../libraries/SelectionManager'\n\nimport '../styles/Button.scss'\n\nconst Button = React.createClass({\n\tmixins: [PureRenderMixin, SelectionManager.reactPauseResumeMixin()],\n\tgetInitialState: function () {\n\t\treturn {};\n\t},\n\tgetDefaultProps: function () {\n\t\treturn {\n\t\t\tdisableSelection: true,\n\t\t\tclassName: '',\n\t\t\tlabel: null,\n\t\t\ttitle: null,\n\t\t\tsrc: null,\n\t\t\tonClick: () => {}\n\t\t};\n\t},\n\tcomponentWillMount: function () {\n\t},\n\tcomponentDidMount: function () {\n\t},\n\tcomponentDidUpdate: function () {\n\t},\n\tcomponentWillUnmount: function () {\n\t},\n\trender() {\n\t\tconst src = this.props.src;\n\t\tconst label = this.props.label;\n\t\tconst title = this.props.title;\n\t\tconst draggable = this.props.draggable;\n\t\tconst className = ClassNames(this.props.className, 'Button');\n\t\treturn (\n\t\t\t<div className={className} {...this.pauseSelection(this.props.disableSelection)} onClick={this.props.onClick} title={title} draggable={draggable} onDragStart={this.props.onDragStart}>\n\t\t\t\t<img src={src} />\n\t\t\t\t<span>{label}</span>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default Button;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/Button.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./Button.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./Button.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./Button.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/Button.scss\n ** module id = 530\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.Button {\\n  display: inline-block;\\n  vertical-align: middle;\\n  margin: 2px;\\n  border: 1px solid transparent;\\n  border-radius: 3px;\\n  padding: 3px 6px;\\n}\\n\\n.Button:hover {\\n  cursor: pointer;\\n}\\n\\n.Button.primary-action {\\n  border-color: rgba(34, 34, 34, 0.38);\\n  box-shadow: 0px 0px 8px 0px rgba(255, 255, 255, 0.65);\\n}\\n\\n.Button:hover {\\n  color: #ffffff;\\n  border-color: rgba(34, 34, 34, 0.38);\\n  box-shadow: 0px 0px 8px 0px rgba(255, 255, 255, 0.65);\\n  background-color: #7E9BC1;\\n}\\n\\n.Button:active, .Button:visited {\\n  background-color: #4C5E74;\\n}\\n\\n.Button img {\\n  width: 20px;\\n  height: 20px;\\n  margin: 0;\\n  box-shadow: none;\\n  vertical-align: middle;\\n}\\n\\n.Button span {\\n  vertical-align: middle;\\n  font-size: 12px;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n  margin-left: 3px;\\n  white-space: nowrap;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/Button.scss\n ** module id = 531\n ** module chunks = 0\n **/","/**\n * Created by onvelocity on 2/12/16.\n */\n\n'use strict';\n\nimport React from 'react'\nimport ClassNames from 'classnames'\n\nimport '../styles/LayoutRow.scss'\n\nexport default function LayoutRow(props) {\n\n\tconst primaryActionColumn = props.primaryActionColumn ? props.primaryActionColumn : <div className=\"layout-row-empty-cell\"> </div>;\n\tconst secondaryActionColumn = props.secondaryActionColumn ? props.secondaryActionColumn : <div className=\"layout-row-empty-cell\"> </div>;\n\n\treturn (\n\t\t<table className={ClassNames('layout-row', props.className)}>\n\t\t\t<tbody>\n\t\t\t\t<tr>\n\t\t\t\t\t<th className=\"primary-action-column\">\n\t\t\t\t\t\t<div className=\"primary-action-column\">{primaryActionColumn}</div>\n\t\t\t\t\t</th>\n\t\t\t\t\t<th className=\"secondary-action-column\">\n\t\t\t\t\t\t<div className=\"primary-action-column\">{secondaryActionColumn}</div>\n\t\t\t\t\t</th>\n\t\t\t\t\t<td className=\"columns\">\n\t\t\t\t\t\t{props.children}\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tbody>\n\t\t</table>\n\t);\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/LayoutRow.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./LayoutRow.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./LayoutRow.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./LayoutRow.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/LayoutRow.scss\n ** module id = 533\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".layout-row {\\n  min-width: 600px;\\n  display: flex;\\n  flex-wrap: nowrap;\\n  vertical-align: baseline;\\n  line-height: 30px;\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n}\\n\\n.layout-row > .primary-action-column {\\n  flex: 0;\\n  min-width: 30px;\\n  max-width: 30px;\\n  text-align: center;\\n}\\n\\n.layout-row > .primary-action-column > * {\\n  vertical-align: middle;\\n}\\n\\n.layout-row > .secondary-action-column {\\n  flex: 0;\\n  min-width: 30px;\\n  max-width: 30px;\\n  text-align: center;\\n  margin: 0 9px;\\n}\\n\\n.layout-row > .secondary-action-column > * {\\n  vertical-align: middle;\\n}\\n\\n.layout-row > .columns {\\n  flex: auto;\\n}\\n\\n.layout-row > .columns > * {\\n  vertical-align: middle;\\n}\\n\\n.layout-row .Button {\\n  margin: 2px 0 0 0;\\n  padding: 0;\\n  width: 30px;\\n  height: 30px;\\n  position: relative;\\n}\\n\\n.layout-row .Button img {\\n  margin: 0;\\n  position: absolute;\\n  top: 4px;\\n  left: 4px;\\n  width: 20px;\\n  height: 20px;\\n}\\n\\n.layout-row .Button span {\\n  margin: 8px;\\n}\\n\\n.layout-row small.Button {\\n  margin: 2px 8px;\\n  padding: 0 8px;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/LayoutRow.scss\n ** module id = 534\n ** module chunks = 0\n **/","/**\n * Created by onvelocity on 2/13/16.\n */\n'use static';\nimport React from 'react'\nexport default function ContentEditableDiv (props) {\n\n\treturn (\n\t\t<input className=\"ContentEditableDiv\" {...props} style={{borderColor: 'transparent', background: 'transparent'}} />\n\t);\n\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/ContentEditableDiv.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ForwardingGraphPathsEditor.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ForwardingGraphPathsEditor.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ForwardingGraphPathsEditor.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/ForwardingGraphPathsEditor.scss\n ** module id = 536\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".ForwardingGraphPathsEditor {\\n  padding: 8px;\\n}\\n\\n.ForwardingGraphPathsEditor.-with-transitions * {\\n  transition: all 300ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n\\n.ForwardingGraphPathsEditor .layout-row {\\n  min-height: 47px;\\n}\\n\\n.ForwardingGraphPathsEditor .NetworkService {\\n  position: relative;\\n}\\n\\n.ForwardingGraphPathsEditor .NetworkService > .footer-actions {\\n  border-top: 1px solid silver;\\n}\\n\\n.ForwardingGraphPathsEditor .ForwardingGraph {\\n  margin-bottom: 20px;\\n}\\n\\n.ForwardingGraphPathsEditor .ForwardingGraph h2:hover > .header-actions, .ForwardingGraphPathsEditor .ForwardingGraph .rsp-classifier th:hover > .header-actions, .ForwardingGraphPathsEditor .rsp-classifier .ForwardingGraph th:hover > .header-actions {\\n  display: block;\\n}\\n\\n.ForwardingGraphPathsEditor .ForwardingGraph h2:hover > .header-actions:hover, .ForwardingGraphPathsEditor .ForwardingGraph .rsp-classifier th:hover > .header-actions:hover, .ForwardingGraphPathsEditor .rsp-classifier .ForwardingGraph th:hover > .header-actions:hover {\\n  opacity: 1;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath {\\n  position: relative;\\n  height: 3em;\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);\\n  white-space: nowrap;\\n  overflow: visible;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath .ConstituentVnfd {\\n  position: relative;\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath .ConstituentVnfd > small {\\n  vertical-align: bottom;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath .ConstituentVnfd small.vnfd-title {\\n  position: absolute;\\n  top: -20px;\\n  width: 100%;\\n  left: 0;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath .ConstituentVnfd .connectors {\\n  border-top: 3px solid silver;\\n  border-radius: 9px;\\n  padding-top: 3px;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath .ConstituentVnfd .connectors .ConnectionPoint {\\n  border: 2px solid;\\n  margin: 2px;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath .ConstituentVnfd .connectors .ConnectionPoint * {\\n  vertical-align: middle;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath.-is-factory {\\n  opacity: 0.33;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath.-is-factory:hover {\\n  opacity: 1;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath.-is-factory:hover .ConstituentVnfd {\\n  display: inline-block;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath.-is-factory .create-record-service-path {\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover > .header-actions {\\n  display: block;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover > .header-actions:hover {\\n  opacity: 1;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover.-is-edit-paths-mode .ConstituentVnfd {\\n  display: inline-block;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover.-is-edit-paths-mode .enter-path-edit-mode {\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover.-is-edit-paths-mode .selection {\\n  display: inline-block;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover.-is-edit-paths-mode > .header-actions {\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .RecordServicePath:hover .rsp-create-new-connection-point-line,\\n.ForwardingGraphPathsEditor .RecordServicePath:hover .enter-path-edit-mode {\\n  opacity: 1;\\n}\\n\\n.ForwardingGraphPathsEditor .RspConnectionPointRef, .ForwardingGraphPathsEditor .ConnectionPoint {\\n  border: 2px solid transparent;\\n  border-radius: 8px;\\n  width: 35px;\\n  height: 35px;\\n  display: inline-block;\\n  margin: 0;\\n  padding: 0;\\n  font-size: 11px;\\n  text-align: center;\\n  cursor: pointer;\\n  vertical-align: middle;\\n}\\n\\n.ForwardingGraphPathsEditor .RspConnectionPointRef.create-new-connection-point, .ForwardingGraphPathsEditor .create-new-connection-point.ConnectionPoint {\\n  width: auto;\\n  height: auto;\\n  border: dotted red;\\n}\\n\\n.ForwardingGraphPathsEditor .RspConnectionPointRef small, .ForwardingGraphPathsEditor .ConnectionPoint small {\\n  vertical-align: baseline;\\n}\\n\\n.ForwardingGraphPathsEditor .ConnectionPoint {\\n  display: inline-block;\\n  border: dotted red;\\n}\\n\\n.ForwardingGraphPathsEditor .ConnectionPoint text {\\n  fill: #111831;\\n  stroke: #111831;\\n}\\n\\n.ForwardingGraphPathsEditor .Classifier td .match-attr-name {\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-classifier {\\n  display: none;\\n  position: relative;\\n  margin-left: 55px;\\n  margin-bottom: 13px;\\n  height: 0;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-classifier th,\\n.ForwardingGraphPathsEditor .rsp-classifier td {\\n  min-width: 80px;\\n  text-align: left;\\n  padding: 4px 7px;\\n  border-width: 5px;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-classifier th:nth-child(1),\\n.ForwardingGraphPathsEditor .rsp-classifier th:nth-child(2),\\n.ForwardingGraphPathsEditor .rsp-classifier td:nth-child(1),\\n.ForwardingGraphPathsEditor .rsp-classifier td:nth-child(2) {\\n  width: 30px;\\n  min-width: 35px;\\n  max-width: 35px;\\n  white-space: nowrap;\\n  margin: 0;\\n  padding: 0 5px;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-classifier th:nth-child(1) img,\\n.ForwardingGraphPathsEditor .rsp-classifier th:nth-child(2) img,\\n.ForwardingGraphPathsEditor .rsp-classifier td:nth-child(1) img,\\n.ForwardingGraphPathsEditor .rsp-classifier td:nth-child(2) img {\\n  width: 20px;\\n  margin: 3px;\\n  vertical-align: middle;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-classifier th.primary-action-column img {\\n  width: 20px;\\n  height: 20px;\\n  opacity: 0.05;\\n  cursor: move;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-classifier.-is-show-classifiers {\\n  display: block;\\n  height: auto;\\n  transition: height 300ms cubic-bezier(0.23, 2, 0.32, 5);\\n}\\n\\n.ForwardingGraphPathsEditor h2, .ForwardingGraphPathsEditor .rsp-classifier th {\\n  font-size: 9px;\\n  text-transform: uppercase;\\n  color: #AEAEAE;\\n}\\n\\n.ForwardingGraphPathsEditor h2 img, .ForwardingGraphPathsEditor .rsp-classifier th img {\\n  border: 0;\\n  width: 30px;\\n  margin: 3px;\\n  vertical-align: middle;\\n}\\n\\n.ForwardingGraphPathsEditor h3 {\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .primary-action-column {\\n  width: 40px;\\n}\\n\\n.ForwardingGraphPathsEditor .secondary-action-column {\\n  width: 40px;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp {\\n  display: inline-block;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp:first-of-type .rsp-line {\\n  display: none;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-line {\\n  border: 2px solid red;\\n  display: inline-block;\\n  width: 20px;\\n  vertical-align: middle;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-line.rsp-create-new-connection-point-line {\\n  border-style: dotted;\\n}\\n\\n.ForwardingGraphPathsEditor .header-actions {\\n  position: absolute;\\n  right: 0;\\n}\\n\\n.ForwardingGraphPathsEditor .row-action-column {\\n  width: 50px;\\n  overflow: visible;\\n  white-space: nowrap;\\n  text-align: center;\\n  /* border-right: 1px solid silver; */\\n  padding: 8px;\\n  display: inline-block;\\n}\\n\\n.ForwardingGraphPathsEditor .row-action-column .action {\\n  cursor: pointer;\\n}\\n\\n.ForwardingGraphPathsEditor .connection-points {\\n  display: inline-block;\\n  margin-right: 25px;\\n}\\n\\n.ForwardingGraphPathsEditor .connection-points .selection {\\n  display: none;\\n  position: absolute;\\n  top: -2.2em;\\n  font-size: 10px;\\n  text-align: center;\\n  border-radius: 33px;\\n  margin: 0 0 0 -12px;\\n  padding: 12px;\\n  background-color: rgba(255, 255, 255, 0.66);\\n  border-top: 1px solid rgba(192, 192, 192, 0.13);\\n  border-bottom: 1px solid rgba(192, 192, 192, 0.13);\\n}\\n\\n.ForwardingGraphPathsEditor .create-new-connection-point.Button {\\n  padding: 0;\\n}\\n\\n.ForwardingGraphPathsEditor .create-new-connection-point.Button img {\\n  width: 34px;\\n  height: 34px;\\n}\\n\\n.ForwardingGraphPathsEditor .header-actions {\\n  display: none;\\n  opacity: 0.33;\\n}\\n\\n.ForwardingGraphPathsEditor .footer-actions {\\n  border-color: transparent;\\n  opacity: 0.33;\\n}\\n\\n.ForwardingGraphPathsEditor .footer-actions:hover {\\n  opacity: 1;\\n}\\n\\n.ForwardingGraphPathsEditor .select-next-connection-point-list {\\n  display: inline-block;\\n}\\n\\n.ForwardingGraphPathsEditor .rsp-create-new-connection-point-line,\\n.ForwardingGraphPathsEditor .enter-path-edit-mode {\\n  opacity: 0.33;\\n}\\n\\n.ForwardingGraphPathsEditor .fg-icon {\\n  width: 25px;\\n  vertical-align: middle;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/ForwardingGraphPathsEditor.scss\n ** module id = 537\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"c05f4636ad2b973dcbb227bcbd31d3a9.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/iconmonstr-network-6-icon.svg\n ** module id = 538\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"fb4e243e120516d9f681ca063e131f0a.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/iconmonstr-infinity-4-icon.svg\n ** module id = 539\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"606b035e43b021c0aeb4eb062a1b3149.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/recycle69.svg\n ** module id = 540\n ** module chunks = 0\n **/","module.exports = \"data:image/png;base64,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\"\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/iconmonstr-plus-5-icon-256.png\n ** module id = 541\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"fe1afdf8cc0d811a89b095055f9eb5a3.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/connection.svg\n ** module id = 542\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"7fa0fed576e0e0397cf5ac22cf3426f5.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/iconmonstr-control-panel-4.svg\n ** module id = 543\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"0cc827aed42802cbff2ea0a056de0d2e.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/menu51.svg\n ** module id = 544\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasPanel.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasPanel.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CanvasPanel.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CanvasPanel.scss\n ** module id = 545\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CanvasPanel {\\n  position: absolute;\\n  top: 0;\\n  right: 0;\\n  bottom: 0;\\n  left: 250px;\\n  width: auto;\\n  min-width: 300px;\\n  overflow: hidden;\\n  z-index: 1;\\n}\\n\\n.CanvasPanel .CanvasPanelHeader h1 {\\n  margin: 0;\\n  min-height: 56px;\\n  padding: 20px;\\n  color: #000000;\\n  font-size: 14px;\\n  font-weight: bold;\\n  text-align: left;\\n  text-transform: uppercase;\\n  line-height: 16px;\\n  background-color: #ffffff;\\n}\\n\\n.CanvasPanel .CanvasPanelBody {\\n  position: absolute;\\n  bottom: 0;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CanvasPanel.scss\n ** module id = 546\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport messages from './messages'\nimport ClassNames from 'classnames'\nimport UploadDropZone from '../libraries/CatalogPackageManagerUploadDropZone'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport DropTarget from './DropTarget'\nimport DropZonePanel from './DropZonePanel'\nimport CatalogItems from './CatalogItems'\nimport CatalogFilter from './CatalogFilter'\nimport CatalogPanelTray from './CatalogPanelTray'\nimport CatalogPanelToolbar from './CatalogPanelToolbar'\nimport CatalogPackageManager from './CatalogPackageManager'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport ComposerAppStore from '../stores/ComposerAppStore'\nimport CatalogPanelStore from '../stores/CatalogPanelStore'\nimport LoadingIndicator from './LoadingIndicator'\n\nimport '../styles/CatalogPanel.scss'\n\nconst createDropZone = function (action, clickable, dropTarget) {\n\tconst dropZone = new UploadDropZone(ReactDOM.findDOMNode(dropTarget), [clickable], action);\n\tdropZone.on('dragover', this.onDragOver);\n\tdropZone.on('dragend', this.onDragEnd);\n\tdropZone.on('addedfile', this.onFileAdded);\n\treturn dropZone;\n};\n\nconst uiTransientState = {\n\tisDrop: false,\n\tisDragging: false,\n\tisDraggingFiles: false,\n\ttimeoutId: 0\n};\n\nconst CatalogPanel = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn CatalogPanelStore.getState();\n\t},\n\tgetDefaultProps() {\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t\tCatalogPanelStore.listen(this.onChange);\n\t\tdocument.body.addEventListener('dragover', this.onDragOver);\n\t\tdocument.body.addEventListener('dragend', this.onDragEnd);\n\t\twindow.addEventListener('dragend', this.onDragEnd);\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t\tCatalogPanelStore.unlisten(this.onChange);\n\t\tdocument.body.removeEventListener('dragover', this.onDragOver);\n\t\tdocument.body.removeEventListener('dragend', this.onDragEnd);\n\t\twindow.removeEventListener('dragend', this.onDragEnd);\n\t},\n\trender() {\n\n\t\tconst onDropCatalogItem = e => {\n\t\t\te.preventDefault();\n\t\t\tclearTimeout(uiTransientState.timeoutId);\n\t\t\tuiTransientState.isDragging = false;\n\t\t\tuiTransientState.isDrop = true;\n\t\t\tconst item = JSON.parse(e.dataTransfer.getData('text')).item;\n\t\t\tCatalogItemsActions.exportSelectedCatalogItems(item);\n\t\t\tCatalogPanelTrayActions.open();\n\t\t};\n\n\t\tconst onDropUpdatePackage = e => {\n\t\t\te.preventDefault();\n\t\t\tclearTimeout(uiTransientState.timeoutId);\n\t\t\tuiTransientState.isDragging = false;\n\t\t\tuiTransientState.isDrop = true;\n\t\t\tCatalogPanelTrayActions.open();\n\t\t};\n\n\t\tconst onDropOnboardPackage = e => {\n\t\t\te.preventDefault();\n\t\t\tclearTimeout(uiTransientState.timeoutId);\n\t\t\tuiTransientState.isDragging = false;\n\t\t\tuiTransientState.isDrop = true;\n\t\t\tCatalogPanelTrayActions.open();\n\t\t};\n\n\t\tconst isDraggingItem = uiTransientState.isDragging && !uiTransientState.isDraggingFiles;\n\t\tconst isDraggingFiles = uiTransientState.isDragging && uiTransientState.isDraggingFiles;\n\t\tconst updateDropZone = createDropZone.bind(this, UploadDropZone.ACTIONS.update, '.action-update-catalog-package');\n\t\tconst onboardDropZone = createDropZone.bind(this, UploadDropZone.ACTIONS.onboard, '.action-onboard-catalog-package');\n\t\tconst className = ClassNames('CatalogPanel', {'-is-tray-open': this.state.isTrayOpen});\n\t\tconst hasNoCatalogs = this.props.hasNoCatalogs;\n\t\tconst isLoading = this.props.isLoading;\n\t\treturn (\n\t\t\t<div className={className} data-resizable=\"right\" style={{width: this.props.layout.left}}>\n\t\t\t\t<CatalogPanelToolbar />\n\t\t\t\t<div className=\"CatalogPanelBody\">\n\t\t\t\t\t{(() => {\n\t\t\t\t\t\tif (isLoading) {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div className=\"LoaderWrapper\">\n\t\t\t\t\t\t\t\t\t<LoadingIndicator />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (hasNoCatalogs) {\n\t\t\t\t\t\t\treturn messages.catalogWelcome;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<CatalogFilter filterByType={this.props.filterByType} />\n\t\t\t\t\t\t\t\t<CatalogItems filterByType={this.props.filterByType} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t})()}\n\t\t\t\t</div>\n\t\t\t\t<CatalogPanelTray show={this.state.isTrayOpen}>\n\t\t\t\t\t<DropZonePanel show={isDraggingItem} title=\"Drop catalog item to export.\">\n\t\t\t\t\t\t<DropTarget className=\"action-export-catalog-items\" onDrop={onDropCatalogItem}>\n\t\t\t\t\t\t\t<span>Export catalog item.</span>\n\t\t\t\t\t\t</DropTarget>\n\t\t\t\t\t</DropZonePanel>\n\t\t\t\t\t<DropZonePanel show={isDraggingFiles}>\n\t\t\t\t\t\t<DropTarget className=\"action-onboard-catalog-package\" dropZone={onboardDropZone} onDrop={onDropOnboardPackage}>\n\t\t\t\t\t\t\t<span>On-board new catalog package.</span>\n\t\t\t\t\t\t</DropTarget>\n\t\t\t\t\t\t<DropTarget className=\"action-update-catalog-package\" dropZone={updateDropZone} onDrop={onDropUpdatePackage}>\n\t\t\t\t\t\t\t<span>Update existing catalog package.</span>\n\t\t\t\t\t\t</DropTarget>\n\t\t\t\t\t</DropZonePanel>\n\t\t\t\t\t<CatalogPackageManager />\n\t\t\t\t</CatalogPanelTray>\n\t\t\t</div>\n\t\t);\n\n\t},\n\tonChange(state) {\n\t\tthis.setState(state);\n\t},\n\tonDragOver(e) {\n\t\t// NOTE do not call preventDefault here - see DropTarget\n\t\tif (!uiTransientState.isDragging) {\n\t\t\tuiTransientState.isDrop = false;\n\t\t\tuiTransientState.isDragging = true;\n\t\t\tuiTransientState.wasTrayOpen = this.state.isTrayOpen;\n\t\t\tuiTransientState.isDraggingFiles = _.contains(e.dataTransfer.types, 'Files');\n\t\t\tconst dragState = ComposerAppStore.getState().drag || {};\n\t\t\tif (uiTransientState.isDraggingFiles || (dragState.type === 'catalog-item')) {\n\t\t\t\tCatalogPanelTrayActions.open();\n\t\t\t}\n\t\t}\n\t\te.dataTransfer.dropEffect = 'none';\n\t\t// the drag-end event does not fire on drag events that originate\n\t\t// outside of the browser, e.g. dragging files from desktop, so\n\t\t// we use this debounced callback to simulate a drag-end event\n\t\tclearTimeout(uiTransientState.timeoutId);\n\t\tuiTransientState.timeoutId = setTimeout(() => {\n\t\t\tthis.onDragEnd();\n\t\t}, 400);\n\t},\n\tonDragEnd() {\n\t\tclearTimeout(uiTransientState.timeoutId);\n\t\tif (uiTransientState.isDragging) {\n\t\t\tuiTransientState.isDragging = false;\n\t\t\tif (uiTransientState.isDrop || uiTransientState.wasTrayOpen) {\n\t\t\t\tCatalogPanelTrayActions.open();\n\t\t\t} else {\n\t\t\t\tCatalogPanelTrayActions.close();\n\t\t\t}\n\t\t}\n\t},\n\tonFileAdded() {\n\t\tCatalogPanelTrayActions.open();\n\t}\n});\n\nexport default CatalogPanel;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogPanel.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/27/15.\n */\n\nimport guid from '../libraries/guid'\nimport DropZone from 'dropzone'\nimport Utils from '../libraries/utils'\nimport CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'\n\n/**\n * This class is responsible for wiring the DropZone.js to our React actions.\n */\n\nconst ACTIONS = {\n\tonboard: 'onboard',\n\tupdate: 'update'\n};\n\nfunction getCatalogPackageManagerServerOrigin() {\n\treturn Utils.getSearchParams(window.location).upload_server + ':4567';\n}\n\nfunction initializeDropZone(element = '#dropzone', button = false, action = ACTIONS.onboard) {\n\tDropZone.autoDiscover = false;\n\treturn new DropZone(element, {\n\t\tparamName: 'descriptor',\n\t\turl() {\n\t\t\tif (action === ACTIONS.update) {\n\t\t\t\treturn getCatalogPackageManagerServerOrigin() + '/api/update';\n\t\t\t}\n\t\t\treturn getCatalogPackageManagerServerOrigin() + '/api/upload';\n\t\t},\n\t\tmaxFilesize: 10000000000,\n\t\tclickable: button,\n\t\tacceptedFiles: 'application/octet-stream,.gz,.tar.gz,.tar,.qcow,.qcow2,.iso,application/json,.json,application/zip,.zip,application/x-rar-compressed,.rar,application/x-7z-compressed,.7z,application/x-bzip,.bz,application/x-bzip2,.bz2,application/x-gtar,.gtar',\n\t\tautoProcessQueue: true,\n\t\tpreviewTemplate: '',\n\t\tsending(file, xhr, formData) {\n\t\t\t// NOTE ie11 does not get this form data\n\t\t\tformData.append('id', file.id);\n\t\t},\n\t\terror(file, errorMessage) {\n\t\t\tconst response = {\n\t\t\t\tstate: file,\n\t\t\t\tdata: {\n\t\t\t\t\tstatus: 'upload-error',\n\t\t\t\t\tmessage: errorMessage\n\t\t\t\t}\n\t\t\t};\n\t\t\tCatalogPackageManagerActions.uploadCatalogPackageError(response);\n\t\t},\n\t\tsuccess(file) {\n\t\t\tconst data = JSON.parse(file.xhr.responseText);\n\t\t\tdata.status = 'upload-success';\n\t\t\tconst response = {\n\t\t\t\tstate: file,\n\t\t\t\tdata: data\n\t\t\t};\n\t\t\tCatalogPackageManagerActions.uploadCatalogPackageStatusUpdated(response);\n\t\t},\n\t\taddedfile(file) {\n\t\t\tfile.id = file.id || guid();\n\t\t\tfile.riftAction = action;\n\t\t\tCatalogPackageManagerActions.uploadCatalogPackage(file);\n\t\t},\n\t\tthumbnail(file, dataUrl) {\n\t\t\tconst response = {\n\t\t\t\tstate: file,\n\t\t\t\tdata: {\n\t\t\t\t\tstatus: 'upload-thumbnail',\n\t\t\t\t\tdataUrl: dataUrl\n\t\t\t\t}\n\t\t\t};\n\t\t\tCatalogPackageManagerActions.uploadCatalogPackageStatusUpdated(response);\n\t\t},\n\t\tuploadprogress(file, progress, bytesSent) {\n\t\t\tconst response = {\n\t\t\t\tstate: file,\n\t\t\t\tdata: {\n\t\t\t\t\tstatus: 'upload-progress',\n\t\t\t\t\tprogress: progress,\n\t\t\t\t\tbytesSent: bytesSent\n\t\t\t\t}\n\t\t\t};\n\t\t\tCatalogPackageManagerActions.uploadCatalogPackageStatusUpdated(response);\n\t\t}\n\t});\n}\n\nexport default class CatalogPackageManagerUploadDropZone {\n\n\tconstructor(element, button, action) {\n\t\tthis.dropZone = initializeDropZone(element, button, action);\n\t}\n\n\tstatic get ACTIONS() {\n\t\treturn ACTIONS;\n\t}\n\n\ton(eventName, eventCallback) {\n\t\tthis.dropZone.on(eventName, eventCallback);\n\t}\n\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/CatalogPackageManagerUploadDropZone.js\n **/","\n/*\n *\n * More info at [www.dropzonejs.com](http://www.dropzonejs.com)\n *\n * Copyright (c) 2012, Matias Meno\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n(function() {\n  var Dropzone, Emitter, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without,\n    __slice = [].slice,\n    __hasProp = {}.hasOwnProperty,\n    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };\n\n  noop = function() {};\n\n  Emitter = (function() {\n    function Emitter() {}\n\n    Emitter.prototype.addEventListener = Emitter.prototype.on;\n\n    Emitter.prototype.on = function(event, fn) {\n      this._callbacks = this._callbacks || {};\n      if (!this._callbacks[event]) {\n        this._callbacks[event] = [];\n      }\n      this._callbacks[event].push(fn);\n      return this;\n    };\n\n    Emitter.prototype.emit = function() {\n      var args, callback, callbacks, event, _i, _len;\n      event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      this._callbacks = this._callbacks || {};\n      callbacks = this._callbacks[event];\n      if (callbacks) {\n        for (_i = 0, _len = callbacks.length; _i < _len; _i++) {\n          callback = callbacks[_i];\n          callback.apply(this, args);\n        }\n      }\n      return this;\n    };\n\n    Emitter.prototype.removeListener = Emitter.prototype.off;\n\n    Emitter.prototype.removeAllListeners = Emitter.prototype.off;\n\n    Emitter.prototype.removeEventListener = Emitter.prototype.off;\n\n    Emitter.prototype.off = function(event, fn) {\n      var callback, callbacks, i, _i, _len;\n      if (!this._callbacks || arguments.length === 0) {\n        this._callbacks = {};\n        return this;\n      }\n      callbacks = this._callbacks[event];\n      if (!callbacks) {\n        return this;\n      }\n      if (arguments.length === 1) {\n        delete this._callbacks[event];\n        return this;\n      }\n      for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) {\n        callback = callbacks[i];\n        if (callback === fn) {\n          callbacks.splice(i, 1);\n          break;\n        }\n      }\n      return this;\n    };\n\n    return Emitter;\n\n  })();\n\n  Dropzone = (function(_super) {\n    var extend, resolveOption;\n\n    __extends(Dropzone, _super);\n\n    Dropzone.prototype.Emitter = Emitter;\n\n\n    /*\n    This is a list of all available events you can register on a dropzone object.\n    \n    You can register an event handler like this:\n    \n        dropzone.on(\"dragEnter\", function() { });\n     */\n\n    Dropzone.prototype.events = [\"drop\", \"dragstart\", \"dragend\", \"dragenter\", \"dragover\", \"dragleave\", \"addedfile\", \"addedfiles\", \"removedfile\", \"thumbnail\", \"error\", \"errormultiple\", \"processing\", \"processingmultiple\", \"uploadprogress\", \"totaluploadprogress\", \"sending\", \"sendingmultiple\", \"success\", \"successmultiple\", \"canceled\", \"canceledmultiple\", \"complete\", \"completemultiple\", \"reset\", \"maxfilesexceeded\", \"maxfilesreached\", \"queuecomplete\"];\n\n    Dropzone.prototype.defaultOptions = {\n      url: null,\n      method: \"post\",\n      withCredentials: false,\n      parallelUploads: 2,\n      uploadMultiple: false,\n      maxFilesize: 256,\n      paramName: \"file\",\n      createImageThumbnails: true,\n      maxThumbnailFilesize: 10,\n      thumbnailWidth: 120,\n      thumbnailHeight: 120,\n      filesizeBase: 1000,\n      maxFiles: null,\n      params: {},\n      clickable: true,\n      ignoreHiddenFiles: true,\n      acceptedFiles: null,\n      acceptedMimeTypes: null,\n      autoProcessQueue: true,\n      autoQueue: true,\n      addRemoveLinks: false,\n      previewsContainer: null,\n      hiddenInputContainer: \"body\",\n      capture: null,\n      dictDefaultMessage: \"Drop files here to upload\",\n      dictFallbackMessage: \"Your browser does not support drag'n'drop file uploads.\",\n      dictFallbackText: \"Please use the fallback form below to upload your files like in the olden days.\",\n      dictFileTooBig: \"File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.\",\n      dictInvalidFileType: \"You can't upload files of this type.\",\n      dictResponseError: \"Server responded with {{statusCode}} code.\",\n      dictCancelUpload: \"Cancel upload\",\n      dictCancelUploadConfirmation: \"Are you sure you want to cancel this upload?\",\n      dictRemoveFile: \"Remove file\",\n      dictRemoveFileConfirmation: null,\n      dictMaxFilesExceeded: \"You can not upload any more files.\",\n      accept: function(file, done) {\n        return done();\n      },\n      init: function() {\n        return noop;\n      },\n      forceFallback: false,\n      fallback: function() {\n        var child, messageElement, span, _i, _len, _ref;\n        this.element.className = \"\" + this.element.className + \" dz-browser-not-supported\";\n        _ref = this.element.getElementsByTagName(\"div\");\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          child = _ref[_i];\n          if (/(^| )dz-message($| )/.test(child.className)) {\n            messageElement = child;\n            child.className = \"dz-message\";\n            continue;\n          }\n        }\n        if (!messageElement) {\n          messageElement = Dropzone.createElement(\"<div class=\\\"dz-message\\\"><span></span></div>\");\n          this.element.appendChild(messageElement);\n        }\n        span = messageElement.getElementsByTagName(\"span\")[0];\n        if (span) {\n          if (span.textContent != null) {\n            span.textContent = this.options.dictFallbackMessage;\n          } else if (span.innerText != null) {\n            span.innerText = this.options.dictFallbackMessage;\n          }\n        }\n        return this.element.appendChild(this.getFallbackForm());\n      },\n      resize: function(file) {\n        var info, srcRatio, trgRatio;\n        info = {\n          srcX: 0,\n          srcY: 0,\n          srcWidth: file.width,\n          srcHeight: file.height\n        };\n        srcRatio = file.width / file.height;\n        info.optWidth = this.options.thumbnailWidth;\n        info.optHeight = this.options.thumbnailHeight;\n        if ((info.optWidth == null) && (info.optHeight == null)) {\n          info.optWidth = info.srcWidth;\n          info.optHeight = info.srcHeight;\n        } else if (info.optWidth == null) {\n          info.optWidth = srcRatio * info.optHeight;\n        } else if (info.optHeight == null) {\n          info.optHeight = (1 / srcRatio) * info.optWidth;\n        }\n        trgRatio = info.optWidth / info.optHeight;\n        if (file.height < info.optHeight || file.width < info.optWidth) {\n          info.trgHeight = info.srcHeight;\n          info.trgWidth = info.srcWidth;\n        } else {\n          if (srcRatio > trgRatio) {\n            info.srcHeight = file.height;\n            info.srcWidth = info.srcHeight * trgRatio;\n          } else {\n            info.srcWidth = file.width;\n            info.srcHeight = info.srcWidth / trgRatio;\n          }\n        }\n        info.srcX = (file.width - info.srcWidth) / 2;\n        info.srcY = (file.height - info.srcHeight) / 2;\n        return info;\n      },\n\n      /*\n      Those functions register themselves to the events on init and handle all\n      the user interface specific stuff. Overwriting them won't break the upload\n      but can break the way it's displayed.\n      You can overwrite them if you don't like the default behavior. If you just\n      want to add an additional event handler, register it on the dropzone object\n      and don't overwrite those options.\n       */\n      drop: function(e) {\n        return this.element.classList.remove(\"dz-drag-hover\");\n      },\n      dragstart: noop,\n      dragend: function(e) {\n        return this.element.classList.remove(\"dz-drag-hover\");\n      },\n      dragenter: function(e) {\n        return this.element.classList.add(\"dz-drag-hover\");\n      },\n      dragover: function(e) {\n        return this.element.classList.add(\"dz-drag-hover\");\n      },\n      dragleave: function(e) {\n        return this.element.classList.remove(\"dz-drag-hover\");\n      },\n      paste: noop,\n      reset: function() {\n        return this.element.classList.remove(\"dz-started\");\n      },\n      addedfile: function(file) {\n        var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;\n        if (this.element === this.previewsContainer) {\n          this.element.classList.add(\"dz-started\");\n        }\n        if (this.previewsContainer) {\n          file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());\n          file.previewTemplate = file.previewElement;\n          this.previewsContainer.appendChild(file.previewElement);\n          _ref = file.previewElement.querySelectorAll(\"[data-dz-name]\");\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            node = _ref[_i];\n            node.textContent = file.name;\n          }\n          _ref1 = file.previewElement.querySelectorAll(\"[data-dz-size]\");\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            node = _ref1[_j];\n            node.innerHTML = this.filesize(file.size);\n          }\n          if (this.options.addRemoveLinks) {\n            file._removeLink = Dropzone.createElement(\"<a class=\\\"dz-remove\\\" href=\\\"javascript:undefined;\\\" data-dz-remove>\" + this.options.dictRemoveFile + \"</a>\");\n            file.previewElement.appendChild(file._removeLink);\n          }\n          removeFileEvent = (function(_this) {\n            return function(e) {\n              e.preventDefault();\n              e.stopPropagation();\n              if (file.status === Dropzone.UPLOADING) {\n                return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {\n                  return _this.removeFile(file);\n                });\n              } else {\n                if (_this.options.dictRemoveFileConfirmation) {\n                  return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {\n                    return _this.removeFile(file);\n                  });\n                } else {\n                  return _this.removeFile(file);\n                }\n              }\n            };\n          })(this);\n          _ref2 = file.previewElement.querySelectorAll(\"[data-dz-remove]\");\n          _results = [];\n          for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {\n            removeLink = _ref2[_k];\n            _results.push(removeLink.addEventListener(\"click\", removeFileEvent));\n          }\n          return _results;\n        }\n      },\n      removedfile: function(file) {\n        var _ref;\n        if (file.previewElement) {\n          if ((_ref = file.previewElement) != null) {\n            _ref.parentNode.removeChild(file.previewElement);\n          }\n        }\n        return this._updateMaxFilesReachedClass();\n      },\n      thumbnail: function(file, dataUrl) {\n        var thumbnailElement, _i, _len, _ref;\n        if (file.previewElement) {\n          file.previewElement.classList.remove(\"dz-file-preview\");\n          _ref = file.previewElement.querySelectorAll(\"[data-dz-thumbnail]\");\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            thumbnailElement = _ref[_i];\n            thumbnailElement.alt = file.name;\n            thumbnailElement.src = dataUrl;\n          }\n          return setTimeout(((function(_this) {\n            return function() {\n              return file.previewElement.classList.add(\"dz-image-preview\");\n            };\n          })(this)), 1);\n        }\n      },\n      error: function(file, message) {\n        var node, _i, _len, _ref, _results;\n        if (file.previewElement) {\n          file.previewElement.classList.add(\"dz-error\");\n          if (typeof message !== \"String\" && message.error) {\n            message = message.error;\n          }\n          _ref = file.previewElement.querySelectorAll(\"[data-dz-errormessage]\");\n          _results = [];\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            node = _ref[_i];\n            _results.push(node.textContent = message);\n          }\n          return _results;\n        }\n      },\n      errormultiple: noop,\n      processing: function(file) {\n        if (file.previewElement) {\n          file.previewElement.classList.add(\"dz-processing\");\n          if (file._removeLink) {\n            return file._removeLink.textContent = this.options.dictCancelUpload;\n          }\n        }\n      },\n      processingmultiple: noop,\n      uploadprogress: function(file, progress, bytesSent) {\n        var node, _i, _len, _ref, _results;\n        if (file.previewElement) {\n          _ref = file.previewElement.querySelectorAll(\"[data-dz-uploadprogress]\");\n          _results = [];\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            node = _ref[_i];\n            if (node.nodeName === 'PROGRESS') {\n              _results.push(node.value = progress);\n            } else {\n              _results.push(node.style.width = \"\" + progress + \"%\");\n            }\n          }\n          return _results;\n        }\n      },\n      totaluploadprogress: noop,\n      sending: noop,\n      sendingmultiple: noop,\n      success: function(file) {\n        if (file.previewElement) {\n          return file.previewElement.classList.add(\"dz-success\");\n        }\n      },\n      successmultiple: noop,\n      canceled: function(file) {\n        return this.emit(\"error\", file, \"Upload canceled.\");\n      },\n      canceledmultiple: noop,\n      complete: function(file) {\n        if (file._removeLink) {\n          file._removeLink.textContent = this.options.dictRemoveFile;\n        }\n        if (file.previewElement) {\n          return file.previewElement.classList.add(\"dz-complete\");\n        }\n      },\n      completemultiple: noop,\n      maxfilesexceeded: noop,\n      maxfilesreached: noop,\n      queuecomplete: noop,\n      addedfiles: noop,\n      previewTemplate: \"<div class=\\\"dz-preview dz-file-preview\\\">\\n  <div class=\\\"dz-image\\\"><img data-dz-thumbnail /></div>\\n  <div class=\\\"dz-details\\\">\\n    <div class=\\\"dz-size\\\"><span data-dz-size></span></div>\\n    <div class=\\\"dz-filename\\\"><span data-dz-name></span></div>\\n  </div>\\n  <div class=\\\"dz-progress\\\"><span class=\\\"dz-upload\\\" data-dz-uploadprogress></span></div>\\n  <div class=\\\"dz-error-message\\\"><span data-dz-errormessage></span></div>\\n  <div class=\\\"dz-success-mark\\\">\\n    <svg width=\\\"54px\\\" height=\\\"54px\\\" viewBox=\\\"0 0 54 54\\\" version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" xmlns:sketch=\\\"http://www.bohemiancoding.com/sketch/ns\\\">\\n      <title>Check</title>\\n      <defs></defs>\\n      <g id=\\\"Page-1\\\" stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" sketch:type=\\\"MSPage\\\">\\n        <path d=\\\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\\\" id=\\\"Oval-2\\\" stroke-opacity=\\\"0.198794158\\\" stroke=\\\"#747474\\\" fill-opacity=\\\"0.816519475\\\" fill=\\\"#FFFFFF\\\" sketch:type=\\\"MSShapeGroup\\\"></path>\\n      </g>\\n    </svg>\\n  </div>\\n  <div class=\\\"dz-error-mark\\\">\\n    <svg width=\\\"54px\\\" height=\\\"54px\\\" viewBox=\\\"0 0 54 54\\\" version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" xmlns:sketch=\\\"http://www.bohemiancoding.com/sketch/ns\\\">\\n      <title>Error</title>\\n      <defs></defs>\\n      <g id=\\\"Page-1\\\" stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" sketch:type=\\\"MSPage\\\">\\n        <g id=\\\"Check-+-Oval-2\\\" sketch:type=\\\"MSLayerGroup\\\" stroke=\\\"#747474\\\" stroke-opacity=\\\"0.198794158\\\" fill=\\\"#FFFFFF\\\" fill-opacity=\\\"0.816519475\\\">\\n          <path d=\\\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\\\" id=\\\"Oval-2\\\" sketch:type=\\\"MSShapeGroup\\\"></path>\\n        </g>\\n      </g>\\n    </svg>\\n  </div>\\n</div>\"\n    };\n\n    extend = function() {\n      var key, object, objects, target, val, _i, _len;\n      target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      for (_i = 0, _len = objects.length; _i < _len; _i++) {\n        object = objects[_i];\n        for (key in object) {\n          val = object[key];\n          target[key] = val;\n        }\n      }\n      return target;\n    };\n\n    function Dropzone(element, options) {\n      var elementOptions, fallback, _ref;\n      this.element = element;\n      this.version = Dropzone.version;\n      this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\\n*/g, \"\");\n      this.clickableElements = [];\n      this.listeners = [];\n      this.files = [];\n      if (typeof this.element === \"string\") {\n        this.element = document.querySelector(this.element);\n      }\n      if (!(this.element && (this.element.nodeType != null))) {\n        throw new Error(\"Invalid dropzone element.\");\n      }\n      if (this.element.dropzone) {\n        throw new Error(\"Dropzone already attached.\");\n      }\n      Dropzone.instances.push(this);\n      this.element.dropzone = this;\n      elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {};\n      this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});\n      if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {\n        return this.options.fallback.call(this);\n      }\n      if (this.options.url == null) {\n        this.options.url = this.element.getAttribute(\"action\");\n      }\n      if (!this.options.url) {\n        throw new Error(\"No URL provided.\");\n      }\n      if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {\n        throw new Error(\"You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.\");\n      }\n      if (this.options.acceptedMimeTypes) {\n        this.options.acceptedFiles = this.options.acceptedMimeTypes;\n        delete this.options.acceptedMimeTypes;\n      }\n      this.options.method = this.options.method.toUpperCase();\n      if ((fallback = this.getExistingFallback()) && fallback.parentNode) {\n        fallback.parentNode.removeChild(fallback);\n      }\n      if (this.options.previewsContainer !== false) {\n        if (this.options.previewsContainer) {\n          this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, \"previewsContainer\");\n        } else {\n          this.previewsContainer = this.element;\n        }\n      }\n      if (this.options.clickable) {\n        if (this.options.clickable === true) {\n          this.clickableElements = [this.element];\n        } else {\n          this.clickableElements = Dropzone.getElements(this.options.clickable, \"clickable\");\n        }\n      }\n      this.init();\n    }\n\n    Dropzone.prototype.getAcceptedFiles = function() {\n      var file, _i, _len, _ref, _results;\n      _ref = this.files;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        file = _ref[_i];\n        if (file.accepted) {\n          _results.push(file);\n        }\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.getRejectedFiles = function() {\n      var file, _i, _len, _ref, _results;\n      _ref = this.files;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        file = _ref[_i];\n        if (!file.accepted) {\n          _results.push(file);\n        }\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.getFilesWithStatus = function(status) {\n      var file, _i, _len, _ref, _results;\n      _ref = this.files;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        file = _ref[_i];\n        if (file.status === status) {\n          _results.push(file);\n        }\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.getQueuedFiles = function() {\n      return this.getFilesWithStatus(Dropzone.QUEUED);\n    };\n\n    Dropzone.prototype.getUploadingFiles = function() {\n      return this.getFilesWithStatus(Dropzone.UPLOADING);\n    };\n\n    Dropzone.prototype.getAddedFiles = function() {\n      return this.getFilesWithStatus(Dropzone.ADDED);\n    };\n\n    Dropzone.prototype.getActiveFiles = function() {\n      var file, _i, _len, _ref, _results;\n      _ref = this.files;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        file = _ref[_i];\n        if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) {\n          _results.push(file);\n        }\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.init = function() {\n      var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1;\n      if (this.element.tagName === \"form\") {\n        this.element.setAttribute(\"enctype\", \"multipart/form-data\");\n      }\n      if (this.element.classList.contains(\"dropzone\") && !this.element.querySelector(\".dz-message\")) {\n        this.element.appendChild(Dropzone.createElement(\"<div class=\\\"dz-default dz-message\\\"><span>\" + this.options.dictDefaultMessage + \"</span></div>\"));\n      }\n      if (this.clickableElements.length) {\n        setupHiddenFileInput = (function(_this) {\n          return function() {\n            if (_this.hiddenFileInput) {\n              _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput);\n            }\n            _this.hiddenFileInput = document.createElement(\"input\");\n            _this.hiddenFileInput.setAttribute(\"type\", \"file\");\n            if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {\n              _this.hiddenFileInput.setAttribute(\"multiple\", \"multiple\");\n            }\n            _this.hiddenFileInput.className = \"dz-hidden-input\";\n            if (_this.options.acceptedFiles != null) {\n              _this.hiddenFileInput.setAttribute(\"accept\", _this.options.acceptedFiles);\n            }\n            if (_this.options.capture != null) {\n              _this.hiddenFileInput.setAttribute(\"capture\", _this.options.capture);\n            }\n            _this.hiddenFileInput.style.visibility = \"hidden\";\n            _this.hiddenFileInput.style.position = \"absolute\";\n            _this.hiddenFileInput.style.top = \"0\";\n            _this.hiddenFileInput.style.left = \"0\";\n            _this.hiddenFileInput.style.height = \"0\";\n            _this.hiddenFileInput.style.width = \"0\";\n            document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput);\n            return _this.hiddenFileInput.addEventListener(\"change\", function() {\n              var file, files, _i, _len;\n              files = _this.hiddenFileInput.files;\n              if (files.length) {\n                for (_i = 0, _len = files.length; _i < _len; _i++) {\n                  file = files[_i];\n                  _this.addFile(file);\n                }\n              }\n              _this.emit(\"addedfiles\", files);\n              return setupHiddenFileInput();\n            });\n          };\n        })(this);\n        setupHiddenFileInput();\n      }\n      this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL;\n      _ref1 = this.events;\n      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n        eventName = _ref1[_i];\n        this.on(eventName, this.options[eventName]);\n      }\n      this.on(\"uploadprogress\", (function(_this) {\n        return function() {\n          return _this.updateTotalUploadProgress();\n        };\n      })(this));\n      this.on(\"removedfile\", (function(_this) {\n        return function() {\n          return _this.updateTotalUploadProgress();\n        };\n      })(this));\n      this.on(\"canceled\", (function(_this) {\n        return function(file) {\n          return _this.emit(\"complete\", file);\n        };\n      })(this));\n      this.on(\"complete\", (function(_this) {\n        return function(file) {\n          if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {\n            return setTimeout((function() {\n              return _this.emit(\"queuecomplete\");\n            }), 0);\n          }\n        };\n      })(this));\n      noPropagation = function(e) {\n        e.stopPropagation();\n        if (e.preventDefault) {\n          return e.preventDefault();\n        } else {\n          return e.returnValue = false;\n        }\n      };\n      this.listeners = [\n        {\n          element: this.element,\n          events: {\n            \"dragstart\": (function(_this) {\n              return function(e) {\n                return _this.emit(\"dragstart\", e);\n              };\n            })(this),\n            \"dragenter\": (function(_this) {\n              return function(e) {\n                noPropagation(e);\n                return _this.emit(\"dragenter\", e);\n              };\n            })(this),\n            \"dragover\": (function(_this) {\n              return function(e) {\n                var efct;\n                try {\n                  efct = e.dataTransfer.effectAllowed;\n                } catch (_error) {}\n                e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';\n                noPropagation(e);\n                return _this.emit(\"dragover\", e);\n              };\n            })(this),\n            \"dragleave\": (function(_this) {\n              return function(e) {\n                return _this.emit(\"dragleave\", e);\n              };\n            })(this),\n            \"drop\": (function(_this) {\n              return function(e) {\n                noPropagation(e);\n                return _this.drop(e);\n              };\n            })(this),\n            \"dragend\": (function(_this) {\n              return function(e) {\n                return _this.emit(\"dragend\", e);\n              };\n            })(this)\n          }\n        }\n      ];\n      this.clickableElements.forEach((function(_this) {\n        return function(clickableElement) {\n          return _this.listeners.push({\n            element: clickableElement,\n            events: {\n              \"click\": function(evt) {\n                if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(\".dz-message\")))) {\n                  _this.hiddenFileInput.click();\n                }\n                return true;\n              }\n            }\n          });\n        };\n      })(this));\n      this.enable();\n      return this.options.init.call(this);\n    };\n\n    Dropzone.prototype.destroy = function() {\n      var _ref;\n      this.disable();\n      this.removeAllFiles(true);\n      if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) {\n        this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);\n        this.hiddenFileInput = null;\n      }\n      delete this.element.dropzone;\n      return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);\n    };\n\n    Dropzone.prototype.updateTotalUploadProgress = function() {\n      var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref;\n      totalBytesSent = 0;\n      totalBytes = 0;\n      activeFiles = this.getActiveFiles();\n      if (activeFiles.length) {\n        _ref = this.getActiveFiles();\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          file = _ref[_i];\n          totalBytesSent += file.upload.bytesSent;\n          totalBytes += file.upload.total;\n        }\n        totalUploadProgress = 100 * totalBytesSent / totalBytes;\n      } else {\n        totalUploadProgress = 100;\n      }\n      return this.emit(\"totaluploadprogress\", totalUploadProgress, totalBytes, totalBytesSent);\n    };\n\n    Dropzone.prototype._getParamName = function(n) {\n      if (typeof this.options.paramName === \"function\") {\n        return this.options.paramName(n);\n      } else {\n        return \"\" + this.options.paramName + (this.options.uploadMultiple ? \"[\" + n + \"]\" : \"\");\n      }\n    };\n\n    Dropzone.prototype.getFallbackForm = function() {\n      var existingFallback, fields, fieldsString, form;\n      if (existingFallback = this.getExistingFallback()) {\n        return existingFallback;\n      }\n      fieldsString = \"<div class=\\\"dz-fallback\\\">\";\n      if (this.options.dictFallbackText) {\n        fieldsString += \"<p>\" + this.options.dictFallbackText + \"</p>\";\n      }\n      fieldsString += \"<input type=\\\"file\\\" name=\\\"\" + (this._getParamName(0)) + \"\\\" \" + (this.options.uploadMultiple ? 'multiple=\"multiple\"' : void 0) + \" /><input type=\\\"submit\\\" value=\\\"Upload!\\\"></div>\";\n      fields = Dropzone.createElement(fieldsString);\n      if (this.element.tagName !== \"FORM\") {\n        form = Dropzone.createElement(\"<form action=\\\"\" + this.options.url + \"\\\" enctype=\\\"multipart/form-data\\\" method=\\\"\" + this.options.method + \"\\\"></form>\");\n        form.appendChild(fields);\n      } else {\n        this.element.setAttribute(\"enctype\", \"multipart/form-data\");\n        this.element.setAttribute(\"method\", this.options.method);\n      }\n      return form != null ? form : fields;\n    };\n\n    Dropzone.prototype.getExistingFallback = function() {\n      var fallback, getFallback, tagName, _i, _len, _ref;\n      getFallback = function(elements) {\n        var el, _i, _len;\n        for (_i = 0, _len = elements.length; _i < _len; _i++) {\n          el = elements[_i];\n          if (/(^| )fallback($| )/.test(el.className)) {\n            return el;\n          }\n        }\n      };\n      _ref = [\"div\", \"form\"];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        tagName = _ref[_i];\n        if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {\n          return fallback;\n        }\n      }\n    };\n\n    Dropzone.prototype.setupEventListeners = function() {\n      var elementListeners, event, listener, _i, _len, _ref, _results;\n      _ref = this.listeners;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        elementListeners = _ref[_i];\n        _results.push((function() {\n          var _ref1, _results1;\n          _ref1 = elementListeners.events;\n          _results1 = [];\n          for (event in _ref1) {\n            listener = _ref1[event];\n            _results1.push(elementListeners.element.addEventListener(event, listener, false));\n          }\n          return _results1;\n        })());\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.removeEventListeners = function() {\n      var elementListeners, event, listener, _i, _len, _ref, _results;\n      _ref = this.listeners;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        elementListeners = _ref[_i];\n        _results.push((function() {\n          var _ref1, _results1;\n          _ref1 = elementListeners.events;\n          _results1 = [];\n          for (event in _ref1) {\n            listener = _ref1[event];\n            _results1.push(elementListeners.element.removeEventListener(event, listener, false));\n          }\n          return _results1;\n        })());\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.disable = function() {\n      var file, _i, _len, _ref, _results;\n      this.clickableElements.forEach(function(element) {\n        return element.classList.remove(\"dz-clickable\");\n      });\n      this.removeEventListeners();\n      _ref = this.files;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        file = _ref[_i];\n        _results.push(this.cancelUpload(file));\n      }\n      return _results;\n    };\n\n    Dropzone.prototype.enable = function() {\n      this.clickableElements.forEach(function(element) {\n        return element.classList.add(\"dz-clickable\");\n      });\n      return this.setupEventListeners();\n    };\n\n    Dropzone.prototype.filesize = function(size) {\n      var cutoff, i, selectedSize, selectedUnit, unit, units, _i, _len;\n      selectedSize = 0;\n      selectedUnit = \"b\";\n      if (size > 0) {\n        units = ['TB', 'GB', 'MB', 'KB', 'b'];\n        for (i = _i = 0, _len = units.length; _i < _len; i = ++_i) {\n          unit = units[i];\n          cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;\n          if (size >= cutoff) {\n            selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);\n            selectedUnit = unit;\n            break;\n          }\n        }\n        selectedSize = Math.round(10 * selectedSize) / 10;\n      }\n      return \"<strong>\" + selectedSize + \"</strong> \" + selectedUnit;\n    };\n\n    Dropzone.prototype._updateMaxFilesReachedClass = function() {\n      if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {\n        if (this.getAcceptedFiles().length === this.options.maxFiles) {\n          this.emit('maxfilesreached', this.files);\n        }\n        return this.element.classList.add(\"dz-max-files-reached\");\n      } else {\n        return this.element.classList.remove(\"dz-max-files-reached\");\n      }\n    };\n\n    Dropzone.prototype.drop = function(e) {\n      var files, items;\n      if (!e.dataTransfer) {\n        return;\n      }\n      this.emit(\"drop\", e);\n      files = e.dataTransfer.files;\n      this.emit(\"addedfiles\", files);\n      if (files.length) {\n        items = e.dataTransfer.items;\n        if (items && items.length && (items[0].webkitGetAsEntry != null)) {\n          this._addFilesFromItems(items);\n        } else {\n          this.handleFiles(files);\n        }\n      }\n    };\n\n    Dropzone.prototype.paste = function(e) {\n      var items, _ref;\n      if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) {\n        return;\n      }\n      this.emit(\"paste\", e);\n      items = e.clipboardData.items;\n      if (items.length) {\n        return this._addFilesFromItems(items);\n      }\n    };\n\n    Dropzone.prototype.handleFiles = function(files) {\n      var file, _i, _len, _results;\n      _results = [];\n      for (_i = 0, _len = files.length; _i < _len; _i++) {\n        file = files[_i];\n        _results.push(this.addFile(file));\n      }\n      return _results;\n    };\n\n    Dropzone.prototype._addFilesFromItems = function(items) {\n      var entry, item, _i, _len, _results;\n      _results = [];\n      for (_i = 0, _len = items.length; _i < _len; _i++) {\n        item = items[_i];\n        if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) {\n          if (entry.isFile) {\n            _results.push(this.addFile(item.getAsFile()));\n          } else if (entry.isDirectory) {\n            _results.push(this._addFilesFromDirectory(entry, entry.name));\n          } else {\n            _results.push(void 0);\n          }\n        } else if (item.getAsFile != null) {\n          if ((item.kind == null) || item.kind === \"file\") {\n            _results.push(this.addFile(item.getAsFile()));\n          } else {\n            _results.push(void 0);\n          }\n        } else {\n          _results.push(void 0);\n        }\n      }\n      return _results;\n    };\n\n    Dropzone.prototype._addFilesFromDirectory = function(directory, path) {\n      var dirReader, entriesReader;\n      dirReader = directory.createReader();\n      entriesReader = (function(_this) {\n        return function(entries) {\n          var entry, _i, _len;\n          for (_i = 0, _len = entries.length; _i < _len; _i++) {\n            entry = entries[_i];\n            if (entry.isFile) {\n              entry.file(function(file) {\n                if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {\n                  return;\n                }\n                file.fullPath = \"\" + path + \"/\" + file.name;\n                return _this.addFile(file);\n              });\n            } else if (entry.isDirectory) {\n              _this._addFilesFromDirectory(entry, \"\" + path + \"/\" + entry.name);\n            }\n          }\n        };\n      })(this);\n      return dirReader.readEntries(entriesReader, function(error) {\n        return typeof console !== \"undefined\" && console !== null ? typeof console.log === \"function\" ? console.log(error) : void 0 : void 0;\n      });\n    };\n\n    Dropzone.prototype.accept = function(file, done) {\n      if (file.size > this.options.maxFilesize * 1024 * 1024) {\n        return done(this.options.dictFileTooBig.replace(\"{{filesize}}\", Math.round(file.size / 1024 / 10.24) / 100).replace(\"{{maxFilesize}}\", this.options.maxFilesize));\n      } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {\n        return done(this.options.dictInvalidFileType);\n      } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {\n        done(this.options.dictMaxFilesExceeded.replace(\"{{maxFiles}}\", this.options.maxFiles));\n        return this.emit(\"maxfilesexceeded\", file);\n      } else {\n        return this.options.accept.call(this, file, done);\n      }\n    };\n\n    Dropzone.prototype.addFile = function(file) {\n      file.upload = {\n        progress: 0,\n        total: file.size,\n        bytesSent: 0\n      };\n      this.files.push(file);\n      file.status = Dropzone.ADDED;\n      this.emit(\"addedfile\", file);\n      this._enqueueThumbnail(file);\n      return this.accept(file, (function(_this) {\n        return function(error) {\n          if (error) {\n            file.accepted = false;\n            _this._errorProcessing([file], error);\n          } else {\n            file.accepted = true;\n            if (_this.options.autoQueue) {\n              _this.enqueueFile(file);\n            }\n          }\n          return _this._updateMaxFilesReachedClass();\n        };\n      })(this));\n    };\n\n    Dropzone.prototype.enqueueFiles = function(files) {\n      var file, _i, _len;\n      for (_i = 0, _len = files.length; _i < _len; _i++) {\n        file = files[_i];\n        this.enqueueFile(file);\n      }\n      return null;\n    };\n\n    Dropzone.prototype.enqueueFile = function(file) {\n      if (file.status === Dropzone.ADDED && file.accepted === true) {\n        file.status = Dropzone.QUEUED;\n        if (this.options.autoProcessQueue) {\n          return setTimeout(((function(_this) {\n            return function() {\n              return _this.processQueue();\n            };\n          })(this)), 0);\n        }\n      } else {\n        throw new Error(\"This file can't be queued because it has already been processed or was rejected.\");\n      }\n    };\n\n    Dropzone.prototype._thumbnailQueue = [];\n\n    Dropzone.prototype._processingThumbnail = false;\n\n    Dropzone.prototype._enqueueThumbnail = function(file) {\n      if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {\n        this._thumbnailQueue.push(file);\n        return setTimeout(((function(_this) {\n          return function() {\n            return _this._processThumbnailQueue();\n          };\n        })(this)), 0);\n      }\n    };\n\n    Dropzone.prototype._processThumbnailQueue = function() {\n      if (this._processingThumbnail || this._thumbnailQueue.length === 0) {\n        return;\n      }\n      this._processingThumbnail = true;\n      return this.createThumbnail(this._thumbnailQueue.shift(), (function(_this) {\n        return function() {\n          _this._processingThumbnail = false;\n          return _this._processThumbnailQueue();\n        };\n      })(this));\n    };\n\n    Dropzone.prototype.removeFile = function(file) {\n      if (file.status === Dropzone.UPLOADING) {\n        this.cancelUpload(file);\n      }\n      this.files = without(this.files, file);\n      this.emit(\"removedfile\", file);\n      if (this.files.length === 0) {\n        return this.emit(\"reset\");\n      }\n    };\n\n    Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {\n      var file, _i, _len, _ref;\n      if (cancelIfNecessary == null) {\n        cancelIfNecessary = false;\n      }\n      _ref = this.files.slice();\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        file = _ref[_i];\n        if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {\n          this.removeFile(file);\n        }\n      }\n      return null;\n    };\n\n    Dropzone.prototype.createThumbnail = function(file, callback) {\n      var fileReader;\n      fileReader = new FileReader;\n      fileReader.onload = (function(_this) {\n        return function() {\n          if (file.type === \"image/svg+xml\") {\n            _this.emit(\"thumbnail\", file, fileReader.result);\n            if (callback != null) {\n              callback();\n            }\n            return;\n          }\n          return _this.createThumbnailFromUrl(file, fileReader.result, callback);\n        };\n      })(this);\n      return fileReader.readAsDataURL(file);\n    };\n\n    Dropzone.prototype.createThumbnailFromUrl = function(file, imageUrl, callback, crossOrigin) {\n      var img;\n      img = document.createElement(\"img\");\n      if (crossOrigin) {\n        img.crossOrigin = crossOrigin;\n      }\n      img.onload = (function(_this) {\n        return function() {\n          var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3;\n          file.width = img.width;\n          file.height = img.height;\n          resizeInfo = _this.options.resize.call(_this, file);\n          if (resizeInfo.trgWidth == null) {\n            resizeInfo.trgWidth = resizeInfo.optWidth;\n          }\n          if (resizeInfo.trgHeight == null) {\n            resizeInfo.trgHeight = resizeInfo.optHeight;\n          }\n          canvas = document.createElement(\"canvas\");\n          ctx = canvas.getContext(\"2d\");\n          canvas.width = resizeInfo.trgWidth;\n          canvas.height = resizeInfo.trgHeight;\n          drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);\n          thumbnail = canvas.toDataURL(\"image/png\");\n          _this.emit(\"thumbnail\", file, thumbnail);\n          if (callback != null) {\n            return callback();\n          }\n        };\n      })(this);\n      if (callback != null) {\n        img.onerror = callback;\n      }\n      return img.src = imageUrl;\n    };\n\n    Dropzone.prototype.processQueue = function() {\n      var i, parallelUploads, processingLength, queuedFiles;\n      parallelUploads = this.options.parallelUploads;\n      processingLength = this.getUploadingFiles().length;\n      i = processingLength;\n      if (processingLength >= parallelUploads) {\n        return;\n      }\n      queuedFiles = this.getQueuedFiles();\n      if (!(queuedFiles.length > 0)) {\n        return;\n      }\n      if (this.options.uploadMultiple) {\n        return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));\n      } else {\n        while (i < parallelUploads) {\n          if (!queuedFiles.length) {\n            return;\n          }\n          this.processFile(queuedFiles.shift());\n          i++;\n        }\n      }\n    };\n\n    Dropzone.prototype.processFile = function(file) {\n      return this.processFiles([file]);\n    };\n\n    Dropzone.prototype.processFiles = function(files) {\n      var file, _i, _len;\n      for (_i = 0, _len = files.length; _i < _len; _i++) {\n        file = files[_i];\n        file.processing = true;\n        file.status = Dropzone.UPLOADING;\n        this.emit(\"processing\", file);\n      }\n      if (this.options.uploadMultiple) {\n        this.emit(\"processingmultiple\", files);\n      }\n      return this.uploadFiles(files);\n    };\n\n    Dropzone.prototype._getFilesWithXhr = function(xhr) {\n      var file, files;\n      return files = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.files;\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          file = _ref[_i];\n          if (file.xhr === xhr) {\n            _results.push(file);\n          }\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Dropzone.prototype.cancelUpload = function(file) {\n      var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref;\n      if (file.status === Dropzone.UPLOADING) {\n        groupedFiles = this._getFilesWithXhr(file.xhr);\n        for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) {\n          groupedFile = groupedFiles[_i];\n          groupedFile.status = Dropzone.CANCELED;\n        }\n        file.xhr.abort();\n        for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) {\n          groupedFile = groupedFiles[_j];\n          this.emit(\"canceled\", groupedFile);\n        }\n        if (this.options.uploadMultiple) {\n          this.emit(\"canceledmultiple\", groupedFiles);\n        }\n      } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) {\n        file.status = Dropzone.CANCELED;\n        this.emit(\"canceled\", file);\n        if (this.options.uploadMultiple) {\n          this.emit(\"canceledmultiple\", [file]);\n        }\n      }\n      if (this.options.autoProcessQueue) {\n        return this.processQueue();\n      }\n    };\n\n    resolveOption = function() {\n      var args, option;\n      option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      if (typeof option === 'function') {\n        return option.apply(this, args);\n      }\n      return option;\n    };\n\n    Dropzone.prototype.uploadFile = function(file) {\n      return this.uploadFiles([file]);\n    };\n\n    Dropzone.prototype.uploadFiles = function(files) {\n      var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;\n      xhr = new XMLHttpRequest();\n      for (_i = 0, _len = files.length; _i < _len; _i++) {\n        file = files[_i];\n        file.xhr = xhr;\n      }\n      method = resolveOption(this.options.method, files);\n      url = resolveOption(this.options.url, files);\n      xhr.open(method, url, true);\n      xhr.withCredentials = !!this.options.withCredentials;\n      response = null;\n      handleError = (function(_this) {\n        return function() {\n          var _j, _len1, _results;\n          _results = [];\n          for (_j = 0, _len1 = files.length; _j < _len1; _j++) {\n            file = files[_j];\n            _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace(\"{{statusCode}}\", xhr.status), xhr));\n          }\n          return _results;\n        };\n      })(this);\n      updateProgress = (function(_this) {\n        return function(e) {\n          var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results;\n          if (e != null) {\n            progress = 100 * e.loaded / e.total;\n            for (_j = 0, _len1 = files.length; _j < _len1; _j++) {\n              file = files[_j];\n              file.upload = {\n                progress: progress,\n                total: e.total,\n                bytesSent: e.loaded\n              };\n            }\n          } else {\n            allFilesFinished = true;\n            progress = 100;\n            for (_k = 0, _len2 = files.length; _k < _len2; _k++) {\n              file = files[_k];\n              if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {\n                allFilesFinished = false;\n              }\n              file.upload.progress = progress;\n              file.upload.bytesSent = file.upload.total;\n            }\n            if (allFilesFinished) {\n              return;\n            }\n          }\n          _results = [];\n          for (_l = 0, _len3 = files.length; _l < _len3; _l++) {\n            file = files[_l];\n            _results.push(_this.emit(\"uploadprogress\", file, progress, file.upload.bytesSent));\n          }\n          return _results;\n        };\n      })(this);\n      xhr.onload = (function(_this) {\n        return function(e) {\n          var _ref;\n          if (files[0].status === Dropzone.CANCELED) {\n            return;\n          }\n          if (xhr.readyState !== 4) {\n            return;\n          }\n          response = xhr.responseText;\n          if (xhr.getResponseHeader(\"content-type\") && ~xhr.getResponseHeader(\"content-type\").indexOf(\"application/json\")) {\n            try {\n              response = JSON.parse(response);\n            } catch (_error) {\n              e = _error;\n              response = \"Invalid JSON response from server.\";\n            }\n          }\n          updateProgress();\n          if (!((200 <= (_ref = xhr.status) && _ref < 300))) {\n            return handleError();\n          } else {\n            return _this._finished(files, response, e);\n          }\n        };\n      })(this);\n      xhr.onerror = (function(_this) {\n        return function() {\n          if (files[0].status === Dropzone.CANCELED) {\n            return;\n          }\n          return handleError();\n        };\n      })(this);\n      progressObj = (_ref = xhr.upload) != null ? _ref : xhr;\n      progressObj.onprogress = updateProgress;\n      headers = {\n        \"Accept\": \"application/json\",\n        \"Cache-Control\": \"no-cache\",\n        \"X-Requested-With\": \"XMLHttpRequest\"\n      };\n      if (this.options.headers) {\n        extend(headers, this.options.headers);\n      }\n      for (headerName in headers) {\n        headerValue = headers[headerName];\n        if (headerValue) {\n          xhr.setRequestHeader(headerName, headerValue);\n        }\n      }\n      formData = new FormData();\n      if (this.options.params) {\n        _ref1 = this.options.params;\n        for (key in _ref1) {\n          value = _ref1[key];\n          formData.append(key, value);\n        }\n      }\n      for (_j = 0, _len1 = files.length; _j < _len1; _j++) {\n        file = files[_j];\n        this.emit(\"sending\", file, xhr, formData);\n      }\n      if (this.options.uploadMultiple) {\n        this.emit(\"sendingmultiple\", files, xhr, formData);\n      }\n      if (this.element.tagName === \"FORM\") {\n        _ref2 = this.element.querySelectorAll(\"input, textarea, select, button\");\n        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {\n          input = _ref2[_k];\n          inputName = input.getAttribute(\"name\");\n          inputType = input.getAttribute(\"type\");\n          if (input.tagName === \"SELECT\" && input.hasAttribute(\"multiple\")) {\n            _ref3 = input.options;\n            for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {\n              option = _ref3[_l];\n              if (option.selected) {\n                formData.append(inputName, option.value);\n              }\n            }\n          } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== \"checkbox\" && _ref4 !== \"radio\") || input.checked) {\n            formData.append(inputName, input.value);\n          }\n        }\n      }\n      for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) {\n        formData.append(this._getParamName(i), files[i], files[i].name);\n      }\n      return this.submitRequest(xhr, formData, files);\n    };\n\n    Dropzone.prototype.submitRequest = function(xhr, formData, files) {\n      return xhr.send(formData);\n    };\n\n    Dropzone.prototype._finished = function(files, responseText, e) {\n      var file, _i, _len;\n      for (_i = 0, _len = files.length; _i < _len; _i++) {\n        file = files[_i];\n        file.status = Dropzone.SUCCESS;\n        this.emit(\"success\", file, responseText, e);\n        this.emit(\"complete\", file);\n      }\n      if (this.options.uploadMultiple) {\n        this.emit(\"successmultiple\", files, responseText, e);\n        this.emit(\"completemultiple\", files);\n      }\n      if (this.options.autoProcessQueue) {\n        return this.processQueue();\n      }\n    };\n\n    Dropzone.prototype._errorProcessing = function(files, message, xhr) {\n      var file, _i, _len;\n      for (_i = 0, _len = files.length; _i < _len; _i++) {\n        file = files[_i];\n        file.status = Dropzone.ERROR;\n        this.emit(\"error\", file, message, xhr);\n        this.emit(\"complete\", file);\n      }\n      if (this.options.uploadMultiple) {\n        this.emit(\"errormultiple\", files, message, xhr);\n        this.emit(\"completemultiple\", files);\n      }\n      if (this.options.autoProcessQueue) {\n        return this.processQueue();\n      }\n    };\n\n    return Dropzone;\n\n  })(Emitter);\n\n  Dropzone.version = \"4.2.0\";\n\n  Dropzone.options = {};\n\n  Dropzone.optionsForElement = function(element) {\n    if (element.getAttribute(\"id\")) {\n      return Dropzone.options[camelize(element.getAttribute(\"id\"))];\n    } else {\n      return void 0;\n    }\n  };\n\n  Dropzone.instances = [];\n\n  Dropzone.forElement = function(element) {\n    if (typeof element === \"string\") {\n      element = document.querySelector(element);\n    }\n    if ((element != null ? element.dropzone : void 0) == null) {\n      throw new Error(\"No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.\");\n    }\n    return element.dropzone;\n  };\n\n  Dropzone.autoDiscover = true;\n\n  Dropzone.discover = function() {\n    var checkElements, dropzone, dropzones, _i, _len, _results;\n    if (document.querySelectorAll) {\n      dropzones = document.querySelectorAll(\".dropzone\");\n    } else {\n      dropzones = [];\n      checkElements = function(elements) {\n        var el, _i, _len, _results;\n        _results = [];\n        for (_i = 0, _len = elements.length; _i < _len; _i++) {\n          el = elements[_i];\n          if (/(^| )dropzone($| )/.test(el.className)) {\n            _results.push(dropzones.push(el));\n          } else {\n            _results.push(void 0);\n          }\n        }\n        return _results;\n      };\n      checkElements(document.getElementsByTagName(\"div\"));\n      checkElements(document.getElementsByTagName(\"form\"));\n    }\n    _results = [];\n    for (_i = 0, _len = dropzones.length; _i < _len; _i++) {\n      dropzone = dropzones[_i];\n      if (Dropzone.optionsForElement(dropzone) !== false) {\n        _results.push(new Dropzone(dropzone));\n      } else {\n        _results.push(void 0);\n      }\n    }\n    return _results;\n  };\n\n  Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\\/12/i];\n\n  Dropzone.isBrowserSupported = function() {\n    var capableBrowser, regex, _i, _len, _ref;\n    capableBrowser = true;\n    if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {\n      if (!(\"classList\" in document.createElement(\"a\"))) {\n        capableBrowser = false;\n      } else {\n        _ref = Dropzone.blacklistedBrowsers;\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          regex = _ref[_i];\n          if (regex.test(navigator.userAgent)) {\n            capableBrowser = false;\n            continue;\n          }\n        }\n      }\n    } else {\n      capableBrowser = false;\n    }\n    return capableBrowser;\n  };\n\n  without = function(list, rejectedItem) {\n    var item, _i, _len, _results;\n    _results = [];\n    for (_i = 0, _len = list.length; _i < _len; _i++) {\n      item = list[_i];\n      if (item !== rejectedItem) {\n        _results.push(item);\n      }\n    }\n    return _results;\n  };\n\n  camelize = function(str) {\n    return str.replace(/[\\-_](\\w)/g, function(match) {\n      return match.charAt(1).toUpperCase();\n    });\n  };\n\n  Dropzone.createElement = function(string) {\n    var div;\n    div = document.createElement(\"div\");\n    div.innerHTML = string;\n    return div.childNodes[0];\n  };\n\n  Dropzone.elementInside = function(element, container) {\n    if (element === container) {\n      return true;\n    }\n    while (element = element.parentNode) {\n      if (element === container) {\n        return true;\n      }\n    }\n    return false;\n  };\n\n  Dropzone.getElement = function(el, name) {\n    var element;\n    if (typeof el === \"string\") {\n      element = document.querySelector(el);\n    } else if (el.nodeType != null) {\n      element = el;\n    }\n    if (element == null) {\n      throw new Error(\"Invalid `\" + name + \"` option provided. Please provide a CSS selector or a plain HTML element.\");\n    }\n    return element;\n  };\n\n  Dropzone.getElements = function(els, name) {\n    var e, el, elements, _i, _j, _len, _len1, _ref;\n    if (els instanceof Array) {\n      elements = [];\n      try {\n        for (_i = 0, _len = els.length; _i < _len; _i++) {\n          el = els[_i];\n          elements.push(this.getElement(el, name));\n        }\n      } catch (_error) {\n        e = _error;\n        elements = null;\n      }\n    } else if (typeof els === \"string\") {\n      elements = [];\n      _ref = document.querySelectorAll(els);\n      for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {\n        el = _ref[_j];\n        elements.push(el);\n      }\n    } else if (els.nodeType != null) {\n      elements = [els];\n    }\n    if (!((elements != null) && elements.length)) {\n      throw new Error(\"Invalid `\" + name + \"` option provided. Please provide a CSS selector, a plain HTML element or a list of those.\");\n    }\n    return elements;\n  };\n\n  Dropzone.confirm = function(question, accepted, rejected) {\n    if (window.confirm(question)) {\n      return accepted();\n    } else if (rejected != null) {\n      return rejected();\n    }\n  };\n\n  Dropzone.isValidFile = function(file, acceptedFiles) {\n    var baseMimeType, mimeType, validType, _i, _len;\n    if (!acceptedFiles) {\n      return true;\n    }\n    acceptedFiles = acceptedFiles.split(\",\");\n    mimeType = file.type;\n    baseMimeType = mimeType.replace(/\\/.*$/, \"\");\n    for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {\n      validType = acceptedFiles[_i];\n      validType = validType.trim();\n      if (validType.charAt(0) === \".\") {\n        if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {\n          return true;\n        }\n      } else if (/\\/\\*$/.test(validType)) {\n        if (baseMimeType === validType.replace(/\\/.*$/, \"\")) {\n          return true;\n        }\n      } else {\n        if (mimeType === validType) {\n          return true;\n        }\n      }\n    }\n    return false;\n  };\n\n  if (typeof jQuery !== \"undefined\" && jQuery !== null) {\n    jQuery.fn.dropzone = function(options) {\n      return this.each(function() {\n        return new Dropzone(this, options);\n      });\n    };\n  }\n\n  if (typeof module !== \"undefined\" && module !== null) {\n    module.exports = Dropzone;\n  } else {\n    window.Dropzone = Dropzone;\n  }\n\n  Dropzone.ADDED = \"added\";\n\n  Dropzone.QUEUED = \"queued\";\n\n  Dropzone.ACCEPTED = Dropzone.QUEUED;\n\n  Dropzone.UPLOADING = \"uploading\";\n\n  Dropzone.PROCESSING = Dropzone.UPLOADING;\n\n  Dropzone.CANCELED = \"canceled\";\n\n  Dropzone.ERROR = \"error\";\n\n  Dropzone.SUCCESS = \"success\";\n\n\n  /*\n  \n  Bugfix for iOS 6 and 7\n  Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios\n  based on the work of https://github.com/stomita/ios-imagefile-megapixel\n   */\n\n  detectVerticalSquash = function(img) {\n    var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;\n    iw = img.naturalWidth;\n    ih = img.naturalHeight;\n    canvas = document.createElement(\"canvas\");\n    canvas.width = 1;\n    canvas.height = ih;\n    ctx = canvas.getContext(\"2d\");\n    ctx.drawImage(img, 0, 0);\n    data = ctx.getImageData(0, 0, 1, ih).data;\n    sy = 0;\n    ey = ih;\n    py = ih;\n    while (py > sy) {\n      alpha = data[(py - 1) * 4 + 3];\n      if (alpha === 0) {\n        ey = py;\n      } else {\n        sy = py;\n      }\n      py = (ey + sy) >> 1;\n    }\n    ratio = py / ih;\n    if (ratio === 0) {\n      return 1;\n    } else {\n      return ratio;\n    }\n  };\n\n  drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {\n    var vertSquashRatio;\n    vertSquashRatio = detectVerticalSquash(img);\n    return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);\n  };\n\n\n  /*\n   * contentloaded.js\n   *\n   * Author: Diego Perini (diego.perini at gmail.com)\n   * Summary: cross-browser wrapper for DOMContentLoaded\n   * Updated: 20101020\n   * License: MIT\n   * Version: 1.2\n   *\n   * URL:\n   * http://javascript.nwbox.com/ContentLoaded/\n   * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE\n   */\n\n  contentLoaded = function(win, fn) {\n    var add, doc, done, init, poll, pre, rem, root, top;\n    done = false;\n    top = true;\n    doc = win.document;\n    root = doc.documentElement;\n    add = (doc.addEventListener ? \"addEventListener\" : \"attachEvent\");\n    rem = (doc.addEventListener ? \"removeEventListener\" : \"detachEvent\");\n    pre = (doc.addEventListener ? \"\" : \"on\");\n    init = function(e) {\n      if (e.type === \"readystatechange\" && doc.readyState !== \"complete\") {\n        return;\n      }\n      (e.type === \"load\" ? win : doc)[rem](pre + e.type, init, false);\n      if (!done && (done = true)) {\n        return fn.call(win, e.type || e);\n      }\n    };\n    poll = function() {\n      var e;\n      try {\n        root.doScroll(\"left\");\n      } catch (_error) {\n        e = _error;\n        setTimeout(poll, 50);\n        return;\n      }\n      return init(\"poll\");\n    };\n    if (doc.readyState !== \"complete\") {\n      if (doc.createEventObject && root.doScroll) {\n        try {\n          top = !win.frameElement;\n        } catch (_error) {}\n        if (top) {\n          poll();\n        }\n      }\n      doc[add](pre + \"DOMContentLoaded\", init, false);\n      doc[add](pre + \"readystatechange\", init, false);\n      return win[add](pre + \"load\", init, false);\n    }\n  };\n\n  Dropzone._autoDiscoverFunction = function() {\n    if (Dropzone.autoDiscover) {\n      return Dropzone.discover();\n    }\n  };\n\n  contentLoaded(window, Dropzone._autoDiscoverFunction);\n\n}).call(this);\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/dropzone/dist/dropzone.js\n ** module id = 549\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/6/15.\n */\n'use strict';\n\nimport React from 'react'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport ClassNames from 'classnames'\n\nconst DropTarget = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {isDragHover: false};\n\t},\n\tgetDefaultProps() {\n\t\treturn {onDrop: () => {}, dropZone: null, className: 'DropTarget'};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t\tif (this.props.dropZone) {\n\t\t\tconst dropTarget = this;\n\t\t\tconst dropZone = this.props.dropZone(dropTarget);\n\t\t\tdropZone.on('dragover', this.onDragOver);\n\t\t\tdropZone.on('dragleave', this.onDragLeave);\n\t\t\tdropZone.on('dragend', this.onDragEnd);\n\t\t\tdropZone.on('drop', this.onDrop);\n\t\t}\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\trender() {\n\t\tconst classNames = ClassNames(this.props.className, 'dnd-target', {'-drag-hover': this.state.isDragHover});\n\t\treturn (\n\t\t\t\t<div className={classNames}\n\t\t\t\t\t onDrop={this.onDrop}\n\t\t\t\t\t onDragEnd={this.onDragEnd}\n\t\t\t\t\t onMouseOut={this.onDragEnd}\n\t\t\t\t\t onDragExit={this.onDragEnd}\n\t\t\t\t\t onDragOver={this.onDragOver}\n\t\t\t\t\t onDragLeave={this.onDragLeave}>{this.props.children}</div>\n\t\t);\n\t},\n\tonDragOver(e) {\n\t\t// NOTE calling preventDefault makes this a valid drop target\n\t\te.preventDefault();\n\t\te.dataTransfer.dropEffect = 'copy';\n\t\tthis.setState({isDragHover: true});\n\t},\n\tonDragLeave() {\n\t\tthis.setState({isDragHover: false});\n\t},\n\tonDragEnd() {\n\t\tthis.setState({isDragHover: false});\n\t},\n\tonDrop(e) {\n\t\tthis.setState({isDragHover: false});\n\t\tthis.props.onDrop(e);\n\t}\n});\n\nexport default DropTarget;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/DropTarget.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 11/6/15.\n */\n'use strict';\n\nimport React from 'react'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport ClassNames from 'classnames'\n\nimport '../styles/DropZonePanel.scss'\n\nconst DropZonePanel = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {};\n\t},\n\tgetDefaultProps() {\n\t\treturn {show: false, className: 'DropZonePanel', title: 'Drop files to upload.'};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\trender() {\n\t\tconst classNames = ClassNames(this.props.className, {'-close': !this.props.show});\n\t\treturn (\n\t\t\t<div className={classNames}>\n\t\t\t\t<div className=\"dz-default dz-message\">\n\t\t\t\t\t<span>{this.props.title}</span>\n\t\t\t\t</div>\n\t\t\t\t{this.props.children}\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default DropZonePanel;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/DropZonePanel.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DropZonePanel.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DropZonePanel.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DropZonePanel.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/DropZonePanel.scss\n ** module id = 552\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.DropZonePanel {\\n  overflow: hidden;\\n  display: flex;\\n  flex-wrap: wrap;\\n  flex-direction: column;\\n  align-content: stretch;\\n}\\n\\n.DropZonePanel.-close {\\n  display: none;\\n}\\n\\n.DropZonePanel .dz-message {\\n  font-size: small;\\n  margin: 2px;\\n  text-align: center;\\n}\\n\\n.DropZonePanel .dnd-target {\\n  flex-grow: 4;\\n  display: block;\\n  margin: 4px;\\n  padding: 25px 20px;\\n  color: #666;\\n  border: 2px dashed #afafb9;\\n  border-radius: 8px;\\n  background-color: #cbd1d1;\\n}\\n\\n.DropZonePanel .dnd-target:hover {\\n  border: 2px dashed #797989;\\n  background-color: #e1e1e1;\\n}\\n\\n.DropZonePanel .dnd-target.-drag-hover,\\n.DropZonePanel .dnd-target.dz-drag-hover {\\n  cursor: pointer !important;\\n  border-color: #797989;\\n  background-color: #95a1a1;\\n  color: #333333;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/DropZonePanel.scss\n ** module id = 553\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react'\nimport messages from './messages'\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogDataStore from '../stores/CatalogDataStore'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport SelectionManager from '../libraries/SelectionManager'\n\nimport '../styles/CatalogItems.scss'\nimport imgFile from 'file!../images/vendor-riftio.png'\n\nconst CatalogItems = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn CatalogDataStore.getState();\n\t},\n\tgetDefaultProps() {\n\t\treturn {\n\t\t\tfilterByType: 'nsd'\n\t\t};\n\t},\n\tcomponentWillMount() {\n\t\tCatalogDataStore.listen(this.onChange);\n\t\tdocument.body.addEventListener('click', this.onClickBody);\n\t},\n\tcomponentDidMount() {\n\t\t// async actions creator will dispatch loadCatalogsSuccess and loadCatalogsError messages\n\t\tCatalogDataStore.loadCatalogs().catch(e => console.warn('unable to load catalogs', e));\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t\tCatalogDataStore.unlisten(this.onChange);\n\t\tdocument.body.removeEventListener('click', this.onClickBody);\n\t},\n\tonChange(state) {\n\t\tthis.setState(state);\n\t},\n\tonClickBody(e) {\n\t\tif (e.target.nodeName === 'DIV') {\n\t\t\t// user did not click a button so it is most\n\t\t\t// likely safe to deselect the catalog items\n\t\t\tCatalogItemsActions.selectCatalogItem({});\n\t\t}\n\t},\n\trender() {\n\t\tconst onDragStart = function(event) {\n\t\t\tconst data = {type: 'catalog-item', item: this};\n\t\t\tevent.dataTransfer.effectAllowed = 'copy';\n\t\t\tevent.dataTransfer.setData('text', JSON.stringify(data));\n\t\t\tComposerAppActions.setDragState(data);\n\t\t};\n\t\tconst onDblClickCatalogItem = function () {\n\t\t\t//SelectionManager.clearSelectionAndRemoveOutline();\n\t\t\t//ComposerAppActions.selectModel(this);\n\t\t\tCatalogItemsActions.editCatalogItem(this);\n\t\t\t//ComposerAppActions.outlineModel(this);\n\t\t};\n\t\tconst onClickCatalogItem = function () {\n\t\t\tCatalogItemsActions.selectCatalogItem(this);\n\t\t};\n\t\tconst cleanDataURI = this.cleanDataURI;\n\t\tconst items = this.getCatalogItems().map(function (d) {\n\t\t\tconst isNSD = d.meta.type === 'nsd';\n\t\t\tconst isDeleted = d.meta.deleted;\n\t\t\tconst isModified = d.meta.modified;\n\t\t\tconst isSelected = SelectionManager.isSelected(d);// d.meta.selected;\n\t\t\tconst isOpenForEdit = d.meta.isOpenForEdit;\n\t\t\tconst spanClassNames = ClassNames({'-is-selected': isSelected, '-is-open-for-edit': isOpenForEdit});\n\t\t\tconst sectionClassNames = ClassNames('catalog-item', {'-is-modified': isModified, '-is-deleted': isDeleted});\n\t\t\tconst instanceCount = d.meta['instance-ref-count'];\n\t\t\tconst instanceCountLabel = isNSD && instanceCount ? <span>({instanceCount})</span> : null;\n\t\t\treturn (\n\t\t\t\t<li key={d.id} onClick={onClickCatalogItem.bind(d)} onDoubleClick={onDblClickCatalogItem.bind(d)}>\n\t\t\t\t\t<div className={spanClassNames}>\n\t\t\t\t\t\t<div className={sectionClassNames} id={d.id} draggable=\"true\" onDragStart={onDragStart.bind(d)}>\n\t\t\t\t\t\t\t{isModified ? <div className=\"-is-modified-indicator\" title=\"This descriptor has changes.\"></div> : null}\n\t\t\t\t\t\t\t<dl>\n\t\t\t\t\t\t\t\t<dt>{d.name} {instanceCountLabel}</dt>\n\t\t\t\t\t\t\t\t<dd className=\"icon\">\n\t\t\t\t\t\t\t\t\t<img className=\"icon\" src={cleanDataURI(d['icon-svg'])} draggable=\"false\" />\n\t\t\t\t\t\t\t\t</dd>\n\t\t\t\t\t\t\t\t<dd className=\"code-name\" title={d.name}>{d['short-name']}</dd>\n\t\t\t\t\t\t\t\t<dd className=\"description\">{d.description}</dd>\n\t\t\t\t\t\t\t\t<dd className=\"vendor version\">{d.vendor || d.provider} {d.version}</dd>\n\t\t\t\t\t\t\t</dl>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{isOpenForEdit ? <div className=\"-is-open-for-edit-indicator\" title=\"This descriptor is open in the canvas.\"></div> : null}\n\t\t\t\t</li>\n\t\t\t);\n\t\t});\n\t\treturn (\n\t\t\t<div className=\"CatalogItems\">\n\t\t\t\t<ul>\n\t\t\t\t\t{items.length ? items : messages.catalogWelcome}\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t);\n\t},\n\tcleanDataURI(imageString) {\n\t\tif (/\\bbase64\\b/g.test(imageString)) {\n\t\t\treturn imageString;\n\t\t} else if (/<\\?xml\\b/g.test(imageString)) {\n\t\t\tconst imgStr = imageString.substring(imageString.indexOf('<?xml'));\n\t\t\treturn 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr);\n\t\t}\n\t\treturn 'images/network.svg';\n\t},\n\tgetCatalogItems() {\n\t\tconst catalogFilter = (d) => {return d.type === this.props.filterByType};\n\t\treturn this.state.catalogs.filter(catalogFilter).reduce((result, catalog) => {\n\t\t\treturn result.concat(catalog.descriptors);\n\t\t}, []);\n\t}\n});\n\nexport default CatalogItems;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogItems.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItems.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItems.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItems.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogItems.scss\n ** module id = 555\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogItems {\\n  padding: 0;\\n  margin: 0;\\n}\\n\\n.CatalogItems ul {\\n  list-style: none;\\n  margin: 0;\\n  border: 0;\\n  padding: 10px;\\n  display: flex;\\n  flex-wrap: wrap;\\n}\\n\\n.CatalogItems li {\\n  position: relative;\\n  width: 100%;\\n  min-width: 280px;\\n  max-width: 400px;\\n  margin: 1px;\\n  border: 5px;\\n  padding: 4px 8px;\\n}\\n\\n.CatalogItems li > div.-is-selected {\\n  outline: 2px dotted #9fc4f4;\\n  outline-offset: 1px;\\n}\\n\\n.CatalogItems li > div.-is-open-for-edit-indicator {\\n  position: absolute;\\n  top: 10px;\\n  left: -4px;\\n  bottom: 10px;\\n  width: 8px;\\n  border-radius: 2px;\\n  background-color: #4d8fb3;\\n}\\n\\n.CatalogItems div.catalog-item {\\n  cursor: pointer;\\n  display: block;\\n  overflow: hidden;\\n  position: relative;\\n  width: 100%;\\n  height: auto;\\n  min-height: 70px;\\n  margin: 0;\\n  padding: 0;\\n  border-radius: 5px;\\n  border: 1px solid #e5e5e5;\\n  font-size: 14px;\\n  font-weight: 400;\\n  font-style: normal;\\n  background-color: #ffffff;\\n  -webkit-user-select: none;\\n  -moz-user-select: none;\\n  -ms-user-select: none;\\n  user-select: none;\\n}\\n\\n.CatalogItems div.catalog-item:hover {\\n  background-color: #7E9BC1;\\n}\\n\\n.CatalogItems div.catalog-item:hover dl dd {\\n  color: #ffffff;\\n}\\n\\n.CatalogItems div.catalog-item:active, .CatalogItems div.catalog-item:visited {\\n  background-color: #4C5E74;\\n}\\n\\n.CatalogItems div.catalog-item.-is-deleted {\\n  opacity: 0.25;\\n}\\n\\n.CatalogItems div.catalog-item .-is-modified-indicator {\\n  position: absolute;\\n  top: -20px;\\n  left: -20px;\\n  width: 40px;\\n  height: 40px;\\n  background-color: #FF5F5F;\\n  transform: rotate(-45deg);\\n  z-index: 1;\\n}\\n\\n.CatalogItems div.catalog-item dl {\\n  margin: 0;\\n  padding: 3px 0 0 80px;\\n  position: relative;\\n}\\n\\n.CatalogItems div.catalog-item dl dt {\\n  margin: 0;\\n  padding: 0;\\n  font-size: 14px;\\n  font-weight: 400;\\n  white-space: nowrap;\\n}\\n\\n.CatalogItems div.catalog-item dl dd {\\n  display: block;\\n  padding: 0;\\n  color: #aeaeae;\\n  font-size: 10px;\\n  font-style: normal;\\n}\\n\\n.CatalogItems div.catalog-item dl dd.icon {\\n  position: absolute;\\n  top: 0;\\n  left: 8px;\\n  margin: 8px;\\n}\\n\\n.CatalogItems div.catalog-item dl dd.icon img.icon {\\n  width: 50px;\\n  height: 50px;\\n}\\n\\n.CatalogItems div.catalog-item:first-of-type {\\n  margin-top: 0;\\n}\\n\\n.CatalogItems div.catalog-item span.vendor,\\n.CatalogItems div.catalog-item span.version {\\n  display: inline-block;\\n  padding-right: 4px;\\n}\\n\\n.CatalogItems div.catalog-item span.vendor:after {\\n  content: ' /';\\n}\\n\\n.CatalogItems div.catalog-item span.version:before {\\n  content: ' v';\\n}\\n\\n.CatalogItems div.catalog-item span.description {\\n  display: none;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogItems.scss\n ** module id = 556\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"412d7439ee30962f8aeafde4d680478a.png\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/file-loader!./src/images/vendor-riftio.png\n ** module id = 557\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 12/2/15.\n */\n'use strict';\n\nimport React from 'react'\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogFilterActions from '../actions/CatalogFilterActions'\n\nimport '../styles/CatalogFilter.scss'\n\nconst CatalogFilter = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState: function () {\n\t\treturn {};\n\t},\n\tgetDefaultProps: function () {\n\t\treturn {filterByType: 'nsd'};\n\t},\n\tcomponentWillMount: function () {\n\t},\n\tcomponentDidMount: function () {\n\t},\n\tcomponentDidUpdate: function () {\n\t},\n\tcomponentWillUnmount: function () {\n\t},\n\trender() {\n\t\tconst clickFilterByType = function (event) {\n\t\t\tCatalogFilterActions.filterByType(event.target.value);\n\t\t};\n\t\treturn (\n\t\t\t<div className=\"CatalogFilter\">\n\t\t\t\t<button className={ClassNames('CatalogFilterNSD', {'-selected': this.props.filterByType === 'nsd'})}\n\t\t\t\t\t\tvalue=\"nsd\" onClick={clickFilterByType}>NSD\n\t\t\t\t</button>\n\t\t\t\t<button className={ClassNames('CatalogFilterVNFD', {'-selected': this.props.filterByType === 'vnfd'})}\n\t\t\t\t\t\tvalue=\"vnfd\" onClick={clickFilterByType}>VNFD\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default CatalogFilter;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogFilter.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogFilter.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogFilter.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogFilter.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogFilter.scss\n ** module id = 559\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogFilter {\\n  margin: 0;\\n  padding: 0;\\n  border-radius: 0;\\n  width: 100%;\\n}\\n\\n.CatalogFilter button {\\n  height: 33px;\\n  width: 50%;\\n  vertical-align: bottom;\\n  border-radius: 0;\\n  box-shadow: none;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogFilter.scss\n ** module id = 560\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react';\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'\n\nimport '../styles/CatalogPanelTray.scss'\n\nconst CatalogPanelTray = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {\n\t\t\tisDragging: false\n\t\t};\n\t},\n\tgetDefaultProps() {\n\t\treturn {show: false};\n\t},\n\tpreventResizeCursor(e) {\n\t\te.stopPropagation();\n\t\tdocument.body.style.cursor = '';\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\tonDragOver() {\n\t\tthis.setState({isDragging: true});\n\t},\n\tonDragLeave() {\n\t\tthis.setState({isDragging: false});\n\t},\n\trender() {\n\t\tconst classNames = ClassNames('CatalogPanelTray', {\n\t\t\t'-close': !this.props.show,\n\t\t\t'-is-dragging': this.state.isDragging\n\t\t});\n\t\treturn (\n\t\t\t<div className={classNames} onMouseMove={this.preventResizeCursor} onDragOver={this.onDragOver} onDragLeave={this.onDragLeave}>\n\t\t\t\t<h1 onClick={CatalogPanelTrayActions.toggleOpenClose}>Catalog Package Manager</h1>\n\t\t\t\t<div className=\"tray-body\">\n\t\t\t\t\t{this.props.children}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default CatalogPanelTray;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogPanelTray.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 8/11/15.\n */\nimport alt from '../alt';\n\nclass CatalogPanelTrayActions {\n\n\tconstructor() {\n\t\tthis.generateActions('open', 'close', 'toggleOpenClose');\n\t}\n\n}\n\nexport default alt.createActions(CatalogPanelTrayActions);\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/actions/CatalogPanelTrayActions.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanelTray.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanelTray.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanelTray.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogPanelTray.scss\n ** module id = 563\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogPanelTray {\\n  position: absolute;\\n  overflow: hidden;\\n  bottom: 0px;\\n  width: 100%;\\n  min-width: 300px;\\n  height: 275px;\\n  color: #aeaeae;\\n  background-color: #e5e5e5;\\n  z-index: 0;\\n  transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n\\n.CatalogPanelTray.-close {\\n  transform: translate3d(0, 250px, 0);\\n}\\n\\n.CatalogPanelTray h1 {\\n  border-bottom: 1px solid rgba(143, 143, 143, 0.05);\\n  cursor: pointer;\\n  color: #666;\\n  font-size: 12px;\\n  font-style: normal;\\n  line-height: 16px;\\n  height: 25px;\\n  margin: 0;\\n  padding-left: 0;\\n  padding-right: 0;\\n  text-align: center;\\n  text-transform: uppercase;\\n  background-color: #cbd1d1;\\n}\\n\\n.CatalogPanelTray .tray-body {\\n  height: 250px;\\n  overflow: auto;\\n  z-index: 0;\\n  background-color: #e5e5e5;\\n}\\n\\n.CatalogPanelTray.-is-dragging .tray-body {\\n  overflow: hidden;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogPanelTray.scss\n ** module id = 564\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react'\nimport Button from './Button'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\n\nimport '../styles/CatalogPanelToolbar.scss'\n\nimport imgAdd from '../images/add175.svg'\nimport imgCopy from '../images/copy30.svg'\nimport imgOnboard from '../images/upload109.svg'\nimport imgUpdate from '../images/file91.svg'\nimport imgDownload from '../images/download158.svg'\nimport imgDelete from '../images/recycle69.svg'\n\nconst CatalogHeader = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {};\n\t},\n\tgetDefaultProps() {\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\trender() {\n\t\treturn (\n\t\t\t<div className=\"CatalogPanelToolbar\">\n\t\t\t\t<h1>Descriptor Catalogs</h1>\n\t\t\t\t<div className=\"btn-bar\">\n\t\t\t\t\t<div className=\"btn-group\">\n\t\t\t\t\t\t<Button type=\"image\" title=\"OnBoard a catalog package\" className=\"action-onboard-catalog-package\" onClick={this.onClickOnBoardCatalog} src={imgOnboard} />\n\t\t\t\t\t\t<Button type=\"image\" title=\"Update a catalog package\" className=\"action-update-catalog-package\" onClick={this.onClickUpdateCatalog} src={imgUpdate} />\n\t\t\t\t\t\t<Button type=\"image\" title=\"Export selected catalog item(s)\" className=\"action-export-catalog-items\" onClick={this.onClickExportCatalogItems} src={imgDownload} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"btn-group\">\n\t\t\t\t\t\t<div className=\"menu\">\n\t\t\t\t\t\t\t<Button type=\"image\" title=\"Create a new catalog item\" className=\"action-create-catalog-item\" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} />\n\t\t\t\t\t\t\t<div className=\"sub-menu\">\n\t\t\t\t\t\t\t\t<Button type=\"image\" title=\"Create a new catalog item\" className=\"action-create-catalog-item\" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} label=\"Add NSD\" />\n\t\t\t\t\t\t\t\t<Button type=\"image\" title=\"Create a new catalog item\" className=\"action-create-catalog-item\" onClick={this.onClickCreateCatalogItem.bind(null, 'vnfd')} src={imgAdd} label=\"Add VNFD\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<Button type=\"image\" title=\"Copy catalog item\" className=\"action-copy-catalog-item\" onClick={this.onClickDuplicateCatalogItem} src={imgCopy} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"btn-group\">\n\t\t\t\t\t\t<Button type=\"image\" title=\"Delete catalog item\" className=\"action-delete-catalog-item\" onClick = {this.onClickDeleteCatalogItem} src={imgDelete} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t},\n\tonClickUpdateCatalog() {\n\t\t//CatalogPanelTrayActions.open();\n\t\t// note CatalogPackageManagerUploadDropZone wired our btn\n\t\t// click event to the DropZone.js configuration and will\n\t\t// open the tray when/if files are added to the drop zone\n\t},\n\tonClickOnBoardCatalog() {\n\t\t//CatalogPanelTrayActions.open();\n\t\t// note CatalogPackageManagerUploadDropZone wired our btn\n\t\t// click event to the DropZone.js configuration and will\n\t\t// open the tray when/if files are added to the drop zone\n\t},\n\tonClickDeleteCatalogItem() {\n\t\tCatalogItemsActions.deleteSelectedCatalogItem();\n\t},\n\tonClickCreateCatalogItem(type) {\n\t\tCatalogItemsActions.createCatalogItem(type);\n\t},\n\tonClickDuplicateCatalogItem() {\n\t\tCatalogItemsActions.duplicateSelectedCatalogItem();\n\t},\n\tonClickExportCatalogItems() {\n\t\tCatalogPanelTrayActions.open();\n\t\tCatalogItemsActions.exportSelectedCatalogItems();\n\t}\n});\n\nexport default CatalogHeader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogPanelToolbar.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanelToolbar.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanelToolbar.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanelToolbar.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogPanelToolbar.scss\n ** module id = 566\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogPanelToolbar {\\n  display: block;\\n  padding: 0;\\n  margin: 0;\\n  height: auto;\\n  border-bottom: 0 solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.CatalogPanelToolbar h1 {\\n  white-space: nowrap;\\n  text-align: left;\\n  font-size: 14px;\\n  line-height: 16px;\\n  padding: 20px;\\n  text-transform: uppercase;\\n  font-weight: bold;\\n  background-color: #ffffff;\\n}\\n\\n.CatalogPanelToolbar .btn-bar {\\n  height: 55px;\\n  padding: 10px 0;\\n  background-color: #cbd1d1;\\n}\\n\\n.CatalogPanelToolbar .btn-bar .btn-group {\\n  padding: 0 8px;\\n  display: inline-block;\\n}\\n\\n.CatalogPanelToolbar .btn-bar .btn-group input {\\n  margin: 0 4px;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogPanelToolbar.scss\n ** module id = 567\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"2a821599a77165fa59efc37db1959fa1.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/add175.svg\n ** module id = 568\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"82dbccc2be244b65a7ae097341e4bbe8.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/copy30.svg\n ** module id = 569\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"f49a4402bf0c6b9c59832a379ac01eae.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/file91.svg\n ** module id = 570\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"c1ddfad74917a092bd31d82c6b95dc4f.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/download158.svg\n ** module id = 571\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react'\nimport moment from 'moment'\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogPackageManagerStore from '../stores/CatalogPackageManagerStore'\nimport CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'\nimport Button from './Button'\n\nimport '../styles/CatalogPackageManager.scss'\nimport imgVideoFileType from '../images/video167.svg'\nimport imgZipFileType from '../images/zipped2.svg'\nimport imgUnknownFileType from '../images/file87.svg'\nimport imgCancel from '../images/cross95.svg'\n\nconst CatalogPackageManager = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn CatalogPackageManagerStore.getState();\n\t},\n\tgetDefaultProps() {\n\t\treturn {};\n\t},\n\tcomponentWillMount() {\n\t\tCatalogPackageManagerStore.listen(this.onChange);\n\t},\n\tcomponentDidMount() {\n\t},\n\tonChange(state) {\n\t\tthis.setState(state);\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t\tCatalogPackageManagerStore.unlisten(this.onChange);\n\t},\n\trender() {\n\t\tfunction getIndicator(download) {\n\t\t\tif (download.pending) {\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"file-progress-indicator\">\n\t\t\t\t\t\t<div className=\"file-progress-indicator-value\" style={{width: (download.progress || 0) + '%'}}></div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tfunction getDownloadLink(download) {\n\t\t\tif (download.success) {\n\t\t\t\tconst now = moment();\n\t\t\t\tconst duration = moment.duration(moment(download.urlValidUntil).diff(now));\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"file-download\">\n\t\t\t\t\t\t<a className=\"file-download-link\" href={download.url}>Download Package</a>\n\t\t\t\t\t\t<span>expires&nbsp;</span> {duration.humanize(true)}\n\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tfunction getMessage(catalogPackage) {\n\t\t\tif (catalogPackage.success && catalogPackage.url) {\n\t\t\t\treturn getDownloadLink(catalogPackage);\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<div className=\"message\">{catalogPackage.message}</div>\n\t\t\t);\n\t\t}\n\n\t\tvar createItem = function (catalogPackage) {\n\t\t\tconst onClickRemove = function () {\n\t\t\t\tCatalogPackageManagerActions.removeCatalogPackage(catalogPackage);\n\t\t\t};\n\t\t\tconst classNames = ClassNames('item', {'-error': catalogPackage.error, '-success': catalogPackage.success});\n\t\t\treturn (\n\t\t\t\t<div ref=\"catalogPackage\" className={classNames} key={catalogPackage.id}>\n\t\t\t\t\t<div className=\"item-body\">\n\t\t\t\t\t\t<h2 title={catalogPackage.name}>{catalogPackage.name}</h2>\n\t\t\t\t\t\t<img src={catalogPackage.icon} />\n\t\t\t\t\t\t{getIndicator(catalogPackage)}\n\t\t\t\t\t\t{getMessage(catalogPackage)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"item-actions\">\n\t\t\t\t\t\t<Button className=\"action-remove-catalog-package\" onClick={onClickRemove} src={imgCancel} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t};\n\n\t\tconst packages = this.state.packages || [];\n\t\treturn (\n\t\t\t<div className=\"CatalogPackageManager\">\n\t\t\t\t<div className=\"items\">\n\t\t\t\t\t{packages.map(createItem)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\n\t}\n\n});\n\nexport default CatalogPackageManager;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogPackageManager.js\n **/","//! moment.js\n//! version : 2.10.6\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, function () { 'use strict';\n\n    var hookCallback;\n\n    function utils_hooks__hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function isArray(input) {\n        return Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isDate(input) {\n        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function create_utc__createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false\n        };\n    }\n\n    function getParsingFlags(m) {\n        if (m._pf == null) {\n            m._pf = defaultParsingFlags();\n        }\n        return m._pf;\n    }\n\n    function valid__isValid(m) {\n        if (m._isValid == null) {\n            var flags = getParsingFlags(m);\n            m._isValid = !isNaN(m._d.getTime()) &&\n                flags.overflow < 0 &&\n                !flags.empty &&\n                !flags.invalidMonth &&\n                !flags.invalidWeekday &&\n                !flags.nullInput &&\n                !flags.invalidFormat &&\n                !flags.userInvalidated;\n\n            if (m._strict) {\n                m._isValid = m._isValid &&\n                    flags.charsLeftOver === 0 &&\n                    flags.unusedTokens.length === 0 &&\n                    flags.bigHour === undefined;\n            }\n        }\n        return m._isValid;\n    }\n\n    function valid__createInvalid (flags) {\n        var m = create_utc__createUTC(NaN);\n        if (flags != null) {\n            extend(getParsingFlags(m), flags);\n        }\n        else {\n            getParsingFlags(m).userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    var momentProperties = utils_hooks__hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (typeof from._isAMomentObject !== 'undefined') {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (typeof from._i !== 'undefined') {\n            to._i = from._i;\n        }\n        if (typeof from._f !== 'undefined') {\n            to._f = from._f;\n        }\n        if (typeof from._l !== 'undefined') {\n            to._l = from._l;\n        }\n        if (typeof from._strict !== 'undefined') {\n            to._strict = from._strict;\n        }\n        if (typeof from._tzm !== 'undefined') {\n            to._tzm = from._tzm;\n        }\n        if (typeof from._isUTC !== 'undefined') {\n            to._isUTC = from._isUTC;\n        }\n        if (typeof from._offset !== 'undefined') {\n            to._offset = from._offset;\n        }\n        if (typeof from._pf !== 'undefined') {\n            to._pf = getParsingFlags(from);\n        }\n        if (typeof from._locale !== 'undefined') {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i in momentProperties) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (typeof val !== 'undefined') {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            utils_hooks__hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            return Math.ceil(number);\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            value = absFloor(coercedNumber);\n        }\n\n        return value;\n    }\n\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function Locale() {\n    }\n\n    var locales = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return null;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && typeof module !== 'undefined' &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                require('./locale/' + name);\n                // because defineLocale currently also sets the global locale, we\n                // want to undo that for lazy loaded locales\n                locale_locales__getSetGlobalLocale(oldLocale);\n            } catch (e) { }\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function locale_locales__getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (typeof values === 'undefined') {\n                data = locale_locales__getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, values) {\n        if (values !== null) {\n            values.abbr = name;\n            locales[name] = locales[name] || new Locale();\n            locales[name].set(values);\n\n            // backwards compat for now: also set the locale\n            locale_locales__getSetGlobalLocale(name);\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    // returns locale data\n    function locale_locales__getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                get_set__set(this, unit, value);\n                utils_hooks__hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get_set__get(this, unit);\n            }\n        };\n    }\n\n    function get_set__get (mom, unit) {\n        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n    }\n\n    function get_set__set (mom, unit, value) {\n        return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n\n    // MOMENTS\n\n    function getSet (units, value) {\n        var unit;\n        if (typeof units === 'object') {\n            for (unit in units) {\n                this.set(unit, units[unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (typeof this[units] === 'function') {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var absNumber = '' + Math.abs(number),\n            zerosToFill = targetLength - absNumber.length,\n            sign = number >= 0;\n        return (sign ? (forceSign ? '+' : '') : '-') +\n            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '';\n            for (i = 0; i < length; i++) {\n                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n    var regexes = {};\n\n    function isFunction (sth) {\n        // https://github.com/moment/moment/issues/2325\n        return typeof sth === 'function' &&\n            Object.prototype.toString.call(sth) === '[object Function]';\n    }\n\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = isFunction(regex) ? regex : function (isStrict) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }).replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (typeof callback === 'number') {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n\n    function daysInMonth(year, month) {\n        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  matchWord);\n    addRegexToken('MMMM', matchWord);\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            getParsingFlags(config).invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m) {\n        return this._months[m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m) {\n        return this._monthsShort[m.month()];\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = create_utc__createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        // TODO: Move this out of here!\n        if (typeof value === 'string') {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (typeof value !== 'number') {\n                return mom;\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            utils_hooks__hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get_set__get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && getParsingFlags(m).overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n\n            getParsingFlags(m).overflow = overflow;\n        }\n\n        return m;\n    }\n\n    function warn(msg) {\n        if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n\n        return extend(function () {\n            if (firstTime) {\n                warn(msg + '\\n' + (new Error()).stack);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    utils_hooks__hooks.suppressDeprecationWarnings = false;\n\n    var from_string__isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n        ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n        ['HH', /(T| )\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = from_string__isoRegex.exec(string);\n\n        if (match) {\n            getParsingFlags(config).iso = true;\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(string)) {\n                    config._f = isoDates[i][0];\n                    break;\n                }\n            }\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(string)) {\n                    // match[6] should be 'T' or space\n                    config._f += (match[6] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (string.match(matchOffset)) {\n                config._f += 'Z';\n            }\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    utils_hooks__hooks.createFromInputFallback = deprecate(\n        'moment construction falls back to js Date. This is ' +\n        'discouraged and will be removed in upcoming major ' +\n        'release. Please refer to ' +\n        'https://github.com/moment/moment/issues/1407 for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    function createDate (y, m, d, h, M, s, ms) {\n        //can't just apply() to create a date:\n        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply\n        var date = new Date(y, m, d, h, M, s, ms);\n\n        //the date constructor doesn't accept years < 1970\n        if (y < 1970) {\n            date.setFullYear(y);\n        }\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date = new Date(Date.UTC.apply(null, arguments));\n        if (y < 1970) {\n            date.setUTCFullYear(y);\n        }\n        return date;\n    }\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YYYY', function (input, array) {\n        array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);\n    });\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    utils_hooks__hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', false);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // firstDayOfWeek       0 = sun, 6 = sat\n    //                      the day of the week that starts the week\n    //                      (usually sunday or monday)\n    // firstDayOfWeekOfYear 0 = sun, 6 = sat\n    //                      the first week is the week that contains the first\n    //                      of this day of the week\n    //                      (eg. ISO weeks use thursday (4))\n    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n        var end = firstDayOfWeekOfYear - firstDayOfWeek,\n            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n            adjustedMoment;\n\n\n        if (daysToDayOfWeek > end) {\n            daysToDayOfWeek -= 7;\n        }\n\n        if (daysToDayOfWeek < end - 7) {\n            daysToDayOfWeek += 7;\n        }\n\n        adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');\n        return {\n            week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n            year: adjustedMoment.year()\n        };\n    }\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n        var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;\n        if (d < firstDayOfWeek) {\n            d += 7;\n        }\n\n        weekday = weekday != null ? 1 * weekday : firstDayOfWeek;\n\n        dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;\n\n        return {\n            year: dayOfYear > 0 ? year : year - 1,\n            dayOfYear: dayOfYear > 0 ?  dayOfYear : daysInYear(year - 1) + dayOfYear\n        };\n    }\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        var now = new Date();\n        if (config._useUTC) {\n            return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];\n        }\n        return [now.getFullYear(), now.getMonth(), now.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse)) {\n                getParsingFlags(config)._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);\n            week = defaults(w.w, 1);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < dow) {\n                    ++week;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from begining of week\n                weekday = w.e + dow;\n            } else {\n                // default to begining of week\n                weekday = dow;\n            }\n        }\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n\n    utils_hooks__hooks.ISO_8601 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === utils_hooks__hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n\n        config._a = [];\n        getParsingFlags(config).empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    getParsingFlags(config).unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    getParsingFlags(config).empty = false;\n                }\n                else {\n                    getParsingFlags(config).unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            getParsingFlags(config).unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (getParsingFlags(config).bigHour === true &&\n                config._a[HOUR] <= 12 &&\n                config._a[HOUR] > 0) {\n            getParsingFlags(config).bigHour = undefined;\n        }\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            getParsingFlags(config).invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!valid__isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n            //or tokens\n            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n            getParsingFlags(tempConfig).score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var res = new Moment(checkOverflow(prepareConfig(config)));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function prepareConfig (config) {\n        var input = config._i,\n            format = config._f;\n\n        config._locale = config._locale || locale_locales__getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return valid__createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        } else if (isDate(input)) {\n            config._d = input;\n        } else {\n            configFromInput(config);\n        }\n\n        return config;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (input === undefined) {\n            config._d = new Date();\n        } else if (isDate(input)) {\n            config._d = new Date(+input);\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (typeof(input) === 'object') {\n            configFromObject(config);\n        } else if (typeof(input) === 'number') {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (typeof(locale) === 'boolean') {\n            strict = locale;\n            locale = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n\n        return createFromConfig(c);\n    }\n\n    function local__createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n         'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n         function () {\n             var other = local__createLocal.apply(null, arguments);\n             return other < this ? this : other;\n         }\n     );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n        function () {\n            var other = local__createLocal.apply(null, arguments);\n            return other > this ? this : other;\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return local__createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (!moments[i].isValid() || moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 36e5; // 1000 * 60 * 60\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = locale_locales__getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchOffset);\n    addRegexToken('ZZ', matchOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(string) {\n        var matches = ((string || '').match(matchOffset) || []);\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(+res._d + diff);\n            utils_hooks__hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return local__createLocal(input).local();\n        }\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    utils_hooks__hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(input);\n            }\n            if (Math.abs(input) < 16) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    utils_hooks__hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm) {\n            this.utcOffset(this._tzm);\n        } else if (typeof this._i === 'string') {\n            this.utcOffset(offsetFromString(this._i));\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        input = input ? local__createLocal(input).utcOffset() : 0;\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (typeof this._isDSTShifted !== 'undefined') {\n            return this._isDSTShifted;\n        }\n\n        var c = {};\n\n        copyConfig(c, this);\n        c = prepareConfig(c);\n\n        if (c._a) {\n            var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);\n            this._isDSTShifted = this.isValid() &&\n                compareArrays(c._a, other.toArray()) > 0;\n        } else {\n            this._isDSTShifted = false;\n        }\n\n        return this._isDSTShifted;\n    }\n\n    function isLocal () {\n        return !this._isUTC;\n    }\n\n    function isUtcOffset () {\n        return this._isUTC;\n    }\n\n    function isUtc () {\n        return this._isUTC && this._offset === 0;\n    }\n\n    var aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;\n\n    function create__createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (typeof input === 'number') {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])        * sign,\n                h  : toInt(match[HOUR])        * sign,\n                m  : toInt(match[MINUTE])      * sign,\n                s  : toInt(match[SECOND])      * sign,\n                ms : toInt(match[MILLISECOND]) * sign\n            };\n        } else if (!!(match = create__isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                d : parseIso(match[4], sign),\n                h : parseIso(match[5], sign),\n                m : parseIso(match[6], sign),\n                s : parseIso(match[7], sign),\n                w : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    create__createDuration.fn = Duration.prototype;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {milliseconds: 0, months: 0};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = create__createDuration(val, period);\n            add_subtract__addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = duration._days,\n            months = duration._months;\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (milliseconds) {\n            mom._d.setTime(+mom._d + milliseconds * isAdding);\n        }\n        if (days) {\n            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);\n        }\n        if (months) {\n            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);\n        }\n        if (updateOffset) {\n            utils_hooks__hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add_subtract__add      = createAdder(1, 'add');\n    var add_subtract__subtract = createAdder(-1, 'subtract');\n\n    function moment_calendar__calendar (time, formats) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || local__createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            diff = this.diff(sod, 'days', true),\n            format = diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n        return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this > +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return inputMs < +this.clone().startOf(units);\n        }\n    }\n\n    function isBefore (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this < +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return +this.clone().endOf(units) < inputMs;\n        }\n    }\n\n    function isBetween (from, to, units) {\n        return this.isAfter(from, units) && this.isBefore(to, units);\n    }\n\n    function isSame (input, units) {\n        var inputMs;\n        units = normalizeUnits(units || 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this === +input;\n        } else {\n            inputMs = +local__createLocal(input);\n            return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n        }\n    }\n\n    function diff (input, units, asFloat) {\n        var that = cloneWithOffset(input, this),\n            zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,\n            delta, output;\n\n        units = normalizeUnits(units);\n\n        if (units === 'year' || units === 'month' || units === 'quarter') {\n            output = monthDiff(this, that);\n            if (units === 'quarter') {\n                output = output / 3;\n            } else if (units === 'year') {\n                output = output / 12;\n            }\n        } else {\n            delta = this - that;\n            output = units === 'second' ? delta / 1e3 : // 1000\n                units === 'minute' ? delta / 6e4 : // 1000 * 60\n                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n                delta;\n        }\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        return -(wholeMonthDiff + adjust);\n    }\n\n    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function moment_format__toISOString () {\n        var m = this.clone().utc();\n        if (0 < m.year() && m.year() <= 9999) {\n            if ('function' === typeof Date.prototype.toISOString) {\n                // native implementation is ~50x faster, use it when we can\n                return this.toDate().toISOString();\n            } else {\n                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n            }\n        } else {\n            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n        }\n    }\n\n    function format (inputString) {\n        var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n        return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(local__createLocal(), withoutSuffix);\n    }\n\n    function to (time, withoutSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n        return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    }\n\n    function toNow (withoutSuffix) {\n        return this.to(local__createLocal(), withoutSuffix);\n    }\n\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = locale_locales__getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    function startOf (units) {\n        units = normalizeUnits(units);\n        // the following switch intentionally omits break keywords\n        // to utilize falling through the cases.\n        switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n        }\n\n        // weeks are a special case\n        if (units === 'week') {\n            this.weekday(0);\n        }\n        if (units === 'isoWeek') {\n            this.isoWeekday(1);\n        }\n\n        // quarters are also special\n        if (units === 'quarter') {\n            this.month(Math.floor(this.month() / 3) * 3);\n        }\n\n        return this;\n    }\n\n    function endOf (units) {\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond') {\n            return this;\n        }\n        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n    }\n\n    function to_type__valueOf () {\n        return +this._d - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(+this / 1000);\n    }\n\n    function toDate () {\n        return this._offset ? new Date(+this) : this._d;\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function toObject () {\n        var m = this;\n        return {\n            years: m.year(),\n            months: m.month(),\n            date: m.date(),\n            hours: m.hours(),\n            minutes: m.minutes(),\n            seconds: m.seconds(),\n            milliseconds: m.milliseconds()\n        };\n    }\n\n    function moment_valid__isValid () {\n        return valid__isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, getParsingFlags(this));\n    }\n\n    function invalidAt () {\n        return getParsingFlags(this).overflow;\n    }\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    // HELPERS\n\n    function weeksInYear(year, dow, doy) {\n        return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;\n    }\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getSetISOWeekYear (input) {\n        var year = weekOfYear(this, 1, 4).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    addFormatToken('Q', 0, 0, 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0], 10);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   matchWord);\n    addRegexToken('ddd',  matchWord);\n    addRegexToken('dddd', matchWord);\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {\n        var weekday = config._locale.weekdaysParse(input);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            getParsingFlags(config).invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input !== 'string') {\n            return input;\n        }\n\n        if (!isNaN(input)) {\n            return parseInt(input, 10);\n        }\n\n        input = locale.weekdaysParse(input);\n        if (typeof input === 'number') {\n            return input;\n        }\n\n        return null;\n    }\n\n    // LOCALES\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m) {\n        return this._weekdays[m.day()];\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return this._weekdaysShort[m.day()];\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return this._weekdaysMin[m.day()];\n    }\n\n    function localeWeekdaysParse (weekdayName) {\n        var i, mom, regex;\n\n        this._weekdaysParse = this._weekdaysParse || [];\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            if (!this._weekdaysParse[i]) {\n                mom = local__createLocal([2000, 1]).day(i);\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, function () {\n        return this.hours() % 12 || 12;\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        getParsingFlags(config).bigHour = true;\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour he wants. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n    addFormatToken(0, ['SSSS', 4], 0, function () {\n        return this.millisecond() * 10;\n    });\n    addFormatToken(0, ['SSSSS', 5], 0, function () {\n        return this.millisecond() * 100;\n    });\n    addFormatToken(0, ['SSSSSS', 6], 0, function () {\n        return this.millisecond() * 1000;\n    });\n    addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n        return this.millisecond() * 10000;\n    });\n    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n        return this.millisecond() * 100000;\n    });\n    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n        return this.millisecond() * 1000000;\n    });\n\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n\n    var token;\n    for (token = 'SSSS'; token.length <= 9; token += 'S') {\n        addRegexToken(token, matchUnsigned);\n    }\n\n    function parseMs(input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    }\n\n    for (token = 'S'; token.length <= 9; token += 'S') {\n        addParseToken(token, parseMs);\n    }\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var momentPrototype__proto = Moment.prototype;\n\n    momentPrototype__proto.add          = add_subtract__add;\n    momentPrototype__proto.calendar     = moment_calendar__calendar;\n    momentPrototype__proto.clone        = clone;\n    momentPrototype__proto.diff         = diff;\n    momentPrototype__proto.endOf        = endOf;\n    momentPrototype__proto.format       = format;\n    momentPrototype__proto.from         = from;\n    momentPrototype__proto.fromNow      = fromNow;\n    momentPrototype__proto.to           = to;\n    momentPrototype__proto.toNow        = toNow;\n    momentPrototype__proto.get          = getSet;\n    momentPrototype__proto.invalidAt    = invalidAt;\n    momentPrototype__proto.isAfter      = isAfter;\n    momentPrototype__proto.isBefore     = isBefore;\n    momentPrototype__proto.isBetween    = isBetween;\n    momentPrototype__proto.isSame       = isSame;\n    momentPrototype__proto.isValid      = moment_valid__isValid;\n    momentPrototype__proto.lang         = lang;\n    momentPrototype__proto.locale       = locale;\n    momentPrototype__proto.localeData   = localeData;\n    momentPrototype__proto.max          = prototypeMax;\n    momentPrototype__proto.min          = prototypeMin;\n    momentPrototype__proto.parsingFlags = parsingFlags;\n    momentPrototype__proto.set          = getSet;\n    momentPrototype__proto.startOf      = startOf;\n    momentPrototype__proto.subtract     = add_subtract__subtract;\n    momentPrototype__proto.toArray      = toArray;\n    momentPrototype__proto.toObject     = toObject;\n    momentPrototype__proto.toDate       = toDate;\n    momentPrototype__proto.toISOString  = moment_format__toISOString;\n    momentPrototype__proto.toJSON       = moment_format__toISOString;\n    momentPrototype__proto.toString     = toString;\n    momentPrototype__proto.unix         = unix;\n    momentPrototype__proto.valueOf      = to_type__valueOf;\n\n    // Year\n    momentPrototype__proto.year       = getSetYear;\n    momentPrototype__proto.isLeapYear = getIsLeapYear;\n\n    // Week Year\n    momentPrototype__proto.weekYear    = getSetWeekYear;\n    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;\n\n    // Quarter\n    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;\n\n    // Month\n    momentPrototype__proto.month       = getSetMonth;\n    momentPrototype__proto.daysInMonth = getDaysInMonth;\n\n    // Week\n    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;\n    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;\n    momentPrototype__proto.weeksInYear    = getWeeksInYear;\n    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;\n\n    // Day\n    momentPrototype__proto.date       = getSetDayOfMonth;\n    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;\n    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;\n    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;\n    momentPrototype__proto.dayOfYear  = getSetDayOfYear;\n\n    // Hour\n    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;\n\n    // Minute\n    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;\n\n    // Second\n    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;\n\n    // Millisecond\n    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;\n\n    // Offset\n    momentPrototype__proto.utcOffset            = getSetOffset;\n    momentPrototype__proto.utc                  = setOffsetToUTC;\n    momentPrototype__proto.local                = setOffsetToLocal;\n    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;\n    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    momentPrototype__proto.isDST                = isDaylightSavingTime;\n    momentPrototype__proto.isDSTShifted         = isDaylightSavingTimeShifted;\n    momentPrototype__proto.isLocal              = isLocal;\n    momentPrototype__proto.isUtcOffset          = isUtcOffset;\n    momentPrototype__proto.isUtc                = isUtc;\n    momentPrototype__proto.isUTC                = isUtc;\n\n    // Timezone\n    momentPrototype__proto.zoneAbbr = getZoneAbbr;\n    momentPrototype__proto.zoneName = getZoneName;\n\n    // Deprecations\n    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);\n\n    var momentPrototype = momentPrototype__proto;\n\n    function moment__createUnix (input) {\n        return local__createLocal(input * 1000);\n    }\n\n    function moment__createInZone () {\n        return local__createLocal.apply(null, arguments).parseZone();\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function locale_calendar__calendar (key, mom, now) {\n        var output = this._calendar[key];\n        return typeof output === 'function' ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    };\n\n    function longDateFormat (key) {\n        var format = this._longDateFormat[key],\n            formatUpper = this._longDateFormat[key.toUpperCase()];\n\n        if (format || !formatUpper) {\n            return format;\n        }\n\n        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n\n        return this._longDateFormat[key];\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relative__relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (typeof output === 'function') ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n    }\n\n    function locale_set__set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (typeof prop === 'function') {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _ordinalParseLenient.\n        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\\d{1,2}/).source);\n    }\n\n    var prototype__proto = Locale.prototype;\n\n    prototype__proto._calendar       = defaultCalendar;\n    prototype__proto.calendar        = locale_calendar__calendar;\n    prototype__proto._longDateFormat = defaultLongDateFormat;\n    prototype__proto.longDateFormat  = longDateFormat;\n    prototype__proto._invalidDate    = defaultInvalidDate;\n    prototype__proto.invalidDate     = invalidDate;\n    prototype__proto._ordinal        = defaultOrdinal;\n    prototype__proto.ordinal         = ordinal;\n    prototype__proto._ordinalParse   = defaultOrdinalParse;\n    prototype__proto.preparse        = preParsePostFormat;\n    prototype__proto.postformat      = preParsePostFormat;\n    prototype__proto._relativeTime   = defaultRelativeTime;\n    prototype__proto.relativeTime    = relative__relativeTime;\n    prototype__proto.pastFuture      = pastFuture;\n    prototype__proto.set             = locale_set__set;\n\n    // Month\n    prototype__proto.months       =        localeMonths;\n    prototype__proto._months      = defaultLocaleMonths;\n    prototype__proto.monthsShort  =        localeMonthsShort;\n    prototype__proto._monthsShort = defaultLocaleMonthsShort;\n    prototype__proto.monthsParse  =        localeMonthsParse;\n\n    // Week\n    prototype__proto.week = localeWeek;\n    prototype__proto._week = defaultLocaleWeek;\n    prototype__proto.firstDayOfYear = localeFirstDayOfYear;\n    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;\n\n    // Day of Week\n    prototype__proto.weekdays       =        localeWeekdays;\n    prototype__proto._weekdays      = defaultLocaleWeekdays;\n    prototype__proto.weekdaysMin    =        localeWeekdaysMin;\n    prototype__proto._weekdaysMin   = defaultLocaleWeekdaysMin;\n    prototype__proto.weekdaysShort  =        localeWeekdaysShort;\n    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;\n    prototype__proto.weekdaysParse  =        localeWeekdaysParse;\n\n    // Hours\n    prototype__proto.isPM = localeIsPM;\n    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;\n    prototype__proto.meridiem = localeMeridiem;\n\n    function lists__get (format, index, field, setter) {\n        var locale = locale_locales__getLocale();\n        var utc = create_utc__createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function list (format, index, field, count, setter) {\n        if (typeof format === 'number') {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return lists__get(format, index, field, setter);\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < count; i++) {\n            out[i] = lists__get(format, i, field, setter);\n        }\n        return out;\n    }\n\n    function lists__listMonths (format, index) {\n        return list(format, index, 'months', 12, 'month');\n    }\n\n    function lists__listMonthsShort (format, index) {\n        return list(format, index, 'monthsShort', 12, 'month');\n    }\n\n    function lists__listWeekdays (format, index) {\n        return list(format, index, 'weekdays', 7, 'day');\n    }\n\n    function lists__listWeekdaysShort (format, index) {\n        return list(format, index, 'weekdaysShort', 7, 'day');\n    }\n\n    function lists__listWeekdaysMin (format, index) {\n        return list(format, index, 'weekdaysMin', 7, 'day');\n    }\n\n    locale_locales__getSetGlobalLocale('en', {\n        ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);\n    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);\n\n    var mathAbs = Math.abs;\n\n    function duration_abs__abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function duration_add_subtract__addSubtract (duration, input, value, direction) {\n        var other = create__createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function duration_add_subtract__add (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function duration_add_subtract__subtract (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, -1);\n    }\n\n    function absCeil (number) {\n        if (number < 0) {\n            return Math.floor(number);\n        } else {\n            return Math.ceil(number);\n        }\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years, monthsFromDays;\n\n        // if we have a mix of positive and negative values, bubble down first\n        // check: https://github.com/moment/moment/issues/2166\n        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n                (milliseconds <= 0 && days <= 0 && months <= 0))) {\n            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n            days = 0;\n            months = 0;\n        }\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // convert days to months\n        monthsFromDays = absFloor(daysToMonths(days));\n        months += monthsFromDays;\n        days -= absCeil(monthsToDays(monthsFromDays));\n\n        // 12 months -> 1 year\n        years = absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToMonths (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        // 400 years have 12 months === 4800\n        return days * 4800 / 146097;\n    }\n\n    function monthsToDays (months) {\n        // the reverse of daysToMonths\n        return months * 146097 / 4800;\n    }\n\n    function as (units) {\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'year') {\n            days   = this._days   + milliseconds / 864e5;\n            months = this._months + daysToMonths(days);\n            return units === 'month' ? months : months / 12;\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(monthsToDays(this._months));\n            switch (units) {\n                case 'week'   : return days / 7     + milliseconds / 6048e5;\n                case 'day'    : return days         + milliseconds / 864e5;\n                case 'hour'   : return days * 24    + milliseconds / 36e5;\n                case 'minute' : return days * 1440  + milliseconds / 6e4;\n                case 'second' : return days * 86400 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function duration_as__valueOf () {\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asYears        = makeAs('y');\n\n    function duration_get__get (units) {\n        units = normalizeUnits(units);\n        return this[units + 's']();\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this._data[name];\n        };\n    }\n\n    var milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        s: 45,  // seconds to minute\n        m: 45,  // minutes to hour\n        h: 22,  // hours to day\n        d: 26,  // days to month\n        M: 11   // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {\n        var duration = create__createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds < thresholds.s && ['s', seconds]  ||\n                minutes === 1          && ['m']           ||\n                minutes < thresholds.m && ['mm', minutes] ||\n                hours   === 1          && ['h']           ||\n                hours   < thresholds.h && ['hh', hours]   ||\n                days    === 1          && ['d']           ||\n                days    < thresholds.d && ['dd', days]    ||\n                months  === 1          && ['M']           ||\n                months  < thresholds.M && ['MM', months]  ||\n                years   === 1          && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        var locale = this.localeData();\n        var output = duration_humanize__relativeTime(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var iso_string__abs = Math.abs;\n\n    function iso_string__toISOString() {\n        // for ISO strings we do not use the normal bubbling rules:\n        //  * milliseconds bubble up until they become hours\n        //  * days do not bubble at all\n        //  * months bubble up until they become years\n        // This is because there is no context-free conversion between hours and days\n        // (think of clock changes)\n        // and also not between days and months (28-31 days per month)\n        var seconds = iso_string__abs(this._milliseconds) / 1000;\n        var days         = iso_string__abs(this._days);\n        var months       = iso_string__abs(this._months);\n        var minutes, hours, years;\n\n        // 3600 seconds -> 60 minutes -> 1 hour\n        minutes           = absFloor(seconds / 60);\n        hours             = absFloor(minutes / 60);\n        seconds %= 60;\n        minutes %= 60;\n\n        // 12 months -> 1 year\n        years  = absFloor(months / 12);\n        months %= 12;\n\n\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = years;\n        var M = months;\n        var D = days;\n        var h = hours;\n        var m = minutes;\n        var s = seconds;\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        return (total < 0 ? '-' : '') +\n            'P' +\n            (Y ? Y + 'Y' : '') +\n            (M ? M + 'M' : '') +\n            (D ? D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? h + 'H' : '') +\n            (m ? m + 'M' : '') +\n            (s ? s + 'S' : '');\n    }\n\n    var duration_prototype__proto = Duration.prototype;\n\n    duration_prototype__proto.abs            = duration_abs__abs;\n    duration_prototype__proto.add            = duration_add_subtract__add;\n    duration_prototype__proto.subtract       = duration_add_subtract__subtract;\n    duration_prototype__proto.as             = as;\n    duration_prototype__proto.asMilliseconds = asMilliseconds;\n    duration_prototype__proto.asSeconds      = asSeconds;\n    duration_prototype__proto.asMinutes      = asMinutes;\n    duration_prototype__proto.asHours        = asHours;\n    duration_prototype__proto.asDays         = asDays;\n    duration_prototype__proto.asWeeks        = asWeeks;\n    duration_prototype__proto.asMonths       = asMonths;\n    duration_prototype__proto.asYears        = asYears;\n    duration_prototype__proto.valueOf        = duration_as__valueOf;\n    duration_prototype__proto._bubble        = bubble;\n    duration_prototype__proto.get            = duration_get__get;\n    duration_prototype__proto.milliseconds   = milliseconds;\n    duration_prototype__proto.seconds        = seconds;\n    duration_prototype__proto.minutes        = minutes;\n    duration_prototype__proto.hours          = hours;\n    duration_prototype__proto.days           = days;\n    duration_prototype__proto.weeks          = weeks;\n    duration_prototype__proto.months         = months;\n    duration_prototype__proto.years          = years;\n    duration_prototype__proto.humanize       = humanize;\n    duration_prototype__proto.toISOString    = iso_string__toISOString;\n    duration_prototype__proto.toString       = iso_string__toISOString;\n    duration_prototype__proto.toJSON         = iso_string__toISOString;\n    duration_prototype__proto.locale         = locale;\n    duration_prototype__proto.localeData     = localeData;\n\n    // Deprecations\n    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);\n    duration_prototype__proto.lang = lang;\n\n    // Side effect imports\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    utils_hooks__hooks.version = '2.10.6';\n\n    setHookCallback(local__createLocal);\n\n    utils_hooks__hooks.fn                    = momentPrototype;\n    utils_hooks__hooks.min                   = min;\n    utils_hooks__hooks.max                   = max;\n    utils_hooks__hooks.utc                   = create_utc__createUTC;\n    utils_hooks__hooks.unix                  = moment__createUnix;\n    utils_hooks__hooks.months                = lists__listMonths;\n    utils_hooks__hooks.isDate                = isDate;\n    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;\n    utils_hooks__hooks.invalid               = valid__createInvalid;\n    utils_hooks__hooks.duration              = create__createDuration;\n    utils_hooks__hooks.isMoment              = isMoment;\n    utils_hooks__hooks.weekdays              = lists__listWeekdays;\n    utils_hooks__hooks.parseZone             = moment__createInZone;\n    utils_hooks__hooks.localeData            = locale_locales__getLocale;\n    utils_hooks__hooks.isDuration            = isDuration;\n    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;\n    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;\n    utils_hooks__hooks.defineLocale          = defineLocale;\n    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;\n    utils_hooks__hooks.normalizeUnits        = normalizeUnits;\n    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;\n\n    var _moment = utils_hooks__hooks;\n\n    return _moment;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/moment.js\n ** module id = 573\n ** module chunks = 0\n **/","var map = {\n\t\"./af\": 575,\n\t\"./af.js\": 575,\n\t\"./ar\": 576,\n\t\"./ar-ma\": 577,\n\t\"./ar-ma.js\": 577,\n\t\"./ar-sa\": 578,\n\t\"./ar-sa.js\": 578,\n\t\"./ar-tn\": 579,\n\t\"./ar-tn.js\": 579,\n\t\"./ar.js\": 576,\n\t\"./az\": 580,\n\t\"./az.js\": 580,\n\t\"./be\": 581,\n\t\"./be.js\": 581,\n\t\"./bg\": 582,\n\t\"./bg.js\": 582,\n\t\"./bn\": 583,\n\t\"./bn.js\": 583,\n\t\"./bo\": 584,\n\t\"./bo.js\": 584,\n\t\"./br\": 585,\n\t\"./br.js\": 585,\n\t\"./bs\": 586,\n\t\"./bs.js\": 586,\n\t\"./ca\": 587,\n\t\"./ca.js\": 587,\n\t\"./cs\": 588,\n\t\"./cs.js\": 588,\n\t\"./cv\": 589,\n\t\"./cv.js\": 589,\n\t\"./cy\": 590,\n\t\"./cy.js\": 590,\n\t\"./da\": 591,\n\t\"./da.js\": 591,\n\t\"./de\": 592,\n\t\"./de-at\": 593,\n\t\"./de-at.js\": 593,\n\t\"./de.js\": 592,\n\t\"./el\": 594,\n\t\"./el.js\": 594,\n\t\"./en-au\": 595,\n\t\"./en-au.js\": 595,\n\t\"./en-ca\": 596,\n\t\"./en-ca.js\": 596,\n\t\"./en-gb\": 597,\n\t\"./en-gb.js\": 597,\n\t\"./eo\": 598,\n\t\"./eo.js\": 598,\n\t\"./es\": 599,\n\t\"./es.js\": 599,\n\t\"./et\": 600,\n\t\"./et.js\": 600,\n\t\"./eu\": 601,\n\t\"./eu.js\": 601,\n\t\"./fa\": 602,\n\t\"./fa.js\": 602,\n\t\"./fi\": 603,\n\t\"./fi.js\": 603,\n\t\"./fo\": 604,\n\t\"./fo.js\": 604,\n\t\"./fr\": 605,\n\t\"./fr-ca\": 606,\n\t\"./fr-ca.js\": 606,\n\t\"./fr.js\": 605,\n\t\"./fy\": 607,\n\t\"./fy.js\": 607,\n\t\"./gl\": 608,\n\t\"./gl.js\": 608,\n\t\"./he\": 609,\n\t\"./he.js\": 609,\n\t\"./hi\": 610,\n\t\"./hi.js\": 610,\n\t\"./hr\": 611,\n\t\"./hr.js\": 611,\n\t\"./hu\": 612,\n\t\"./hu.js\": 612,\n\t\"./hy-am\": 613,\n\t\"./hy-am.js\": 613,\n\t\"./id\": 614,\n\t\"./id.js\": 614,\n\t\"./is\": 615,\n\t\"./is.js\": 615,\n\t\"./it\": 616,\n\t\"./it.js\": 616,\n\t\"./ja\": 617,\n\t\"./ja.js\": 617,\n\t\"./jv\": 618,\n\t\"./jv.js\": 618,\n\t\"./ka\": 619,\n\t\"./ka.js\": 619,\n\t\"./km\": 620,\n\t\"./km.js\": 620,\n\t\"./ko\": 621,\n\t\"./ko.js\": 621,\n\t\"./lb\": 622,\n\t\"./lb.js\": 622,\n\t\"./lt\": 623,\n\t\"./lt.js\": 623,\n\t\"./lv\": 624,\n\t\"./lv.js\": 624,\n\t\"./me\": 625,\n\t\"./me.js\": 625,\n\t\"./mk\": 626,\n\t\"./mk.js\": 626,\n\t\"./ml\": 627,\n\t\"./ml.js\": 627,\n\t\"./mr\": 628,\n\t\"./mr.js\": 628,\n\t\"./ms\": 629,\n\t\"./ms-my\": 630,\n\t\"./ms-my.js\": 630,\n\t\"./ms.js\": 629,\n\t\"./my\": 631,\n\t\"./my.js\": 631,\n\t\"./nb\": 632,\n\t\"./nb.js\": 632,\n\t\"./ne\": 633,\n\t\"./ne.js\": 633,\n\t\"./nl\": 634,\n\t\"./nl.js\": 634,\n\t\"./nn\": 635,\n\t\"./nn.js\": 635,\n\t\"./pl\": 636,\n\t\"./pl.js\": 636,\n\t\"./pt\": 637,\n\t\"./pt-br\": 638,\n\t\"./pt-br.js\": 638,\n\t\"./pt.js\": 637,\n\t\"./ro\": 639,\n\t\"./ro.js\": 639,\n\t\"./ru\": 640,\n\t\"./ru.js\": 640,\n\t\"./si\": 641,\n\t\"./si.js\": 641,\n\t\"./sk\": 642,\n\t\"./sk.js\": 642,\n\t\"./sl\": 643,\n\t\"./sl.js\": 643,\n\t\"./sq\": 644,\n\t\"./sq.js\": 644,\n\t\"./sr\": 645,\n\t\"./sr-cyrl\": 646,\n\t\"./sr-cyrl.js\": 646,\n\t\"./sr.js\": 645,\n\t\"./sv\": 647,\n\t\"./sv.js\": 647,\n\t\"./ta\": 648,\n\t\"./ta.js\": 648,\n\t\"./th\": 649,\n\t\"./th.js\": 649,\n\t\"./tl-ph\": 650,\n\t\"./tl-ph.js\": 650,\n\t\"./tr\": 651,\n\t\"./tr.js\": 651,\n\t\"./tzl\": 652,\n\t\"./tzl.js\": 652,\n\t\"./tzm\": 653,\n\t\"./tzm-latn\": 654,\n\t\"./tzm-latn.js\": 654,\n\t\"./tzm.js\": 653,\n\t\"./uk\": 655,\n\t\"./uk.js\": 655,\n\t\"./uz\": 656,\n\t\"./uz.js\": 656,\n\t\"./vi\": 657,\n\t\"./vi.js\": 657,\n\t\"./zh-cn\": 658,\n\t\"./zh-cn.js\": 658,\n\t\"./zh-tw\": 659,\n\t\"./zh-tw.js\": 659\n};\nfunction webpackContext(req) {\n\treturn __webpack_require__(webpackContextResolve(req));\n};\nfunction webpackContextResolve(req) {\n\treturn map[req] || (function() { throw new Error(\"Cannot find module '\" + req + \"'.\") }());\n};\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 574;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale ^\\.\\/.*$\n ** module id = 574\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : afrikaans (af)\n//! author : Werner Mollentze : https://github.com/wernerm\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var af = moment.defineLocale('af', {\n        months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n        weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n        weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n        meridiemParse: /vm|nm/i,\n        isPM : function (input) {\n            return /^nm$/i.test(input);\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower ? 'vm' : 'VM';\n            } else {\n                return isLower ? 'nm' : 'NM';\n            }\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[Vandag om] LT',\n            nextDay : '[Môre om] LT',\n            nextWeek : 'dddd [om] LT',\n            lastDay : '[Gister om] LT',\n            lastWeek : '[Laas] dddd [om] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'oor %s',\n            past : '%s gelede',\n            s : '\\'n paar sekondes',\n            m : '\\'n minuut',\n            mm : '%d minute',\n            h : '\\'n uur',\n            hh : '%d ure',\n            d : '\\'n dag',\n            dd : '%d dae',\n            M : '\\'n maand',\n            MM : '%d maande',\n            y : '\\'n jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n        },\n        week : {\n            dow : 1, // Maandag is die eerste dag van die week.\n            doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n        }\n    });\n\n    return af;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/af.js\n ** module id = 575\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! Locale: Arabic (ar)\n//! Author: Abdel Said: https://github.com/abdelsaid\n//! Changes in months, weekdays: Ahmed Elkhatib\n//! Native plural forms: forabi https://github.com/forabi\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    }, pluralForm = function (n) {\n        return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n    }, plurals = {\n        s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n        m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n        h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n        d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n        M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n        y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n    }, pluralize = function (u) {\n        return function (number, withoutSuffix, string, isFuture) {\n            var f = pluralForm(number),\n                str = plurals[u][pluralForm(number)];\n            if (f === 2) {\n                str = str[withoutSuffix ? 0 : 1];\n            }\n            return str.replace(/%d/i, number);\n        };\n    }, months = [\n        'كانون الثاني يناير',\n        'شباط فبراير',\n        'آذار مارس',\n        'نيسان أبريل',\n        'أيار مايو',\n        'حزيران يونيو',\n        'تموز يوليو',\n        'آب أغسطس',\n        'أيلول سبتمبر',\n        'تشرين الأول أكتوبر',\n        'تشرين الثاني نوفمبر',\n        'كانون الأول ديسمبر'\n    ];\n\n    var ar = moment.defineLocale('ar', {\n        months : months,\n        monthsShort : months,\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'D/\\u200FM/\\u200FYYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم عند الساعة] LT',\n            nextDay: '[غدًا عند الساعة] LT',\n            nextWeek: 'dddd [عند الساعة] LT',\n            lastDay: '[أمس عند الساعة] LT',\n            lastWeek: 'dddd [عند الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'بعد %s',\n            past : 'منذ %s',\n            s : pluralize('s'),\n            m : pluralize('m'),\n            mm : pluralize('m'),\n            h : pluralize('h'),\n            hh : pluralize('h'),\n            d : pluralize('d'),\n            dd : pluralize('d'),\n            M : pluralize('M'),\n            MM : pluralize('M'),\n            y : pluralize('y'),\n            yy : pluralize('y')\n        },\n        preparse: function (string) {\n            return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ar;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ar.js\n ** module id = 576\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Moroccan Arabic (ar-ma)\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ar_ma = moment.defineLocale('ar-ma', {\n        months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ar_ma;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ar-ma.js\n ** module id = 577\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Arabic Saudi Arabia (ar-sa)\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    };\n\n    var ar_sa = moment.defineLocale('ar-sa', {\n        months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ar_sa;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ar-sa.js\n ** module id = 578\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale  : Tunisian Arabic (ar-tn)\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ar_tn = moment.defineLocale('ar-tn', {\n        months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY HH:mm',\n            LLLL: 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar: {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'في %s',\n            past: 'منذ %s',\n            s: 'ثوان',\n            m: 'دقيقة',\n            mm: '%d دقائق',\n            h: 'ساعة',\n            hh: '%d ساعات',\n            d: 'يوم',\n            dd: '%d أيام',\n            M: 'شهر',\n            MM: '%d أشهر',\n            y: 'سنة',\n            yy: '%d سنوات'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return ar_tn;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ar-tn.js\n ** module id = 579\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : azerbaijani (az)\n//! author : topchiyev : https://github.com/topchiyev\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var suffixes = {\n        1: '-inci',\n        5: '-inci',\n        8: '-inci',\n        70: '-inci',\n        80: '-inci',\n        2: '-nci',\n        7: '-nci',\n        20: '-nci',\n        50: '-nci',\n        3: '-üncü',\n        4: '-üncü',\n        100: '-üncü',\n        6: '-ncı',\n        9: '-uncu',\n        10: '-uncu',\n        30: '-uncu',\n        60: '-ıncı',\n        90: '-ıncı'\n    };\n\n    var az = moment.defineLocale('az', {\n        months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n        monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n        weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n        weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n        weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[sabah saat] LT',\n            nextWeek : '[gələn həftə] dddd [saat] LT',\n            lastDay : '[dünən] LT',\n            lastWeek : '[keçən həftə] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s əvvəl',\n            s : 'birneçə saniyyə',\n            m : 'bir dəqiqə',\n            mm : '%d dəqiqə',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir il',\n            yy : '%d il'\n        },\n        meridiemParse: /gecə|səhər|gündüz|axşam/,\n        isPM : function (input) {\n            return /^(gündüz|axşam)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'gecə';\n            } else if (hour < 12) {\n                return 'səhər';\n            } else if (hour < 17) {\n                return 'gündüz';\n            } else {\n                return 'axşam';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '-ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return az;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/az.js\n ** module id = 580\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : belarusian (be)\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n            'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n            'dd': 'дзень_дні_дзён',\n            'MM': 'месяц_месяцы_месяцаў',\n            'yy': 'год_гады_гадоў'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвіліна' : 'хвіліну';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'гадзіна' : 'гадзіну';\n        }\n        else {\n            return number + ' ' + plural(format[key], +number);\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n            'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var be = moment.defineLocale('be', {\n        months : monthsCaseReplace,\n        monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., HH:mm',\n            LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n        },\n        calendar : {\n            sameDay: '[Сёння ў] LT',\n            nextDay: '[Заўтра ў] LT',\n            lastDay: '[Учора ў] LT',\n            nextWeek: function () {\n                return '[У] dddd [ў] LT';\n            },\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'праз %s',\n            past : '%s таму',\n            s : 'некалькі секунд',\n            m : relativeTimeWithPlural,\n            mm : relativeTimeWithPlural,\n            h : relativeTimeWithPlural,\n            hh : relativeTimeWithPlural,\n            d : 'дзень',\n            dd : relativeTimeWithPlural,\n            M : 'месяц',\n            MM : relativeTimeWithPlural,\n            y : 'год',\n            yy : relativeTimeWithPlural\n        },\n        meridiemParse: /ночы|раніцы|дня|вечара/,\n        isPM : function (input) {\n            return /^(дня|вечара)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночы';\n            } else if (hour < 12) {\n                return 'раніцы';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечара';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(і|ы|га)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return be;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/be.js\n ** module id = 581\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : bulgarian (bg)\n//! author : Krasen Borisov : https://github.com/kraz\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var bg = moment.defineLocale('bg', {\n        months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd, D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay : '[Днес в] LT',\n            nextDay : '[Утре в] LT',\n            nextWeek : 'dddd [в] LT',\n            lastDay : '[Вчера в] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'след %s',\n            past : 'преди %s',\n            s : 'няколко секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дни',\n            M : 'месец',\n            MM : '%d месеца',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bg;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/bg.js\n ** module id = 582\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Bengali (bn)\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '১',\n        '2': '২',\n        '3': '৩',\n        '4': '৪',\n        '5': '৫',\n        '6': '৬',\n        '7': '৭',\n        '8': '৮',\n        '9': '৯',\n        '0': '০'\n    },\n    numberMap = {\n        '১': '1',\n        '২': '2',\n        '৩': '3',\n        '৪': '4',\n        '৫': '5',\n        '৬': '6',\n        '৭': '7',\n        '৮': '8',\n        '৯': '9',\n        '০': '0'\n    };\n\n    var bn = moment.defineLocale('bn', {\n        months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n        monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),\n        weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'),\n        weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'),\n        weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm সময়',\n            LTS : 'A h:mm:ss সময়',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, A h:mm সময়',\n            LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n        },\n        calendar : {\n            sameDay : '[আজ] LT',\n            nextDay : '[আগামীকাল] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[গতকাল] LT',\n            lastWeek : '[গত] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s পরে',\n            past : '%s আগে',\n            s : 'কএক সেকেন্ড',\n            m : 'এক মিনিট',\n            mm : '%d মিনিট',\n            h : 'এক ঘন্টা',\n            hh : '%d ঘন্টা',\n            d : 'এক দিন',\n            dd : '%d দিন',\n            M : 'এক মাস',\n            MM : '%d মাস',\n            y : 'এক বছর',\n            yy : '%d বছর'\n        },\n        preparse: function (string) {\n            return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /রাত|সকাল|দুপুর|বিকেল|রাত/,\n        isPM: function (input) {\n            return /^(দুপুর|বিকেল|রাত)$/.test(input);\n        },\n        //Bengali is a vast language its spoken\n        //in different forms in various parts of the world.\n        //I have just generalized with most common one used\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'রাত';\n            } else if (hour < 10) {\n                return 'সকাল';\n            } else if (hour < 17) {\n                return 'দুপুর';\n            } else if (hour < 20) {\n                return 'বিকেল';\n            } else {\n                return 'রাত';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bn;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/bn.js\n ** module id = 583\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : tibetan (bo)\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '༡',\n        '2': '༢',\n        '3': '༣',\n        '4': '༤',\n        '5': '༥',\n        '6': '༦',\n        '7': '༧',\n        '8': '༨',\n        '9': '༩',\n        '0': '༠'\n    },\n    numberMap = {\n        '༡': '1',\n        '༢': '2',\n        '༣': '3',\n        '༤': '4',\n        '༥': '5',\n        '༦': '6',\n        '༧': '7',\n        '༨': '8',\n        '༩': '9',\n        '༠': '0'\n    };\n\n    var bo = moment.defineLocale('bo', {\n        months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n        weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm',\n            LTS : 'A h:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, A h:mm',\n            LLLL : 'dddd, D MMMM YYYY, A h:mm'\n        },\n        calendar : {\n            sameDay : '[དི་རིང] LT',\n            nextDay : '[སང་ཉིན] LT',\n            nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n            lastDay : '[ཁ་སང] LT',\n            lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s ལ་',\n            past : '%s སྔན་ལ',\n            s : 'ལམ་སང',\n            m : 'སྐར་མ་གཅིག',\n            mm : '%d སྐར་མ',\n            h : 'ཆུ་ཚོད་གཅིག',\n            hh : '%d ཆུ་ཚོད',\n            d : 'ཉིན་གཅིག',\n            dd : '%d ཉིན་',\n            M : 'ཟླ་བ་གཅིག',\n            MM : '%d ཟླ་བ',\n            y : 'ལོ་གཅིག',\n            yy : '%d ལོ'\n        },\n        preparse: function (string) {\n            return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n        isPM: function (input) {\n            return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'མཚན་མོ';\n            } else if (hour < 10) {\n                return 'ཞོགས་ཀས';\n            } else if (hour < 17) {\n                return 'ཉིན་གུང';\n            } else if (hour < 20) {\n                return 'དགོང་དག';\n            } else {\n                return 'མཚན་མོ';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bo;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/bo.js\n ** module id = 584\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : breton (br)\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function relativeTimeWithMutation(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'munutenn',\n            'MM': 'miz',\n            'dd': 'devezh'\n        };\n        return number + ' ' + mutation(format[key], number);\n    }\n    function specialMutationForYears(number) {\n        switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n        }\n    }\n    function lastNumber(number) {\n        if (number > 9) {\n            return lastNumber(number % 10);\n        }\n        return number;\n    }\n    function mutation(text, number) {\n        if (number === 2) {\n            return softMutation(text);\n        }\n        return text;\n    }\n    function softMutation(text) {\n        var mutationTable = {\n            'm': 'v',\n            'b': 'v',\n            'd': 'z'\n        };\n        if (mutationTable[text.charAt(0)] === undefined) {\n            return text;\n        }\n        return mutationTable[text.charAt(0)] + text.substring(1);\n    }\n\n    var br = moment.defineLocale('br', {\n        months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n        monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n        weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n        weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n        weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h[e]mm A',\n            LTS : 'h[e]mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D [a viz] MMMM YYYY',\n            LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n            LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n        },\n        calendar : {\n            sameDay : '[Hiziv da] LT',\n            nextDay : '[Warc\\'hoazh da] LT',\n            nextWeek : 'dddd [da] LT',\n            lastDay : '[Dec\\'h da] LT',\n            lastWeek : 'dddd [paset da] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'a-benn %s',\n            past : '%s \\'zo',\n            s : 'un nebeud segondennoù',\n            m : 'ur vunutenn',\n            mm : relativeTimeWithMutation,\n            h : 'un eur',\n            hh : '%d eur',\n            d : 'un devezh',\n            dd : relativeTimeWithMutation,\n            M : 'ur miz',\n            MM : relativeTimeWithMutation,\n            y : 'ur bloaz',\n            yy : specialMutationForYears\n        },\n        ordinalParse: /\\d{1,2}(añ|vet)/,\n        ordinal : function (number) {\n            var output = (number === 1) ? 'añ' : 'vet';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return br;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/br.js\n ** module id = 585\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : bosnian (bs)\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var bs = moment.defineLocale('bs', {\n        months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY H:mm',\n            LLLL : 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : translate,\n            mm     : translate,\n            h      : translate,\n            hh     : translate,\n            d      : 'dan',\n            dd     : translate,\n            M      : 'mjesec',\n            MM     : translate,\n            y      : 'godinu',\n            yy     : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bs;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/bs.js\n ** module id = 586\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : catalan (ca)\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ca = moment.defineLocale('ca', {\n        months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),\n        weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n        weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n        weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextDay : function () {\n                return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastDay : function () {\n                return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'fa %s',\n            s : 'uns segons',\n            m : 'un minut',\n            mm : '%d minuts',\n            h : 'una hora',\n            hh : '%d hores',\n            d : 'un dia',\n            dd : '%d dies',\n            M : 'un mes',\n            MM : '%d mesos',\n            y : 'un any',\n            yy : '%d anys'\n        },\n        ordinalParse: /\\d{1,2}(r|n|t|è|a)/,\n        ordinal : function (number, period) {\n            var output = (number === 1) ? 'r' :\n                (number === 2) ? 'n' :\n                (number === 3) ? 'r' :\n                (number === 4) ? 't' : 'è';\n            if (period === 'w' || period === 'W') {\n                output = 'a';\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return ca;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ca.js\n ** module id = 587\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : czech (cs)\n//! author : petrbela : https://github.com/petrbela\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n        monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\n    function plural(n) {\n        return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n        }\n    }\n\n    var cs = moment.defineLocale('cs', {\n        months : months,\n        monthsShort : monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                // use custom parser to solve problem with July (červenec)\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(months, monthsShort)),\n        weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n        weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n        weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY H:mm',\n            LLLL : 'dddd D. MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay: '[dnes v] LT',\n            nextDay: '[zítra v] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n                }\n            },\n            lastDay: '[včera v] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'před %s',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse : /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return cs;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/cs.js\n ** module id = 588\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : chuvash (cv)\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var cv = moment.defineLocale('cv', {\n        months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n        monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n        weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n        weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n        weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n            LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n            LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n        },\n        calendar : {\n            sameDay: '[Паян] LT [сехетре]',\n            nextDay: '[Ыран] LT [сехетре]',\n            lastDay: '[Ӗнер] LT [сехетре]',\n            nextWeek: '[Ҫитес] dddd LT [сехетре]',\n            lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (output) {\n                var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n                return output + affix;\n            },\n            past : '%s каялла',\n            s : 'пӗр-ик ҫеккунт',\n            m : 'пӗр минут',\n            mm : '%d минут',\n            h : 'пӗр сехет',\n            hh : '%d сехет',\n            d : 'пӗр кун',\n            dd : '%d кун',\n            M : 'пӗр уйӑх',\n            MM : '%d уйӑх',\n            y : 'пӗр ҫул',\n            yy : '%d ҫул'\n        },\n        ordinalParse: /\\d{1,2}-мӗш/,\n        ordinal : '%d-мӗш',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return cv;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/cv.js\n ** module id = 589\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Welsh (cy)\n//! author : Robert Allen\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var cy = moment.defineLocale('cy', {\n        months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n        monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n        weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n        weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n        weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n        // time formats are the same as en-gb\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY HH:mm',\n            LLLL: 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar: {\n            sameDay: '[Heddiw am] LT',\n            nextDay: '[Yfory am] LT',\n            nextWeek: 'dddd [am] LT',\n            lastDay: '[Ddoe am] LT',\n            lastWeek: 'dddd [diwethaf am] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'mewn %s',\n            past: '%s yn ôl',\n            s: 'ychydig eiliadau',\n            m: 'munud',\n            mm: '%d munud',\n            h: 'awr',\n            hh: '%d awr',\n            d: 'diwrnod',\n            dd: '%d diwrnod',\n            M: 'mis',\n            MM: '%d mis',\n            y: 'blwyddyn',\n            yy: '%d flynedd'\n        },\n        ordinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n        // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n        ordinal: function (number) {\n            var b = number,\n                output = '',\n                lookup = [\n                    '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                    'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n                ];\n            if (b > 20) {\n                if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                    output = 'fed'; // not 30ain, 70ain or 90ain\n                } else {\n                    output = 'ain';\n                }\n            } else if (b > 0) {\n                output = lookup[b];\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return cy;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/cy.js\n ** module id = 590\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : danish (da)\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var da = moment.defineLocale('da', {\n        months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY HH:mm',\n            LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[I dag kl.] LT',\n            nextDay : '[I morgen kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[I går kl.] LT',\n            lastWeek : '[sidste] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : '%s siden',\n            s : 'få sekunder',\n            m : 'et minut',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dage',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'et år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return da;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/da.js\n ** module id = 591\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : german (de)\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de = moment.defineLocale('de', {\n        months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY HH:mm',\n            LLLL : 'dddd, D. MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : processRelativeTime,\n            mm : '%d Minuten',\n            h : processRelativeTime,\n            hh : '%d Stunden',\n            d : processRelativeTime,\n            dd : processRelativeTime,\n            M : processRelativeTime,\n            MM : processRelativeTime,\n            y : processRelativeTime,\n            yy : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return de;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/de.js\n ** module id = 592\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : austrian german (de-at)\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de_at = moment.defineLocale('de-at', {\n        months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY HH:mm',\n            LLLL : 'dddd, D. MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : processRelativeTime,\n            mm : '%d Minuten',\n            h : processRelativeTime,\n            hh : '%d Stunden',\n            d : processRelativeTime,\n            dd : processRelativeTime,\n            M : processRelativeTime,\n            MM : processRelativeTime,\n            y : processRelativeTime,\n            yy : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return de_at;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/de-at.js\n ** module id = 593\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : modern greek (el)\n//! author : Aggelos Karalias : https://github.com/mehiel\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var el = moment.defineLocale('el', {\n        monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n        monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n        months : function (momentToFormat, format) {\n            if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n                return this._monthsGenitiveEl[momentToFormat.month()];\n            } else {\n                return this._monthsNominativeEl[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n        weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n        weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n        weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'μμ' : 'ΜΜ';\n            } else {\n                return isLower ? 'πμ' : 'ΠΜ';\n            }\n        },\n        isPM : function (input) {\n            return ((input + '').toLowerCase()[0] === 'μ');\n        },\n        meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY h:mm A',\n            LLLL : 'dddd, D MMMM YYYY h:mm A'\n        },\n        calendarEl : {\n            sameDay : '[Σήμερα {}] LT',\n            nextDay : '[Αύριο {}] LT',\n            nextWeek : 'dddd [{}] LT',\n            lastDay : '[Χθες {}] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                    case 6:\n                        return '[το προηγούμενο] dddd [{}] LT';\n                    default:\n                        return '[την προηγούμενη] dddd [{}] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        calendar : function (key, mom) {\n            var output = this._calendarEl[key],\n                hours = mom && mom.hours();\n            if (typeof output === 'function') {\n                output = output.apply(mom);\n            }\n            return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n        },\n        relativeTime : {\n            future : 'σε %s',\n            past : '%s πριν',\n            s : 'λίγα δευτερόλεπτα',\n            m : 'ένα λεπτό',\n            mm : '%d λεπτά',\n            h : 'μία ώρα',\n            hh : '%d ώρες',\n            d : 'μία μέρα',\n            dd : '%d μέρες',\n            M : 'ένας μήνας',\n            MM : '%d μήνες',\n            y : 'ένας χρόνος',\n            yy : '%d χρόνια'\n        },\n        ordinalParse: /\\d{1,2}η/,\n        ordinal: '%dη',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4st is the first week of the year.\n        }\n    });\n\n    return el;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/el.js\n ** module id = 594\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : australian english (en-au)\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var en_au = moment.defineLocale('en-au', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY h:mm A',\n            LLLL : 'dddd, D MMMM YYYY h:mm A'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return en_au;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/en-au.js\n ** module id = 595\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : canadian english (en-ca)\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var en_ca = moment.defineLocale('en-ca', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM, YYYY',\n            LLL : 'D MMMM, YYYY h:mm A',\n            LLLL : 'dddd, D MMMM, YYYY h:mm A'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    return en_ca;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/en-ca.js\n ** module id = 596\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : great britain english (en-gb)\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var en_gb = moment.defineLocale('en-gb', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return en_gb;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/en-gb.js\n ** module id = 597\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : esperanto (eo)\n//! author : Colin Dean : https://github.com/colindean\n//! komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.\n//!          Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var eo = moment.defineLocale('eo', {\n        months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n        weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),\n        weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D[-an de] MMMM, YYYY',\n            LLL : 'D[-an de] MMMM, YYYY HH:mm',\n            LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'\n        },\n        meridiemParse: /[ap]\\.t\\.m/i,\n        isPM: function (input) {\n            return input.charAt(0).toLowerCase() === 'p';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'p.t.m.' : 'P.T.M.';\n            } else {\n                return isLower ? 'a.t.m.' : 'A.T.M.';\n            }\n        },\n        calendar : {\n            sameDay : '[Hodiaŭ je] LT',\n            nextDay : '[Morgaŭ je] LT',\n            nextWeek : 'dddd [je] LT',\n            lastDay : '[Hieraŭ je] LT',\n            lastWeek : '[pasinta] dddd [je] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'je %s',\n            past : 'antaŭ %s',\n            s : 'sekundoj',\n            m : 'minuto',\n            mm : '%d minutoj',\n            h : 'horo',\n            hh : '%d horoj',\n            d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n            dd : '%d tagoj',\n            M : 'monato',\n            MM : '%d monatoj',\n            y : 'jaro',\n            yy : '%d jaroj'\n        },\n        ordinalParse: /\\d{1,2}a/,\n        ordinal : '%da',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return eo;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/eo.js\n ** module id = 598\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : spanish (es)\n//! author : Julio Napurí : https://github.com/julionc\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsShortDot = 'Ene._Feb._Mar._Abr._May._Jun._Jul._Ago._Sep._Oct._Nov._Dic.'.split('_'),\n        monthsShort = 'Ene_Feb_Mar_Abr_May_Jun_Jul_Ago_Sep_Oct_Nov_Dic'.split('_');\n\n    var es = moment.defineLocale('es', {\n        months : 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return monthsShort[m.month()];\n            } else {\n                return monthsShortDot[m.month()];\n            }\n        },\n        weekdays : 'Domingo_Lunes_Martes_Miércoles_Jueves_Viernes_Sábado'.split('_'),\n        weekdaysShort : 'Dom._Lun._Mar._Mié._Jue._Vie._Sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY H:mm',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastDay : function () {\n                return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'hace %s',\n            s : 'unos segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'una hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un año',\n            yy : '%d años'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return es;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/es.js\n ** module id = 599\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : estonian (et)\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n            'm' : ['ühe minuti', 'üks minut'],\n            'mm': [number + ' minuti', number + ' minutit'],\n            'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n            'hh': [number + ' tunni', number + ' tundi'],\n            'd' : ['ühe päeva', 'üks päev'],\n            'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n            'MM': [number + ' kuu', number + ' kuud'],\n            'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n            'yy': [number + ' aasta', number + ' aastat']\n        };\n        if (withoutSuffix) {\n            return format[key][2] ? format[key][2] : format[key][1];\n        }\n        return isFuture ? format[key][0] : format[key][1];\n    }\n\n    var et = moment.defineLocale('et', {\n        months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n        monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n        weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n        weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n        weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n        longDateFormat : {\n            LT   : 'H:mm',\n            LTS : 'H:mm:ss',\n            L    : 'DD.MM.YYYY',\n            LL   : 'D. MMMM YYYY',\n            LLL  : 'D. MMMM YYYY H:mm',\n            LLLL : 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay  : '[Täna,] LT',\n            nextDay  : '[Homme,] LT',\n            nextWeek : '[Järgmine] dddd LT',\n            lastDay  : '[Eile,] LT',\n            lastWeek : '[Eelmine] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s pärast',\n            past   : '%s tagasi',\n            s      : processRelativeTime,\n            m      : processRelativeTime,\n            mm     : processRelativeTime,\n            h      : processRelativeTime,\n            hh     : processRelativeTime,\n            d      : processRelativeTime,\n            dd     : '%d päeva',\n            M      : processRelativeTime,\n            MM     : processRelativeTime,\n            y      : processRelativeTime,\n            yy     : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return et;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/et.js\n ** module id = 600\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : euskara (eu)\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var eu = moment.defineLocale('eu', {\n        months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n        monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n        weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n        weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n        weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY[ko] MMMM[ren] D[a]',\n            LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n            LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n            l : 'YYYY-M-D',\n            ll : 'YYYY[ko] MMM D[a]',\n            lll : 'YYYY[ko] MMM D[a] HH:mm',\n            llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n        },\n        calendar : {\n            sameDay : '[gaur] LT[etan]',\n            nextDay : '[bihar] LT[etan]',\n            nextWeek : 'dddd LT[etan]',\n            lastDay : '[atzo] LT[etan]',\n            lastWeek : '[aurreko] dddd LT[etan]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s barru',\n            past : 'duela %s',\n            s : 'segundo batzuk',\n            m : 'minutu bat',\n            mm : '%d minutu',\n            h : 'ordu bat',\n            hh : '%d ordu',\n            d : 'egun bat',\n            dd : '%d egun',\n            M : 'hilabete bat',\n            MM : '%d hilabete',\n            y : 'urte bat',\n            yy : '%d urte'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return eu;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/eu.js\n ** module id = 601\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Persian (fa)\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '۱',\n        '2': '۲',\n        '3': '۳',\n        '4': '۴',\n        '5': '۵',\n        '6': '۶',\n        '7': '۷',\n        '8': '۸',\n        '9': '۹',\n        '0': '۰'\n    }, numberMap = {\n        '۱': '1',\n        '۲': '2',\n        '۳': '3',\n        '۴': '4',\n        '۵': '5',\n        '۶': '6',\n        '۷': '7',\n        '۸': '8',\n        '۹': '9',\n        '۰': '0'\n    };\n\n    var fa = moment.defineLocale('fa', {\n        months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        meridiemParse: /قبل از ظهر|بعد از ظهر/,\n        isPM: function (input) {\n            return /بعد از ظهر/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'قبل از ظهر';\n            } else {\n                return 'بعد از ظهر';\n            }\n        },\n        calendar : {\n            sameDay : '[امروز ساعت] LT',\n            nextDay : '[فردا ساعت] LT',\n            nextWeek : 'dddd [ساعت] LT',\n            lastDay : '[دیروز ساعت] LT',\n            lastWeek : 'dddd [پیش] [ساعت] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'در %s',\n            past : '%s پیش',\n            s : 'چندین ثانیه',\n            m : 'یک دقیقه',\n            mm : '%d دقیقه',\n            h : 'یک ساعت',\n            hh : '%d ساعت',\n            d : 'یک روز',\n            dd : '%d روز',\n            M : 'یک ماه',\n            MM : '%d ماه',\n            y : 'یک سال',\n            yy : '%d سال'\n        },\n        preparse: function (string) {\n            return string.replace(/[۰-۹]/g, function (match) {\n                return numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        ordinalParse: /\\d{1,2}م/,\n        ordinal : '%dم',\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return fa;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/fa.js\n ** module id = 602\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : finnish (fi)\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n        numbersFuture = [\n            'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n            numbersPast[7], numbersPast[8], numbersPast[9]\n        ];\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = '';\n        switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n        }\n        result = verbalNumber(number, isFuture) + ' ' + result;\n        return result;\n    }\n    function verbalNumber(number, isFuture) {\n        return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n    }\n\n    var fi = moment.defineLocale('fi', {\n        months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n        monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n        weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n        weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'Do MMMM[ta] YYYY',\n            LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n            LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n            l : 'D.M.YYYY',\n            ll : 'Do MMM YYYY',\n            lll : 'Do MMM YYYY, [klo] HH.mm',\n            llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n        },\n        calendar : {\n            sameDay : '[tänään] [klo] LT',\n            nextDay : '[huomenna] [klo] LT',\n            nextWeek : 'dddd [klo] LT',\n            lastDay : '[eilen] [klo] LT',\n            lastWeek : '[viime] dddd[na] [klo] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s päästä',\n            past : '%s sitten',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fi;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/fi.js\n ** module id = 603\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : faroese (fo)\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var fo = moment.defineLocale('fo', {\n        months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n        weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n        weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D. MMMM, YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[Í dag kl.] LT',\n            nextDay : '[Í morgin kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[Í gjár kl.] LT',\n            lastWeek : '[síðstu] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'um %s',\n            past : '%s síðani',\n            s : 'fá sekund',\n            m : 'ein minutt',\n            mm : '%d minuttir',\n            h : 'ein tími',\n            hh : '%d tímar',\n            d : 'ein dagur',\n            dd : '%d dagar',\n            M : 'ein mánaði',\n            MM : '%d mánaðir',\n            y : 'eitt ár',\n            yy : '%d ár'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fo;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/fo.js\n ** module id = 604\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : french (fr)\n//! author : John Fischer : https://github.com/jfroffice\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var fr = moment.defineLocale('fr', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fr;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/fr.js\n ** module id = 605\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : canadian french (fr-ca)\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var fr_ca = moment.defineLocale('fr-ca', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|e)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : 'e');\n        }\n    });\n\n    return fr_ca;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/fr-ca.js\n ** module id = 606\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : frisian (fy)\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n        monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\n    var fy = moment.defineLocale('fy', {\n        months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return monthsShortWithoutDots[m.month()];\n            } else {\n                return monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n        weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n        weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[hjoed om] LT',\n            nextDay: '[moarn om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[juster om] LT',\n            lastWeek: '[ôfrûne] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'oer %s',\n            past : '%s lyn',\n            s : 'in pear sekonden',\n            m : 'ien minút',\n            mm : '%d minuten',\n            h : 'ien oere',\n            hh : '%d oeren',\n            d : 'ien dei',\n            dd : '%d dagen',\n            M : 'ien moanne',\n            MM : '%d moannen',\n            y : 'ien jier',\n            yy : '%d jierren'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fy;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/fy.js\n ** module id = 607\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : galician (gl)\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var gl = moment.defineLocale('gl', {\n        months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),\n        monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'),\n        weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'),\n        weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            lastDay : function () {\n                return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n            },\n            lastWeek : function () {\n                return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (str) {\n                if (str === 'uns segundos') {\n                    return 'nuns segundos';\n                }\n                return 'en ' + str;\n            },\n            past : 'hai %s',\n            s : 'uns segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'unha hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un ano',\n            yy : '%d anos'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return gl;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/gl.js\n ** module id = 608\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Hebrew (he)\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var he = moment.defineLocale('he', {\n        months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n        monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n        weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n        weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n        weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [ב]MMMM YYYY',\n            LLL : 'D [ב]MMMM YYYY HH:mm',\n            LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n            l : 'D/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY HH:mm',\n            llll : 'ddd, D MMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[היום ב־]LT',\n            nextDay : '[מחר ב־]LT',\n            nextWeek : 'dddd [בשעה] LT',\n            lastDay : '[אתמול ב־]LT',\n            lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'בעוד %s',\n            past : 'לפני %s',\n            s : 'מספר שניות',\n            m : 'דקה',\n            mm : '%d דקות',\n            h : 'שעה',\n            hh : function (number) {\n                if (number === 2) {\n                    return 'שעתיים';\n                }\n                return number + ' שעות';\n            },\n            d : 'יום',\n            dd : function (number) {\n                if (number === 2) {\n                    return 'יומיים';\n                }\n                return number + ' ימים';\n            },\n            M : 'חודש',\n            MM : function (number) {\n                if (number === 2) {\n                    return 'חודשיים';\n                }\n                return number + ' חודשים';\n            },\n            y : 'שנה',\n            yy : function (number) {\n                if (number === 2) {\n                    return 'שנתיים';\n                } else if (number % 10 === 0 && number !== 10) {\n                    return number + ' שנה';\n                }\n                return number + ' שנים';\n            }\n        }\n    });\n\n    return he;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/he.js\n ** module id = 609\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : hindi (hi)\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var hi = moment.defineLocale('hi', {\n        months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n        monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm बजे',\n            LTS : 'A h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, A h:mm बजे',\n            LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[कल] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[कल] LT',\n            lastWeek : '[पिछले] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s में',\n            past : '%s पहले',\n            s : 'कुछ ही क्षण',\n            m : 'एक मिनट',\n            mm : '%d मिनट',\n            h : 'एक घंटा',\n            hh : '%d घंटे',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महीने',\n            MM : '%d महीने',\n            y : 'एक वर्ष',\n            yy : '%d वर्ष'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n        // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n        meridiemParse: /रात|सुबह|दोपहर|शाम/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सुबह') {\n                return hour;\n            } else if (meridiem === 'दोपहर') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'शाम') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात';\n            } else if (hour < 10) {\n                return 'सुबह';\n            } else if (hour < 17) {\n                return 'दोपहर';\n            } else if (hour < 20) {\n                return 'शाम';\n            } else {\n                return 'रात';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hi;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/hi.js\n ** module id = 610\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : hrvatski (hr)\n//! author : Bojan Marković : https://github.com/bmarkovic\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var hr = moment.defineLocale('hr', {\n        months : 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'),\n        monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY H:mm',\n            LLLL : 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : translate,\n            mm     : translate,\n            h      : translate,\n            hh     : translate,\n            d      : 'dan',\n            dd     : translate,\n            M      : 'mjesec',\n            MM     : translate,\n            y      : 'godinu',\n            yy     : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hr;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/hr.js\n ** module id = 611\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : hungarian (hu)\n//! author : Adam Brunner : https://github.com/adambrunner\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\n    function translate(number, withoutSuffix, key, isFuture) {\n        var num = number,\n            suffix;\n        switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n        }\n        return '';\n    }\n    function week(isFuture) {\n        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n    }\n\n    var hu = moment.defineLocale('hu', {\n        months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n        monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n        weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n        weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n        weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'YYYY.MM.DD.',\n            LL : 'YYYY. MMMM D.',\n            LLL : 'YYYY. MMMM D. H:mm',\n            LLLL : 'YYYY. MMMM D., dddd H:mm'\n        },\n        meridiemParse: /de|du/i,\n        isPM: function (input) {\n            return input.charAt(1).toLowerCase() === 'u';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower === true ? 'de' : 'DE';\n            } else {\n                return isLower === true ? 'du' : 'DU';\n            }\n        },\n        calendar : {\n            sameDay : '[ma] LT[-kor]',\n            nextDay : '[holnap] LT[-kor]',\n            nextWeek : function () {\n                return week.call(this, true);\n            },\n            lastDay : '[tegnap] LT[-kor]',\n            lastWeek : function () {\n                return week.call(this, false);\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s múlva',\n            past : '%s',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hu;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/hu.js\n ** module id = 612\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Armenian (hy-am)\n//! author : Armendarabyan : https://github.com/armendarabyan\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function monthsShortCaseReplace(m, format) {\n        var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');\n        return monthsShort[m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');\n        return weekdays[m.day()];\n    }\n\n    var hy_am = moment.defineLocale('hy-am', {\n        months : monthsCaseReplace,\n        monthsShort : monthsShortCaseReplace,\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY թ.',\n            LLL : 'D MMMM YYYY թ., HH:mm',\n            LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n        },\n        calendar : {\n            sameDay: '[այսօր] LT',\n            nextDay: '[վաղը] LT',\n            lastDay: '[երեկ] LT',\n            nextWeek: function () {\n                return 'dddd [օրը ժամը] LT';\n            },\n            lastWeek: function () {\n                return '[անցած] dddd [օրը ժամը] LT';\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s հետո',\n            past : '%s առաջ',\n            s : 'մի քանի վայրկյան',\n            m : 'րոպե',\n            mm : '%d րոպե',\n            h : 'ժամ',\n            hh : '%d ժամ',\n            d : 'օր',\n            dd : '%d օր',\n            M : 'ամիս',\n            MM : '%d ամիս',\n            y : 'տարի',\n            yy : '%d տարի'\n        },\n        meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n        isPM: function (input) {\n            return /^(ցերեկվա|երեկոյան)$/.test(input);\n        },\n        meridiem : function (hour) {\n            if (hour < 4) {\n                return 'գիշերվա';\n            } else if (hour < 12) {\n                return 'առավոտվա';\n            } else if (hour < 17) {\n                return 'ցերեկվա';\n            } else {\n                return 'երեկոյան';\n            }\n        },\n        ordinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hy_am;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/hy-am.js\n ** module id = 613\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Bahasa Indonesia (id)\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var id = moment.defineLocale('id', {\n        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n        weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] HH.mm',\n            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n        },\n        meridiemParse: /pagi|siang|sore|malam/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'siang') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'sore' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'siang';\n            } else if (hours < 19) {\n                return 'sore';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Besok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kemarin pukul] LT',\n            lastWeek : 'dddd [lalu pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lalu',\n            s : 'beberapa detik',\n            m : 'semenit',\n            mm : '%d menit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return id;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/id.js\n ** module id = 614\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : icelandic (is)\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(n) {\n        if (n % 100 === 11) {\n            return true;\n        } else if (n % 10 === 1) {\n            return false;\n        }\n        return true;\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n        }\n    }\n\n    var is = moment.defineLocale('is', {\n        months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n        weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n        weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n        weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] H:mm',\n            LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n        },\n        calendar : {\n            sameDay : '[í dag kl.] LT',\n            nextDay : '[á morgun kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[í gær kl.] LT',\n            lastWeek : '[síðasta] dddd [kl.] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'eftir %s',\n            past : 'fyrir %s síðan',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : 'klukkustund',\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return is;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/is.js\n ** module id = 615\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : italian (it)\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var it = moment.defineLocale('it', {\n        months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n        monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n        weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),\n        weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),\n        weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Oggi alle] LT',\n            nextDay: '[Domani alle] LT',\n            nextWeek: 'dddd [alle] LT',\n            lastDay: '[Ieri alle] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 0:\n                        return '[la scorsa] dddd [alle] LT';\n                    default:\n                        return '[lo scorso] dddd [alle] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n            },\n            past : '%s fa',\n            s : 'alcuni secondi',\n            m : 'un minuto',\n            mm : '%d minuti',\n            h : 'un\\'ora',\n            hh : '%d ore',\n            d : 'un giorno',\n            dd : '%d giorni',\n            M : 'un mese',\n            MM : '%d mesi',\n            y : 'un anno',\n            yy : '%d anni'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal: '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return it;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/it.js\n ** module id = 616\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : japanese (ja)\n//! author : LI Long : https://github.com/baryon\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ja = moment.defineLocale('ja', {\n        months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n        weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n        weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n        longDateFormat : {\n            LT : 'Ah時m分',\n            LTS : 'Ah時m分s秒',\n            L : 'YYYY/MM/DD',\n            LL : 'YYYY年M月D日',\n            LLL : 'YYYY年M月D日Ah時m分',\n            LLLL : 'YYYY年M月D日Ah時m分 dddd'\n        },\n        meridiemParse: /午前|午後/i,\n        isPM : function (input) {\n            return input === '午後';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return '午前';\n            } else {\n                return '午後';\n            }\n        },\n        calendar : {\n            sameDay : '[今日] LT',\n            nextDay : '[明日] LT',\n            nextWeek : '[来週]dddd LT',\n            lastDay : '[昨日] LT',\n            lastWeek : '[前週]dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s後',\n            past : '%s前',\n            s : '数秒',\n            m : '1分',\n            mm : '%d分',\n            h : '1時間',\n            hh : '%d時間',\n            d : '1日',\n            dd : '%d日',\n            M : '1ヶ月',\n            MM : '%dヶ月',\n            y : '1年',\n            yy : '%d年'\n        }\n    });\n\n    return ja;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ja.js\n ** module id = 617\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Boso Jowo (jv)\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var jv = moment.defineLocale('jv', {\n        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n        weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n        weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] HH.mm',\n            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n        },\n        meridiemParse: /enjing|siyang|sonten|ndalu/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'enjing') {\n                return hour;\n            } else if (meridiem === 'siyang') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'enjing';\n            } else if (hours < 15) {\n                return 'siyang';\n            } else if (hours < 19) {\n                return 'sonten';\n            } else {\n                return 'ndalu';\n            }\n        },\n        calendar : {\n            sameDay : '[Dinten puniko pukul] LT',\n            nextDay : '[Mbenjang pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kala wingi pukul] LT',\n            lastWeek : 'dddd [kepengker pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'wonten ing %s',\n            past : '%s ingkang kepengker',\n            s : 'sawetawis detik',\n            m : 'setunggal menit',\n            mm : '%d menit',\n            h : 'setunggal jam',\n            hh : '%d jam',\n            d : 'sedinten',\n            dd : '%d dinten',\n            M : 'sewulan',\n            MM : '%d wulan',\n            y : 'setaun',\n            yy : '%d taun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return jv;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/jv.js\n ** module id = 618\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Georgian (ka)\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n            'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n        },\n        nounCase = (/D[oD] *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n            'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')\n        },\n        nounCase = (/(წინა|შემდეგ)/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ka = moment.defineLocale('ka', {\n        months : monthsCaseReplace,\n        monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n        weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY h:mm A',\n            LLLL : 'dddd, D MMMM YYYY h:mm A'\n        },\n        calendar : {\n            sameDay : '[დღეს] LT[-ზე]',\n            nextDay : '[ხვალ] LT[-ზე]',\n            lastDay : '[გუშინ] LT[-ზე]',\n            nextWeek : '[შემდეგ] dddd LT[-ზე]',\n            lastWeek : '[წინა] dddd LT-ზე',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                    s.replace(/ი$/, 'ში') :\n                    s + 'ში';\n            },\n            past : function (s) {\n                if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                    return s.replace(/(ი|ე)$/, 'ის წინ');\n                }\n                if ((/წელი/).test(s)) {\n                    return s.replace(/წელი$/, 'წლის წინ');\n                }\n            },\n            s : 'რამდენიმე წამი',\n            m : 'წუთი',\n            mm : '%d წუთი',\n            h : 'საათი',\n            hh : '%d საათი',\n            d : 'დღე',\n            dd : '%d დღე',\n            M : 'თვე',\n            MM : '%d თვე',\n            y : 'წელი',\n            yy : '%d წელი'\n        },\n        ordinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n        ordinal : function (number) {\n            if (number === 0) {\n                return number;\n            }\n            if (number === 1) {\n                return number + '-ლი';\n            }\n            if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n                return 'მე-' + number;\n            }\n            return number + '-ე';\n        },\n        week : {\n            dow : 1,\n            doy : 7\n        }\n    });\n\n    return ka;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ka.js\n ** module id = 619\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : khmer (km)\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var km = moment.defineLocale('km', {\n        months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY HH:mm',\n            LLLL: 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar: {\n            sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',\n            nextDay: '[ស្អែក ម៉ោង] LT',\n            nextWeek: 'dddd [ម៉ោង] LT',\n            lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n            lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: '%sទៀត',\n            past: '%sមុន',\n            s: 'ប៉ុន្មានវិនាទី',\n            m: 'មួយនាទី',\n            mm: '%d នាទី',\n            h: 'មួយម៉ោង',\n            hh: '%d ម៉ោង',\n            d: 'មួយថ្ងៃ',\n            dd: '%d ថ្ងៃ',\n            M: 'មួយខែ',\n            MM: '%d ខែ',\n            y: 'មួយឆ្នាំ',\n            yy: '%d ឆ្នាំ'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return km;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/km.js\n ** module id = 620\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : korean (ko)\n//!\n//! authors\n//!\n//! - Kyungwook, Park : https://github.com/kyungw00k\n//! - Jeeeyul Lee <jeeeyul@gmail.com>\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ko = moment.defineLocale('ko', {\n        months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n        weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n        weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n        longDateFormat : {\n            LT : 'A h시 m분',\n            LTS : 'A h시 m분 s초',\n            L : 'YYYY.MM.DD',\n            LL : 'YYYY년 MMMM D일',\n            LLL : 'YYYY년 MMMM D일 A h시 m분',\n            LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'\n        },\n        calendar : {\n            sameDay : '오늘 LT',\n            nextDay : '내일 LT',\n            nextWeek : 'dddd LT',\n            lastDay : '어제 LT',\n            lastWeek : '지난주 dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s 후',\n            past : '%s 전',\n            s : '몇초',\n            ss : '%d초',\n            m : '일분',\n            mm : '%d분',\n            h : '한시간',\n            hh : '%d시간',\n            d : '하루',\n            dd : '%d일',\n            M : '한달',\n            MM : '%d달',\n            y : '일년',\n            yy : '%d년'\n        },\n        ordinalParse : /\\d{1,2}일/,\n        ordinal : '%d일',\n        meridiemParse : /오전|오후/,\n        isPM : function (token) {\n            return token === '오후';\n        },\n        meridiem : function (hour, minute, isUpper) {\n            return hour < 12 ? '오전' : '오후';\n        }\n    });\n\n    return ko;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ko.js\n ** module id = 621\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Luxembourgish (lb)\n//! author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eng Minutt', 'enger Minutt'],\n            'h': ['eng Stonn', 'enger Stonn'],\n            'd': ['een Dag', 'engem Dag'],\n            'M': ['ee Mount', 'engem Mount'],\n            'y': ['ee Joer', 'engem Joer']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n    function processFutureTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'a ' + string;\n        }\n        return 'an ' + string;\n    }\n    function processPastTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'viru ' + string;\n        }\n        return 'virun ' + string;\n    }\n    /**\n     * Returns true if the word before the given number loses the '-n' ending.\n     * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n     *\n     * @param number {integer}\n     * @returns {boolean}\n     */\n    function eifelerRegelAppliesToNumber(number) {\n        number = parseInt(number, 10);\n        if (isNaN(number)) {\n            return false;\n        }\n        if (number < 0) {\n            // Negative Number --> always true\n            return true;\n        } else if (number < 10) {\n            // Only 1 digit\n            if (4 <= number && number <= 7) {\n                return true;\n            }\n            return false;\n        } else if (number < 100) {\n            // 2 digits\n            var lastDigit = number % 10, firstDigit = number / 10;\n            if (lastDigit === 0) {\n                return eifelerRegelAppliesToNumber(firstDigit);\n            }\n            return eifelerRegelAppliesToNumber(lastDigit);\n        } else if (number < 10000) {\n            // 3 or 4 digits --> recursively check first digit\n            while (number >= 10) {\n                number = number / 10;\n            }\n            return eifelerRegelAppliesToNumber(number);\n        } else {\n            // Anything larger than 4 digits: recursively check first n-3 digits\n            number = number / 1000;\n            return eifelerRegelAppliesToNumber(number);\n        }\n    }\n\n    var lb = moment.defineLocale('lb', {\n        months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n        weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n        weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'H:mm [Auer]',\n            LTS: 'H:mm:ss [Auer]',\n            L: 'DD.MM.YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY H:mm [Auer]',\n            LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n        },\n        calendar: {\n            sameDay: '[Haut um] LT',\n            sameElse: 'L',\n            nextDay: '[Muer um] LT',\n            nextWeek: 'dddd [um] LT',\n            lastDay: '[Gëschter um] LT',\n            lastWeek: function () {\n                // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n                switch (this.day()) {\n                    case 2:\n                    case 4:\n                        return '[Leschten] dddd [um] LT';\n                    default:\n                        return '[Leschte] dddd [um] LT';\n                }\n            }\n        },\n        relativeTime : {\n            future : processFutureTime,\n            past : processPastTime,\n            s : 'e puer Sekonnen',\n            m : processRelativeTime,\n            mm : '%d Minutten',\n            h : processRelativeTime,\n            hh : '%d Stonnen',\n            d : processRelativeTime,\n            dd : '%d Deeg',\n            M : processRelativeTime,\n            MM : '%d Méint',\n            y : processRelativeTime,\n            yy : '%d Joer'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal: '%d.',\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return lb;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/lb.js\n ** module id = 622\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Lithuanian (lt)\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var units = {\n        'm' : 'minutė_minutės_minutę',\n        'mm': 'minutės_minučių_minutes',\n        'h' : 'valanda_valandos_valandą',\n        'hh': 'valandos_valandų_valandas',\n        'd' : 'diena_dienos_dieną',\n        'dd': 'dienos_dienų_dienas',\n        'M' : 'mėnuo_mėnesio_mėnesį',\n        'MM': 'mėnesiai_mėnesių_mėnesius',\n        'y' : 'metai_metų_metus',\n        'yy': 'metai_metų_metus'\n    },\n    weekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_');\n    function translateSeconds(number, withoutSuffix, key, isFuture) {\n        if (withoutSuffix) {\n            return 'kelios sekundės';\n        } else {\n            return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n                'nominative': 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n                'accusative': 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_')\n            },\n            nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n                'accusative' :\n                'nominative';\n        return months[nounCase][m.month()];\n    }\n    function translateSingular(number, withoutSuffix, key, isFuture) {\n        return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n    }\n    function special(number) {\n        return number % 10 === 0 || (number > 10 && number < 20);\n    }\n    function forms(key) {\n        return units[key].split('_');\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        if (number === 1) {\n            return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n        } else if (withoutSuffix) {\n            return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n        } else {\n            if (isFuture) {\n                return result + forms(key)[1];\n            } else {\n                return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n            }\n        }\n    }\n    function relativeWeekDay(moment, format) {\n        var nominative = format.indexOf('dddd HH:mm') === -1,\n            weekDay = weekDays[moment.day()];\n        return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į';\n    }\n\n    var lt = moment.defineLocale('lt', {\n        months : monthsCaseReplace,\n        monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n        weekdays : relativeWeekDay,\n        weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n        weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY [m.] MMMM D [d.]',\n            LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n            LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY [m.] MMMM D [d.]',\n            lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n            llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n        },\n        calendar : {\n            sameDay : '[Šiandien] LT',\n            nextDay : '[Rytoj] LT',\n            nextWeek : 'dddd LT',\n            lastDay : '[Vakar] LT',\n            lastWeek : '[Praėjusį] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'po %s',\n            past : 'prieš %s',\n            s : translateSeconds,\n            m : translateSingular,\n            mm : translate,\n            h : translateSingular,\n            hh : translate,\n            d : translateSingular,\n            dd : translate,\n            M : translateSingular,\n            MM : translate,\n            y : translateSingular,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}-oji/,\n        ordinal : function (number) {\n            return number + '-oji';\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return lt;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/lt.js\n ** module id = 623\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : latvian (lv)\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var units = {\n        'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n        'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n        'h': 'stundas_stundām_stunda_stundas'.split('_'),\n        'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n        'd': 'dienas_dienām_diena_dienas'.split('_'),\n        'dd': 'dienas_dienām_diena_dienas'.split('_'),\n        'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n        'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n        'y': 'gada_gadiem_gads_gadi'.split('_'),\n        'yy': 'gada_gadiem_gads_gadi'.split('_')\n    };\n    /**\n     * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n     */\n    function format(forms, number, withoutSuffix) {\n        if (withoutSuffix) {\n            // E.g. \"21 minūte\", \"3 minūtes\".\n            return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];\n        } else {\n            // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n            // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n            return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];\n        }\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        return number + ' ' + format(units[key], number, withoutSuffix);\n    }\n    function relativeTimeWithSingular(number, withoutSuffix, key) {\n        return format(units[key], number, withoutSuffix);\n    }\n    function relativeSeconds(number, withoutSuffix) {\n        return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n    }\n\n    var lv = moment.defineLocale('lv', {\n        months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n        weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY.',\n            LL : 'YYYY. [gada] D. MMMM',\n            LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n            LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n        },\n        calendar : {\n            sameDay : '[Šodien pulksten] LT',\n            nextDay : '[Rīt pulksten] LT',\n            nextWeek : 'dddd [pulksten] LT',\n            lastDay : '[Vakar pulksten] LT',\n            lastWeek : '[Pagājušā] dddd [pulksten] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'pēc %s',\n            past : 'pirms %s',\n            s : relativeSeconds,\n            m : relativeTimeWithSingular,\n            mm : relativeTimeWithPlural,\n            h : relativeTimeWithSingular,\n            hh : relativeTimeWithPlural,\n            d : relativeTimeWithSingular,\n            dd : relativeTimeWithPlural,\n            M : relativeTimeWithSingular,\n            MM : relativeTimeWithPlural,\n            y : relativeTimeWithSingular,\n            yy : relativeTimeWithPlural\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return lv;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/lv.js\n ** module id = 624\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Montenegrin (me)\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var translator = {\n        words: { //Different grammatical cases\n            m: ['jedan minut', 'jednog minuta'],\n            mm: ['minut', 'minuta', 'minuta'],\n            h: ['jedan sat', 'jednog sata'],\n            hh: ['sat', 'sata', 'sati'],\n            dd: ['dan', 'dana', 'dana'],\n            MM: ['mjesec', 'mjeseca', 'mjeseci'],\n            yy: ['godina', 'godine', 'godina']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var me = moment.defineLocale('me', {\n        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],\n        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],\n        weekdays: ['nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'četvrtak', 'petak', 'subota'],\n        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sri.', 'čet.', 'pet.', 'sub.'],\n        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'H:mm:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY H:mm',\n            LLLL: 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar: {\n            sameDay: '[danas u] LT',\n            nextDay: '[sjutra u] LT',\n\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[juče u] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[prošle] [nedjelje] [u] LT',\n                    '[prošlog] [ponedjeljka] [u] LT',\n                    '[prošlog] [utorka] [u] LT',\n                    '[prošle] [srijede] [u] LT',\n                    '[prošlog] [četvrtka] [u] LT',\n                    '[prošlog] [petka] [u] LT',\n                    '[prošle] [subote] [u] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'nekoliko sekundi',\n            m      : translator.translate,\n            mm     : translator.translate,\n            h      : translator.translate,\n            hh     : translator.translate,\n            d      : 'dan',\n            dd     : translator.translate,\n            M      : 'mjesec',\n            MM     : translator.translate,\n            y      : 'godinu',\n            yy     : translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return me;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/me.js\n ** module id = 625\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : macedonian (mk)\n//! author : Borislav Mickov : https://github.com/B0k0\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var mk = moment.defineLocale('mk', {\n        months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n        weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd, D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay : '[Денес во] LT',\n            nextDay : '[Утре во] LT',\n            nextWeek : 'dddd [во] LT',\n            lastDay : '[Вчера во] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Во изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Во изминатиот] dddd [во] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'после %s',\n            past : 'пред %s',\n            s : 'неколку секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дена',\n            M : 'месец',\n            MM : '%d месеци',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return mk;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/mk.js\n ** module id = 626\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : malayalam (ml)\n//! author : Floyd Pink : https://github.com/floydpink\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ml = moment.defineLocale('ml', {\n        months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n        monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n        weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n        weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n        weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm -നു',\n            LTS : 'A h:mm:ss -നു',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, A h:mm -നു',\n            LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n        },\n        calendar : {\n            sameDay : '[ഇന്ന്] LT',\n            nextDay : '[നാളെ] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[ഇന്നലെ] LT',\n            lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s കഴിഞ്ഞ്',\n            past : '%s മുൻപ്',\n            s : 'അൽപ നിമിഷങ്ങൾ',\n            m : 'ഒരു മിനിറ്റ്',\n            mm : '%d മിനിറ്റ്',\n            h : 'ഒരു മണിക്കൂർ',\n            hh : '%d മണിക്കൂർ',\n            d : 'ഒരു ദിവസം',\n            dd : '%d ദിവസം',\n            M : 'ഒരു മാസം',\n            MM : '%d മാസം',\n            y : 'ഒരു വർഷം',\n            yy : '%d വർഷം'\n        },\n        meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n        isPM : function (input) {\n            return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'രാത്രി';\n            } else if (hour < 12) {\n                return 'രാവിലെ';\n            } else if (hour < 17) {\n                return 'ഉച്ച കഴിഞ്ഞ്';\n            } else if (hour < 20) {\n                return 'വൈകുന്നേരം';\n            } else {\n                return 'രാത്രി';\n            }\n        }\n    });\n\n    return ml;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ml.js\n ** module id = 627\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Marathi (mr)\n//! author : Harshad Kale : https://github.com/kalehv\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var mr = moment.defineLocale('mr', {\n        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm वाजता',\n            LTS : 'A h:mm:ss वाजता',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, A h:mm वाजता',\n            LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[उद्या] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[काल] LT',\n            lastWeek: '[मागील] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s नंतर',\n            past : '%s पूर्वी',\n            s : 'सेकंद',\n            m: 'एक मिनिट',\n            mm: '%d मिनिटे',\n            h : 'एक तास',\n            hh : '%d तास',\n            d : 'एक दिवस',\n            dd : '%d दिवस',\n            M : 'एक महिना',\n            MM : '%d महिने',\n            y : 'एक वर्ष',\n            yy : '%d वर्षे'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात्री') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सकाळी') {\n                return hour;\n            } else if (meridiem === 'दुपारी') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'सायंकाळी') {\n                return hour + 12;\n            }\n        },\n        meridiem: function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात्री';\n            } else if (hour < 10) {\n                return 'सकाळी';\n            } else if (hour < 17) {\n                return 'दुपारी';\n            } else if (hour < 20) {\n                return 'सायंकाळी';\n            } else {\n                return 'रात्री';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return mr;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/mr.js\n ** module id = 628\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Bahasa Malaysia (ms-MY)\n//! author : Weldan Jamili : https://github.com/weldan\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ms = moment.defineLocale('ms', {\n        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] HH.mm',\n            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n        },\n        meridiemParse: /pagi|tengahari|petang|malam/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'tengahari') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'petang' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'tengahari';\n            } else if (hours < 19) {\n                return 'petang';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Esok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kelmarin pukul] LT',\n            lastWeek : 'dddd [lepas pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lepas',\n            s : 'beberapa saat',\n            m : 'seminit',\n            mm : '%d minit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ms;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ms.js\n ** module id = 629\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Bahasa Malaysia (ms-MY)\n//! author : Weldan Jamili : https://github.com/weldan\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ms_my = moment.defineLocale('ms-my', {\n        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] HH.mm',\n            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n        },\n        meridiemParse: /pagi|tengahari|petang|malam/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'tengahari') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'petang' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'tengahari';\n            } else if (hours < 19) {\n                return 'petang';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Esok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kelmarin pukul] LT',\n            lastWeek : 'dddd [lepas pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lepas',\n            s : 'beberapa saat',\n            m : 'seminit',\n            mm : '%d minit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ms_my;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ms-my.js\n ** module id = 630\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Burmese (my)\n//! author : Squar team, mysquar.com\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '၁',\n        '2': '၂',\n        '3': '၃',\n        '4': '၄',\n        '5': '၅',\n        '6': '၆',\n        '7': '၇',\n        '8': '၈',\n        '9': '၉',\n        '0': '၀'\n    }, numberMap = {\n        '၁': '1',\n        '၂': '2',\n        '၃': '3',\n        '၄': '4',\n        '၅': '5',\n        '၆': '6',\n        '၇': '7',\n        '၈': '8',\n        '၉': '9',\n        '၀': '0'\n    };\n\n    var my = moment.defineLocale('my', {\n        months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n        monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n        weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n        weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY HH:mm',\n            LLLL: 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar: {\n            sameDay: '[ယနေ.] LT [မှာ]',\n            nextDay: '[မနက်ဖြန်] LT [မှာ]',\n            nextWeek: 'dddd LT [မှာ]',\n            lastDay: '[မနေ.က] LT [မှာ]',\n            lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'လာမည့် %s မှာ',\n            past: 'လွန်ခဲ့သော %s က',\n            s: 'စက္ကန်.အနည်းငယ်',\n            m: 'တစ်မိနစ်',\n            mm: '%d မိနစ်',\n            h: 'တစ်နာရီ',\n            hh: '%d နာရီ',\n            d: 'တစ်ရက်',\n            dd: '%d ရက်',\n            M: 'တစ်လ',\n            MM: '%d လ',\n            y: 'တစ်နှစ်',\n            yy: '%d နှစ်'\n        },\n        preparse: function (string) {\n            return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return my;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/my.js\n ** module id = 631\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : norwegian bokmål (nb)\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var nb = moment.defineLocale('nb', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'H.mm',\n            LTS : 'H.mm.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] H.mm',\n            LLLL : 'dddd D. MMMM YYYY [kl.] H.mm'\n        },\n        calendar : {\n            sameDay: '[i dag kl.] LT',\n            nextDay: '[i morgen kl.] LT',\n            nextWeek: 'dddd [kl.] LT',\n            lastDay: '[i går kl.] LT',\n            lastWeek: '[forrige] dddd [kl.] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s siden',\n            s : 'noen sekunder',\n            m : 'ett minutt',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dager',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return nb;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/nb.js\n ** module id = 632\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : nepali/nepalese\n//! author : suvash : https://github.com/suvash\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var ne = moment.defineLocale('ne', {\n        months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n        monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n        weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n        weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n        weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'),\n        longDateFormat : {\n            LT : 'Aको h:mm बजे',\n            LTS : 'Aको h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, Aको h:mm बजे',\n            LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'राती') {\n                return hour < 3 ? hour : hour + 12;\n            } else if (meridiem === 'बिहान') {\n                return hour;\n            } else if (meridiem === 'दिउँसो') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'बेलुका' || meridiem === 'साँझ') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 3) {\n                return 'राती';\n            } else if (hour < 10) {\n                return 'बिहान';\n            } else if (hour < 15) {\n                return 'दिउँसो';\n            } else if (hour < 18) {\n                return 'बेलुका';\n            } else if (hour < 20) {\n                return 'साँझ';\n            } else {\n                return 'राती';\n            }\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[भोली] LT',\n            nextWeek : '[आउँदो] dddd[,] LT',\n            lastDay : '[हिजो] LT',\n            lastWeek : '[गएको] dddd[,] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%sमा',\n            past : '%s अगाडी',\n            s : 'केही समय',\n            m : 'एक मिनेट',\n            mm : '%d मिनेट',\n            h : 'एक घण्टा',\n            hh : '%d घण्टा',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महिना',\n            MM : '%d महिना',\n            y : 'एक बर्ष',\n            yy : '%d बर्ष'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ne;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ne.js\n ** module id = 633\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : dutch (nl)\n//! author : Joris Röling : https://github.com/jjupiter\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\n    var nl = moment.defineLocale('nl', {\n        months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return monthsShortWithoutDots[m.month()];\n            } else {\n                return monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n        weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n        weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[vandaag om] LT',\n            nextDay: '[morgen om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[gisteren om] LT',\n            lastWeek: '[afgelopen] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'over %s',\n            past : '%s geleden',\n            s : 'een paar seconden',\n            m : 'één minuut',\n            mm : '%d minuten',\n            h : 'één uur',\n            hh : '%d uur',\n            d : 'één dag',\n            dd : '%d dagen',\n            M : 'één maand',\n            MM : '%d maanden',\n            y : 'één jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return nl;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/nl.js\n ** module id = 634\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : norwegian nynorsk (nn)\n//! author : https://github.com/mechuwind\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var nn = moment.defineLocale('nn', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n        weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n        weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[I dag klokka] LT',\n            nextDay: '[I morgon klokka] LT',\n            nextWeek: 'dddd [klokka] LT',\n            lastDay: '[I går klokka] LT',\n            lastWeek: '[Føregåande] dddd [klokka] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s sidan',\n            s : 'nokre sekund',\n            m : 'eit minutt',\n            mm : '%d minutt',\n            h : 'ein time',\n            hh : '%d timar',\n            d : 'ein dag',\n            dd : '%d dagar',\n            M : 'ein månad',\n            MM : '%d månader',\n            y : 'eit år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return nn;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/nn.js\n ** module id = 635\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : polish (pl)\n//! author : Rafal Hirsz : https://github.com/evoL\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n        monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\n    function plural(n) {\n        return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n    }\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural(number) ? 'lata' : 'lat');\n        }\n    }\n\n    var pl = moment.defineLocale('pl', {\n        months : function (momentToFormat, format) {\n            if (format === '') {\n                // Hack: if format empty we know this is used to generate\n                // RegExp by moment. Give then back both valid forms of months\n                // in RegExp ready format.\n                return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n            } else if (/D MMMM/.test(format)) {\n                return monthsSubjective[momentToFormat.month()];\n            } else {\n                return monthsNominative[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n        weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n        weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),\n        weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Dziś o] LT',\n            nextDay: '[Jutro o] LT',\n            nextWeek: '[W] dddd [o] LT',\n            lastDay: '[Wczoraj o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : '%s temu',\n            s : 'kilka sekund',\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : '1 dzień',\n            dd : '%d dni',\n            M : 'miesiąc',\n            MM : translate,\n            y : 'rok',\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return pl;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/pl.js\n ** module id = 636\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : portuguese (pt)\n//! author : Jefferson : https://github.com/jalex79\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var pt = moment.defineLocale('pt', {\n        months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n        monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n        weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n        weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n        weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY HH:mm',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : 'há %s',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return pt;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/pt.js\n ** module id = 637\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : brazilian portuguese (pt-br)\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var pt_br = moment.defineLocale('pt-br', {\n        months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n        monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n        weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n        weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n        weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : '%s atrás',\n            s : 'poucos segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº'\n    });\n\n    return pt_br;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/pt-br.js\n ** module id = 638\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : romanian (ro)\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n                'mm': 'minute',\n                'hh': 'ore',\n                'dd': 'zile',\n                'MM': 'luni',\n                'yy': 'ani'\n            },\n            separator = ' ';\n        if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n            separator = ' de ';\n        }\n        return number + separator + format[key];\n    }\n\n    var ro = moment.defineLocale('ro', {\n        months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n        monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n        weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n        weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n        weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd, D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay: '[azi la] LT',\n            nextDay: '[mâine la] LT',\n            nextWeek: 'dddd [la] LT',\n            lastDay: '[ieri la] LT',\n            lastWeek: '[fosta] dddd [la] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'peste %s',\n            past : '%s în urmă',\n            s : 'câteva secunde',\n            m : 'un minut',\n            mm : relativeTimeWithPlural,\n            h : 'o oră',\n            hh : relativeTimeWithPlural,\n            d : 'o zi',\n            dd : relativeTimeWithPlural,\n            M : 'o lună',\n            MM : relativeTimeWithPlural,\n            y : 'un an',\n            yy : relativeTimeWithPlural\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ro;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ro.js\n ** module id = 639\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : russian (ru)\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n            'hh': 'час_часа_часов',\n            'dd': 'день_дня_дней',\n            'MM': 'месяц_месяца_месяцев',\n            'yy': 'год_года_лет'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'минута' : 'минуту';\n        }\n        else {\n            return number + ' ' + plural(format[key], +number);\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n            'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function monthsShortCaseReplace(m, format) {\n        var monthsShort = {\n            'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return monthsShort[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n            'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ru = moment.defineLocale('ru', {\n        months : monthsCaseReplace,\n        monthsShort : monthsShortCaseReplace,\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., HH:mm',\n            LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n        },\n        calendar : {\n            sameDay: '[Сегодня в] LT',\n            nextDay: '[Завтра в] LT',\n            lastDay: '[Вчера в] LT',\n            nextWeek: function () {\n                return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';\n            },\n            lastWeek: function (now) {\n                if (now.week() !== this.week()) {\n                    switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                    }\n                } else {\n                    if (this.day() === 2) {\n                        return '[Во] dddd [в] LT';\n                    } else {\n                        return '[В] dddd [в] LT';\n                    }\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'через %s',\n            past : '%s назад',\n            s : 'несколько секунд',\n            m : relativeTimeWithPlural,\n            mm : relativeTimeWithPlural,\n            h : 'час',\n            hh : relativeTimeWithPlural,\n            d : 'день',\n            dd : relativeTimeWithPlural,\n            M : 'месяц',\n            MM : relativeTimeWithPlural,\n            y : 'год',\n            yy : relativeTimeWithPlural\n        },\n        meridiemParse: /ночи|утра|дня|вечера/i,\n        isPM : function (input) {\n            return /^(дня|вечера)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночи';\n            } else if (hour < 12) {\n                return 'утра';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечера';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го|я)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ru;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ru.js\n ** module id = 640\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Sinhalese (si)\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var si = moment.defineLocale('si', {\n        months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n        monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n        weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n        weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n        weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n        longDateFormat : {\n            LT : 'a h:mm',\n            LTS : 'a h:mm:ss',\n            L : 'YYYY/MM/DD',\n            LL : 'YYYY MMMM D',\n            LLL : 'YYYY MMMM D, a h:mm',\n            LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n        },\n        calendar : {\n            sameDay : '[අද] LT[ට]',\n            nextDay : '[හෙට] LT[ට]',\n            nextWeek : 'dddd LT[ට]',\n            lastDay : '[ඊයේ] LT[ට]',\n            lastWeek : '[පසුගිය] dddd LT[ට]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%sකින්',\n            past : '%sකට පෙර',\n            s : 'තත්පර කිහිපය',\n            m : 'මිනිත්තුව',\n            mm : 'මිනිත්තු %d',\n            h : 'පැය',\n            hh : 'පැය %d',\n            d : 'දිනය',\n            dd : 'දින %d',\n            M : 'මාසය',\n            MM : 'මාස %d',\n            y : 'වසර',\n            yy : 'වසර %d'\n        },\n        ordinalParse: /\\d{1,2} වැනි/,\n        ordinal : function (number) {\n            return number + ' වැනි';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'ප.ව.' : 'පස් වරු';\n            } else {\n                return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n            }\n        }\n    });\n\n    return si;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/si.js\n ** module id = 641\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : slovak (sk)\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n        monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\n    function plural(n) {\n        return (n > 1) && (n < 5);\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n        }\n    }\n\n    var sk = moment.defineLocale('sk', {\n        months : months,\n        monthsShort : monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                // use custom parser to solve problem with July (červenec)\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(months, monthsShort)),\n        weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n        weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n        weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY H:mm',\n            LLLL : 'dddd D. MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay: '[dnes o] LT',\n            nextDay: '[zajtra o] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n                }\n            },\n            lastDay: '[včera o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'pred %s',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return sk;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/sk.js\n ** module id = 642\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : slovenian (sl)\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n        }\n    }\n\n    var sl = moment.defineLocale('sl', {\n        months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n        weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n        weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'H:mm:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY H:mm',\n            LLLL : 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay  : '[danes ob] LT',\n            nextDay  : '[jutri ob] LT',\n\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n                }\n            },\n            lastDay  : '[včeraj ob] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'čez %s',\n            past   : 'pred %s',\n            s      : processRelativeTime,\n            m      : processRelativeTime,\n            mm     : processRelativeTime,\n            h      : processRelativeTime,\n            hh     : processRelativeTime,\n            d      : processRelativeTime,\n            dd     : processRelativeTime,\n            M      : processRelativeTime,\n            MM     : processRelativeTime,\n            y      : processRelativeTime,\n            yy     : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return sl;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/sl.js\n ** module id = 643\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Albanian (sq)\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author: Menelion Elensúle: https://github.com/Oire (tests)\n//! author : Oerd Cukalla : https://github.com/oerd (fixes)\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var sq = moment.defineLocale('sq', {\n        months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n        monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n        weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n        weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n        weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n        meridiemParse: /PD|MD/,\n        isPM: function (input) {\n            return input.charAt(0) === 'M';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            return hours < 12 ? 'PD' : 'MD';\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[Sot në] LT',\n            nextDay : '[Nesër në] LT',\n            nextWeek : 'dddd [në] LT',\n            lastDay : '[Dje në] LT',\n            lastWeek : 'dddd [e kaluar në] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'në %s',\n            past : '%s më parë',\n            s : 'disa sekonda',\n            m : 'një minutë',\n            mm : '%d minuta',\n            h : 'një orë',\n            hh : '%d orë',\n            d : 'një ditë',\n            dd : '%d ditë',\n            M : 'një muaj',\n            MM : '%d muaj',\n            y : 'një vit',\n            yy : '%d vite'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return sq;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/sq.js\n ** module id = 644\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Serbian-latin (sr)\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var translator = {\n        words: { //Different grammatical cases\n            m: ['jedan minut', 'jedne minute'],\n            mm: ['minut', 'minute', 'minuta'],\n            h: ['jedan sat', 'jednog sata'],\n            hh: ['sat', 'sata', 'sati'],\n            dd: ['dan', 'dana', 'dana'],\n            MM: ['mesec', 'meseca', 'meseci'],\n            yy: ['godina', 'godine', 'godina']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr = moment.defineLocale('sr', {\n        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],\n        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],\n        weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],\n        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],\n        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'H:mm:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY H:mm',\n            LLLL: 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar: {\n            sameDay: '[danas u] LT',\n            nextDay: '[sutra u] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[juče u] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[prošle] [nedelje] [u] LT',\n                    '[prošlog] [ponedeljka] [u] LT',\n                    '[prošlog] [utorka] [u] LT',\n                    '[prošle] [srede] [u] LT',\n                    '[prošlog] [četvrtka] [u] LT',\n                    '[prošlog] [petka] [u] LT',\n                    '[prošle] [subote] [u] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'pre %s',\n            s      : 'nekoliko sekundi',\n            m      : translator.translate,\n            mm     : translator.translate,\n            h      : translator.translate,\n            hh     : translator.translate,\n            d      : 'dan',\n            dd     : translator.translate,\n            M      : 'mesec',\n            MM     : translator.translate,\n            y      : 'godinu',\n            yy     : translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return sr;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/sr.js\n ** module id = 645\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Serbian-cyrillic (sr-cyrl)\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var translator = {\n        words: { //Different grammatical cases\n            m: ['један минут', 'једне минуте'],\n            mm: ['минут', 'минуте', 'минута'],\n            h: ['један сат', 'једног сата'],\n            hh: ['сат', 'сата', 'сати'],\n            dd: ['дан', 'дана', 'дана'],\n            MM: ['месец', 'месеца', 'месеци'],\n            yy: ['година', 'године', 'година']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr_cyrl = moment.defineLocale('sr-cyrl', {\n        months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],\n        monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],\n        weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],\n        weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],\n        weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'H:mm:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY H:mm',\n            LLLL: 'dddd, D. MMMM YYYY H:mm'\n        },\n        calendar: {\n            sameDay: '[данас у] LT',\n            nextDay: '[сутра у] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n                }\n            },\n            lastDay  : '[јуче у] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[прошле] [недеље] [у] LT',\n                    '[прошлог] [понедељка] [у] LT',\n                    '[прошлог] [уторка] [у] LT',\n                    '[прошле] [среде] [у] LT',\n                    '[прошлог] [четвртка] [у] LT',\n                    '[прошлог] [петка] [у] LT',\n                    '[прошле] [суботе] [у] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past   : 'пре %s',\n            s      : 'неколико секунди',\n            m      : translator.translate,\n            mm     : translator.translate,\n            h      : translator.translate,\n            hh     : translator.translate,\n            d      : 'дан',\n            dd     : translator.translate,\n            M      : 'месец',\n            MM     : translator.translate,\n            y      : 'годину',\n            yy     : translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return sr_cyrl;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/sr-cyrl.js\n ** module id = 646\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : swedish (sv)\n//! author : Jens Alm : https://github.com/ulmus\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var sv = moment.defineLocale('sv', {\n        months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n        weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n        weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Idag] LT',\n            nextDay: '[Imorgon] LT',\n            lastDay: '[Igår] LT',\n            nextWeek: '[På] dddd LT',\n            lastWeek: '[I] dddd[s] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'för %s sedan',\n            s : 'några sekunder',\n            m : 'en minut',\n            mm : '%d minuter',\n            h : 'en timme',\n            hh : '%d timmar',\n            d : 'en dag',\n            dd : '%d dagar',\n            M : 'en månad',\n            MM : '%d månader',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}(e|a)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'e' :\n                (b === 1) ? 'a' :\n                (b === 2) ? 'a' :\n                (b === 3) ? 'e' : 'e';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return sv;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/sv.js\n ** module id = 647\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : tamil (ta)\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ta = moment.defineLocale('ta', {\n        months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n        weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n        weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, HH:mm',\n            LLLL : 'dddd, D MMMM YYYY, HH:mm'\n        },\n        calendar : {\n            sameDay : '[இன்று] LT',\n            nextDay : '[நாளை] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[நேற்று] LT',\n            lastWeek : '[கடந்த வாரம்] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s இல்',\n            past : '%s முன்',\n            s : 'ஒரு சில விநாடிகள்',\n            m : 'ஒரு நிமிடம்',\n            mm : '%d நிமிடங்கள்',\n            h : 'ஒரு மணி நேரம்',\n            hh : '%d மணி நேரம்',\n            d : 'ஒரு நாள்',\n            dd : '%d நாட்கள்',\n            M : 'ஒரு மாதம்',\n            MM : '%d மாதங்கள்',\n            y : 'ஒரு வருடம்',\n            yy : '%d ஆண்டுகள்'\n        },\n        ordinalParse: /\\d{1,2}வது/,\n        ordinal : function (number) {\n            return number + 'வது';\n        },\n        // refer http://ta.wikipedia.org/s/1er1\n        meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 2) {\n                return ' யாமம்';\n            } else if (hour < 6) {\n                return ' வைகறை';  // வைகறை\n            } else if (hour < 10) {\n                return ' காலை'; // காலை\n            } else if (hour < 14) {\n                return ' நண்பகல்'; // நண்பகல்\n            } else if (hour < 18) {\n                return ' எற்பாடு'; // எற்பாடு\n            } else if (hour < 22) {\n                return ' மாலை'; // மாலை\n            } else {\n                return ' யாமம்';\n            }\n        },\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'யாமம்') {\n                return hour < 2 ? hour : hour + 12;\n            } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n                return hour;\n            } else if (meridiem === 'நண்பகல்') {\n                return hour >= 10 ? hour : hour + 12;\n            } else {\n                return hour + 12;\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ta;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/ta.js\n ** module id = 648\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : thai (th)\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var th = moment.defineLocale('th', {\n        months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n        monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'),\n        weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n        weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n        weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n        longDateFormat : {\n            LT : 'H นาฬิกา m นาที',\n            LTS : 'H นาฬิกา m นาที s วินาที',\n            L : 'YYYY/MM/DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',\n            LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'\n        },\n        meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n        isPM: function (input) {\n            return input === 'หลังเที่ยง';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ก่อนเที่ยง';\n            } else {\n                return 'หลังเที่ยง';\n            }\n        },\n        calendar : {\n            sameDay : '[วันนี้ เวลา] LT',\n            nextDay : '[พรุ่งนี้ เวลา] LT',\n            nextWeek : 'dddd[หน้า เวลา] LT',\n            lastDay : '[เมื่อวานนี้ เวลา] LT',\n            lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'อีก %s',\n            past : '%sที่แล้ว',\n            s : 'ไม่กี่วินาที',\n            m : '1 นาที',\n            mm : '%d นาที',\n            h : '1 ชั่วโมง',\n            hh : '%d ชั่วโมง',\n            d : '1 วัน',\n            dd : '%d วัน',\n            M : '1 เดือน',\n            MM : '%d เดือน',\n            y : '1 ปี',\n            yy : '%d ปี'\n        }\n    });\n\n    return th;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/th.js\n ** module id = 649\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Tagalog/Filipino (tl-ph)\n//! author : Dan Hagman\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var tl_ph = moment.defineLocale('tl-ph', {\n        months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n        monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n        weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n        weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n        weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'MM/D/YYYY',\n            LL : 'MMMM D, YYYY',\n            LLL : 'MMMM D, YYYY HH:mm',\n            LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Ngayon sa] LT',\n            nextDay: '[Bukas sa] LT',\n            nextWeek: 'dddd [sa] LT',\n            lastDay: '[Kahapon sa] LT',\n            lastWeek: 'dddd [huling linggo] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'sa loob ng %s',\n            past : '%s ang nakalipas',\n            s : 'ilang segundo',\n            m : 'isang minuto',\n            mm : '%d minuto',\n            h : 'isang oras',\n            hh : '%d oras',\n            d : 'isang araw',\n            dd : '%d araw',\n            M : 'isang buwan',\n            MM : '%d buwan',\n            y : 'isang taon',\n            yy : '%d taon'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return tl_ph;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/tl-ph.js\n ** module id = 650\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : turkish (tr)\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var suffixes = {\n        1: '\\'inci',\n        5: '\\'inci',\n        8: '\\'inci',\n        70: '\\'inci',\n        80: '\\'inci',\n        2: '\\'nci',\n        7: '\\'nci',\n        20: '\\'nci',\n        50: '\\'nci',\n        3: '\\'üncü',\n        4: '\\'üncü',\n        100: '\\'üncü',\n        6: '\\'ncı',\n        9: '\\'uncu',\n        10: '\\'uncu',\n        30: '\\'uncu',\n        60: '\\'ıncı',\n        90: '\\'ıncı'\n    };\n\n    var tr = moment.defineLocale('tr', {\n        months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n        monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n        weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n        weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n        weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd, D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[yarın saat] LT',\n            nextWeek : '[haftaya] dddd [saat] LT',\n            lastDay : '[dün] LT',\n            lastWeek : '[geçen hafta] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s önce',\n            s : 'birkaç saniye',\n            m : 'bir dakika',\n            mm : '%d dakika',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir yıl',\n            yy : '%d yıl'\n        },\n        ordinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '\\'ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return tr;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/tr.js\n ** module id = 651\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : talossan (tzl)\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n\n    var tzl = moment.defineLocale('tzl', {\n        months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n        monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n        weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n        weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n        weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM [dallas] YYYY',\n            LLL : 'D. MMMM [dallas] YYYY LT',\n            LLLL : 'dddd, [li] D. MMMM [dallas] YYYY LT'\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'd\\'o' : 'D\\'O';\n            } else {\n                return isLower ? 'd\\'a' : 'D\\'A';\n            }\n        },\n        calendar : {\n            sameDay : '[oxhi à] LT',\n            nextDay : '[demà à] LT',\n            nextWeek : 'dddd [à] LT',\n            lastDay : '[ieiri à] LT',\n            lastWeek : '[sür el] dddd [lasteu à] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'osprei %s',\n            past : 'ja%s',\n            s : processRelativeTime,\n            m : processRelativeTime,\n            mm : processRelativeTime,\n            h : processRelativeTime,\n            hh : processRelativeTime,\n            d : processRelativeTime,\n            dd : processRelativeTime,\n            M : processRelativeTime,\n            MM : processRelativeTime,\n            y : processRelativeTime,\n            yy : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            's': ['viensas secunds', '\\'iensas secunds'],\n            'm': ['\\'n míut', '\\'iens míut'],\n            'mm': [number + ' míuts', ' ' + number + ' míuts'],\n            'h': ['\\'n þora', '\\'iensa þora'],\n            'hh': [number + ' þoras', ' ' + number + ' þoras'],\n            'd': ['\\'n ziua', '\\'iensa ziua'],\n            'dd': [number + ' ziuas', ' ' + number + ' ziuas'],\n            'M': ['\\'n mes', '\\'iens mes'],\n            'MM': [number + ' mesen', ' ' + number + ' mesen'],\n            'y': ['\\'n ar', '\\'iens ar'],\n            'yy': [number + ' ars', ' ' + number + ' ars']\n        };\n        return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1].trim());\n    }\n\n    return tzl;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/tzl.js\n ** module id = 652\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Morocco Central Atlas Tamaziɣt (tzm)\n//! author : Abdel Said : https://github.com/abdelsaid\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var tzm = moment.defineLocale('tzm', {\n        months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n            nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n            nextWeek: 'dddd [ⴴ] LT',\n            lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n            lastWeek: 'dddd [ⴴ] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n            past : 'ⵢⴰⵏ %s',\n            s : 'ⵉⵎⵉⴽ',\n            m : 'ⵎⵉⵏⵓⴺ',\n            mm : '%d ⵎⵉⵏⵓⴺ',\n            h : 'ⵙⴰⵄⴰ',\n            hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n            d : 'ⴰⵙⵙ',\n            dd : '%d oⵙⵙⴰⵏ',\n            M : 'ⴰⵢoⵓⵔ',\n            MM : '%d ⵉⵢⵢⵉⵔⵏ',\n            y : 'ⴰⵙⴳⴰⵙ',\n            yy : '%d ⵉⵙⴳⴰⵙⵏ'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return tzm;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/tzm.js\n ** module id = 653\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)\n//! author : Abdel Said : https://github.com/abdelsaid\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var tzm_latn = moment.defineLocale('tzm-latn', {\n        months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'dddd D MMMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[asdkh g] LT',\n            nextDay: '[aska g] LT',\n            nextWeek: 'dddd [g] LT',\n            lastDay: '[assant g] LT',\n            lastWeek: 'dddd [g] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dadkh s yan %s',\n            past : 'yan %s',\n            s : 'imik',\n            m : 'minuḍ',\n            mm : '%d minuḍ',\n            h : 'saɛa',\n            hh : '%d tassaɛin',\n            d : 'ass',\n            dd : '%d ossan',\n            M : 'ayowr',\n            MM : '%d iyyirn',\n            y : 'asgas',\n            yy : '%d isgasn'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return tzm_latn;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/tzm-latn.js\n ** module id = 654\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : ukrainian (uk)\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'хвилина_хвилини_хвилин',\n            'hh': 'година_години_годин',\n            'dd': 'день_дні_днів',\n            'MM': 'місяць_місяці_місяців',\n            'yy': 'рік_роки_років'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвилина' : 'хвилину';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'година' : 'годину';\n        }\n        else {\n            return number + ' ' + plural(format[key], +number);\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n            'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n        },\n        nounCase = (/D[oD]? *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n            'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n            'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n        },\n        nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n            'accusative' :\n            ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n                'genitive' :\n                'nominative');\n        return weekdays[nounCase][m.day()];\n    }\n    function processHoursFunction(str) {\n        return function () {\n            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n        };\n    }\n\n    var uk = moment.defineLocale('uk', {\n        months : monthsCaseReplace,\n        monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY р.',\n            LLL : 'D MMMM YYYY р., HH:mm',\n            LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n        },\n        calendar : {\n            sameDay: processHoursFunction('[Сьогодні '),\n            nextDay: processHoursFunction('[Завтра '),\n            lastDay: processHoursFunction('[Вчора '),\n            nextWeek: processHoursFunction('[У] dddd ['),\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past : '%s тому',\n            s : 'декілька секунд',\n            m : relativeTimeWithPlural,\n            mm : relativeTimeWithPlural,\n            h : 'годину',\n            hh : relativeTimeWithPlural,\n            d : 'день',\n            dd : relativeTimeWithPlural,\n            M : 'місяць',\n            MM : relativeTimeWithPlural,\n            y : 'рік',\n            yy : relativeTimeWithPlural\n        },\n        // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n        meridiemParse: /ночі|ранку|дня|вечора/,\n        isPM: function (input) {\n            return /^(дня|вечора)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночі';\n            } else if (hour < 12) {\n                return 'ранку';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечора';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return uk;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/uk.js\n ** module id = 655\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : uzbek (uz)\n//! author : Sardor Muminov : https://github.com/muminoff\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var uz = moment.defineLocale('uz', {\n        months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n        weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n        weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n        weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY HH:mm',\n            LLLL : 'D MMMM YYYY, dddd HH:mm'\n        },\n        calendar : {\n            sameDay : '[Бугун соат] LT [да]',\n            nextDay : '[Эртага] LT [да]',\n            nextWeek : 'dddd [куни соат] LT [да]',\n            lastDay : '[Кеча соат] LT [да]',\n            lastWeek : '[Утган] dddd [куни соат] LT [да]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'Якин %s ичида',\n            past : 'Бир неча %s олдин',\n            s : 'фурсат',\n            m : 'бир дакика',\n            mm : '%d дакика',\n            h : 'бир соат',\n            hh : '%d соат',\n            d : 'бир кун',\n            dd : '%d кун',\n            M : 'бир ой',\n            MM : '%d ой',\n            y : 'бир йил',\n            yy : '%d йил'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return uz;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/uz.js\n ** module id = 656\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : vietnamese (vi)\n//! author : Bang Nguyen : https://github.com/bangnk\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var vi = moment.defineLocale('vi', {\n        months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n        monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n        weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n        weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM [năm] YYYY',\n            LLL : 'D MMMM [năm] YYYY HH:mm',\n            LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n            l : 'DD/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY HH:mm',\n            llll : 'ddd, D MMM YYYY HH:mm'\n        },\n        calendar : {\n            sameDay: '[Hôm nay lúc] LT',\n            nextDay: '[Ngày mai lúc] LT',\n            nextWeek: 'dddd [tuần tới lúc] LT',\n            lastDay: '[Hôm qua lúc] LT',\n            lastWeek: 'dddd [tuần rồi lúc] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s tới',\n            past : '%s trước',\n            s : 'vài giây',\n            m : 'một phút',\n            mm : '%d phút',\n            h : 'một giờ',\n            hh : '%d giờ',\n            d : 'một ngày',\n            dd : '%d ngày',\n            M : 'một tháng',\n            MM : '%d tháng',\n            y : 'một năm',\n            yy : '%d năm'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return vi;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/vi.js\n ** module id = 657\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : chinese (zh-cn)\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var zh_cn = moment.defineLocale('zh-cn', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah点mm分',\n            LTS : 'Ah点m分s秒',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日Ah点mm分',\n            LLLL : 'YYYY年MMMD日ddddAh点mm分',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日Ah点mm分',\n            llll : 'YYYY年MMMD日ddddAh点mm分'\n        },\n        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '凌晨' || meridiem === '早上' ||\n                    meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            } else {\n                // '中午'\n                return hour >= 11 ? hour : hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 600) {\n                return '凌晨';\n            } else if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : function () {\n                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';\n            },\n            nextDay : function () {\n                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';\n            },\n            lastDay : function () {\n                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';\n            },\n            nextWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = moment().startOf('week');\n                prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            lastWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = moment().startOf('week');\n                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            sameElse : 'LL'\n        },\n        ordinalParse: /\\d{1,2}(日|月|周)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s内',\n            past : '%s前',\n            s : '几秒',\n            m : '1 分钟',\n            mm : '%d 分钟',\n            h : '1 小时',\n            hh : '%d 小时',\n            d : '1 天',\n            dd : '%d 天',\n            M : '1 个月',\n            MM : '%d 个月',\n            y : '1 年',\n            yy : '%d 年'\n        },\n        week : {\n            // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return zh_cn;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/zh-cn.js\n ** module id = 658\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : traditional chinese (zh-tw)\n//! author : Ben : https://github.com/ben-lin\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var zh_tw = moment.defineLocale('zh-tw', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah點mm分',\n            LTS : 'Ah點m分s秒',\n            L : 'YYYY年MMMD日',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日Ah點mm分',\n            LLLL : 'YYYY年MMMD日ddddAh點mm分',\n            l : 'YYYY年MMMD日',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日Ah點mm分',\n            llll : 'YYYY年MMMD日ddddAh點mm分'\n        },\n        meridiemParse: /早上|上午|中午|下午|晚上/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '早上' || meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '中午') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : '[今天]LT',\n            nextDay : '[明天]LT',\n            nextWeek : '[下]ddddLT',\n            lastDay : '[昨天]LT',\n            lastWeek : '[上]ddddLT',\n            sameElse : 'L'\n        },\n        ordinalParse: /\\d{1,2}(日|月|週)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s內',\n            past : '%s前',\n            s : '幾秒',\n            m : '一分鐘',\n            mm : '%d分鐘',\n            h : '一小時',\n            hh : '%d小時',\n            d : '一天',\n            dd : '%d天',\n            M : '一個月',\n            MM : '%d個月',\n            y : '一年',\n            yy : '%d年'\n        }\n    });\n\n    return zh_tw;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/zh-tw.js\n ** module id = 659\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport alt from '../alt'\nimport guid from '../libraries/guid'\nimport numeral from 'numeral'\nimport moment from 'moment'\nimport utils from '../libraries/utils'\nimport CatalogPackageManagerSource from '../sources/CatalogPackageManagerSource'\nimport CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'\nimport CatalogDataSource from '../sources/CatalogDataSource'\n\nimport imgDownload from '../images/download158.svg'\nimport imgOnboard from '../images/upload109.svg'\nimport imgUpdate from '../images/file91.svg'\n\nconst defaults = {\n\tdownloadPackage: {\n\t\tid: '',\n\t\tname: '',\n\t\ticon: imgDownload,\n\t\tcatalogItems: [],\n\t\ttransactionId: '',\n\t\tprogress: 0,\n\t\tmessage: 'Requesting catalog package export...',\n\t\tpending: false,\n\t\tsuccess: false,\n\t\terror: false,\n\t\turl: '',\n\t\turlValidUntil: ''\n\t},\n\tcheckStatusDelayInSeconds: 2,\n\tdownloadUrlTimeToLiveInMinutes: 5\n};\n\nconst exception = function ignoreException() {};\n\nconst packagePropertyNames = Object.keys(defaults.downloadPackage);\n\nfunction getCatalogPackageManagerServerOrigin() {\n\treturn utils.getSearchParams(window.location).upload_server + ':4567';\n}\n\nfunction delayStatusCheck(statusCheckFunction, catalogPackage) {\n\tif (!catalogPackage.checkStatusTimeoutId) {\n\t\tconst delayCallback = function () {\n\t\t\tdelete catalogPackage.checkStatusTimeoutId;\n\t\t\tstatusCheckFunction(catalogPackage).catch(exception);\n\t\t};\n\t\tcatalogPackage.checkStatusTimeoutId = _.delay(delayCallback, defaults.checkStatusDelayInSeconds * 1000);\n\t}\n}\n\nclass CatalogPackageManagerStore {\n\n\tconstructor() {\n\n\t\tthis.packages = [];\n\n\t\tthis.registerAsync(CatalogDataSource);\n\t\tthis.registerAsync(CatalogPackageManagerSource);\n\t\tthis.bindAction(CatalogPackageManagerActions.REMOVE_CATALOG_PACKAGE, this.removeCatalogPackage);\n\t\tthis.bindAction(CatalogPackageManagerActions.DOWNLOAD_CATALOG_PACKAGE, this.downloadCatalogPackage);\n\t\tthis.bindAction(CatalogPackageManagerActions.DOWNLOAD_CATALOG_PACKAGE_STATUS_UPDATED, this.onDownloadCatalogPackageStatusUpdated);\n\t\tthis.bindAction(CatalogPackageManagerActions.DOWNLOAD_CATALOG_PACKAGE_ERROR, this.onDownloadCatalogPackageError);\n\t\tthis.bindAction(CatalogPackageManagerActions.UPLOAD_CATALOG_PACKAGE, this.uploadCatalogPackage);\n\t\tthis.bindAction(CatalogPackageManagerActions.UPLOAD_CATALOG_PACKAGE_STATUS_UPDATED, this.onUploadCatalogPackageStatusUpdated);\n\t\tthis.bindAction(CatalogPackageManagerActions.UPLOAD_CATALOG_PACKAGE_ERROR, this.onUploadCatalogPackageError);\n\n\t}\n\n\taddPackage(catalogPackage) {\n\t\tconst packages = [catalogPackage].concat(this.packages);\n\t\tthis.setState({packages: packages});\n\t}\n\n\tupdatePackage(catalogPackage) {\n\t\tconst packages = this.packages.map(d => {\n\t\t\tif (d.id === catalogPackage.id) {\n\t\t\t\treturn Object.assign({}, d, catalogPackage);\n\t\t\t}\n\t\t\treturn d;\n\t\t});\n\t\tthis.setState({packages: packages});\n\t}\n\n\tremoveCatalogPackage(catalogPackage) {\n\t\tconst packages = this.packages.filter(d => d.id !== catalogPackage.id);\n\t\tthis.setState({packages: packages});\n\t}\n\n\tuploadCatalogPackage(file) {\n\t\tfile.id = file.id || guid();\n\t\tconst catalogPackage = _.pick(file, packagePropertyNames);\n\t\tcatalogPackage.icon = file.riftAction === 'onboard' ? imgOnboard : imgUpdate;\n\t\tcatalogPackage.type = 'upload';\n\t\tthis.addPackage(catalogPackage);\n\t\t// note DropZone.js handles the async upload so we don't have to invoke any async action creators\n\t}\n\n\tonUploadCatalogPackageStatusUpdated(response) {\n\t\tconst upload = updateStatusInfo(response);\n\t\tthis.updatePackage(upload);\n\t\t// if pending with no transaction id - do nothing\n\t\t// bc DropZone.js will notify upload progress\n\t\tif (upload.pending && upload.transactionId) {\n\t\t\tdelayStatusCheck(this.getInstance().requestCatalogPackageUploadStatus, upload);\n\t\t} else if (upload.success) {\n\t\t\tthis.getInstance().loadCatalogs();\n\t\t}\n\t}\n\n\tonUploadCatalogPackageError(response) {\n\t\tconsole.warn('onUploadCatalogPackageError', response);\n\t\tconst catalogPackage = updateStatusInfo(response);\n\t\tthis.updatePackage(catalogPackage);\n\t}\n\n\tdownloadCatalogPackage(catalogItems = []) {\n\t\tif (catalogItems.length) {\n\t\t\tconst catalogPackage = Object.assign({}, defaults.downloadPackage, {id: guid()});\n\t\t\tcatalogPackage.name = catalogItems[0].name;\n\t\t\tcatalogPackage.type = 'download';\n\t\t\tif (catalogItems.length > 1) {\n\t\t\t\tcatalogPackage.name += ' (' + catalogItems.length + ' items)';\n\t\t\t}\n\t\t\tcatalogPackage.ids = catalogItems.map(d => d.id).sort().toString();\n\t\t\tcatalogPackage.catalogItems = catalogItems;\n\t\t\tthis.addPackage(catalogPackage);\n\t\t\tthis.getInstance().requestCatalogPackageDownload(catalogPackage).catch(exception);\n\t\t}\n\t}\n\n\tonDownloadCatalogPackageStatusUpdated(response) {\n\t\tconst download = updateStatusInfo(response);\n\t\tthis.updatePackage(download);\n\t\tif (download.pending) {\n\t\t\tdelayStatusCheck(this.getInstance().requestCatalogPackageDownloadStatus, download);\n\t\t}\n\t}\n\n\tonDownloadCatalogPackageError(response) {\n\t\tconsole.warn('onDownloadCatalogPackageError', response);\n\t\tconst catalogPackage = updateStatusInfo(response);\n\t\tthis.updatePackage(catalogPackage);\n\t}\n\n}\n\nfunction calculateUploadProgressMessage(size = 0, progress = 0, bytesSent = 0) {\n\tconst amount = parseFloat(progress) || 0;\n\tconst loaded = amount === 100 ? size : size * amount / 100;\n\tlet progressText;\n\tif (amount === 100) {\n\t\tprogressText = numeral(loaded).format('0.0b') + ' loaded ';\n\t} else if (typeof amount === 'number' && amount != 0) {\n\t\tprogressText = numeral(bytesSent).format('0.0b') + ' out of ' + numeral(size).format('0.0b');\n\t} else {\n\t\tprogressText = progress;\n\t}\n\treturn progressText;\n}\n\nfunction updateStatusInfo(response) {\n\t// returns the catalogPackage object with the status fields updated based on the server response\n\tconst statusInfo = {\n\t\tpending: false,\n\t\tsuccess: false,\n\t\terror: false\n\t};\n\tconst responseData = response.data;\n\tconst catalogPackage = response.state;\n\tswitch(responseData.status) {\n\tcase 'upload-progress':\n\t\tstatusInfo.pending = true;\n\t\tstatusInfo.progress = parseFloat(responseData.progress) || 0;\n\t\tstatusInfo.message = calculateUploadProgressMessage(catalogPackage.size, responseData.progress, responseData.bytesSent);\n\t\tbreak;\n\tcase 'upload-success':\n\t\tstatusInfo.pending = true;\n\t\tstatusInfo.progress = 100;\n\t\tstatusInfo.message = 'Upload completed.';\n\t\tstatusInfo.transactionId = responseData.transaction_id;\n\t\tbreak;\n\tcase 'upload-error':\n\t\tstatusInfo.error = true;\n\t\tstatusInfo.message = responseData.message;\n\t\tbreak;\n\tcase 'download-requested':\n\t\tstatusInfo.pending = true;\n\t\tstatusInfo.progress = 25;\n\t\tstatusInfo.transactionId = responseData.transaction_id;\n\t\tbreak;\n\tcase 'pending':\n\t\tstatusInfo.pending = true;\n\t\tstatusInfo.progress = 50;\n\t\tstatusInfo.message = responseData.events[responseData.events.length - 1].text;\n\t\tbreak;\n\tcase 'success':\n\t\tstatusInfo.success = true;\n\t\tstatusInfo.progress = 100;\n\t\tstatusInfo.message = responseData.events[responseData.events.length - 1].text;\n\t\tif (catalogPackage.type === 'download') {\n\t\t\tstatusInfo.urlValidUntil = moment().add(defaults.downloadUrlTimeToLiveInMinutes, 'minutes').toISOString();\n\t\t\tstatusInfo.url = getCatalogPackageManagerServerOrigin() + '/api/export/' + catalogPackage.transactionId + '.tar.gz';\n\t\t}\n\t\tbreak;\n\tcase 'failure':\n\t\tstatusInfo.error = true;\n\t\tstatusInfo.message = responseData.errors[0].value;\n\t\tbreak;\n\tdefault:\n\t\tthrow new ReferenceError('a status of \"request\", \"success\", \"failure\", \"pending\", \"upload-completed\", \"upload-error\", \"download-requested\", \"upload-progress\", \"upload-action\" is required');\n\t}\n\treturn Object.assign({}, catalogPackage, statusInfo);\n}\n\nexport default alt.createStore(CatalogPackageManagerStore, 'CatalogPackageManagerStore');\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/stores/CatalogPackageManagerStore.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport $ from 'jquery'\nimport alt from '../alt'\nimport utils from '../libraries/utils'\nimport CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'\n\nfunction getApiServerOrigin() {\n\treturn utils.getSearchParams(window.location).upload_server + ':4567';\n}\n\nfunction ajaxRequest(path, catalogPackage, resolve, reject, method = 'GET') {\n\t$.ajax({\n\t\turl: getApiServerOrigin() + path,\n\t\ttype: method,\n\t\tbeforeSend: utils.addAuthorizationStub,\n\t\tdataType: 'json',\n\t\tsuccess: function(data) {\n\t\t\tif (typeof data == 'string') {\n\t\t\t\tdata = JSON.parse(data);\n\t\t\t}\n\t\t\tresolve({\n\t\t\t\tdata: data,\n\t\t\t\tstate: catalogPackage\n\t\t\t});\n\t\t},\n\t\terror: function(error) {\n\t\t\tif (typeof error == 'string') {\n\t\t\t\terror = JSON.parse(error);\n\t\t\t}\n\t\t\treject({\n\t\t\t\tdata: error,\n\t\t\t\tstate: catalogPackage\n\t\t\t});\n\t\t}\n\t});\n}\n\nconst CatalogPackageManagerSource = {\n\n\trequestCatalogPackageDownload: function () {\n\t\treturn {\n\t\t\tremote: function (state, download) {\n\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t// the server does not add a status in the payload\n\t\t\t\t\t// so we add one so that the success handler will\n\t\t\t\t\t// be able to follow the flow of this download\n\t\t\t\t\tconst setStatusBeforeResolve = (response = {}) => {\n\t\t\t\t\t\tresponse.data.status = 'download-requested';\n\t\t\t\t\t\tresolve(response);\n\t\t\t\t\t};\n\t\t\t\t\tconst path = '/api/export?ids=' + download.ids;\n\t\t\t\t\tajaxRequest(path, download, setStatusBeforeResolve, reject);\n\t\t\t\t});\n\t\t\t},\n\t\t\tsuccess: CatalogPackageManagerActions.downloadCatalogPackageStatusUpdated,\n\t\t\terror: CatalogPackageManagerActions.downloadCatalogPackageError\n\t\t};\n\t},\n\n\trequestCatalogPackageDownloadStatus: function() {\n\t\treturn {\n\t\t\tremote: function(state, download) {\n\t\t\t\tconst transactionId = download.transactionId;\n\t\t\t\treturn new Promise(function(resolve, reject) {\n\t\t\t\t\tconst path = '/api/export/' + transactionId + '/state';\n\t\t\t\t\tajaxRequest(path, download, resolve, reject);\n\t\t\t\t});\n\t\t\t},\n\t\t\tsuccess: CatalogPackageManagerActions.downloadCatalogPackageStatusUpdated,\n\t\t\terror: CatalogPackageManagerActions.downloadCatalogPackageError\n\t\t}\n\t},\n\n\trequestCatalogPackageUploadStatus: function () {\n\t\treturn {\n\t\t\tremote: function (state, upload) {\n\t\t\t\tconst transactionId = upload.transactionId;\n\t\t\t\treturn new Promise(function (resolve, reject) {\n\t\t\t\t\tconst action = upload.riftAction === 'onboard' ? 'upload' : 'update';\n\t\t\t\t\tconst path = '/api/' + action + '/' + transactionId + '/state';\n\t\t\t\t\tajaxRequest(path, upload, resolve, reject);\n\t\t\t\t});\n\t\t\t},\n\t\t\tsuccess: CatalogPackageManagerActions.uploadCatalogPackageStatusUpdated,\n\t\t\terror: CatalogPackageManagerActions.uploadCatalogPackageError\n\t\t};\n\t}\n\n};\n\nexport default CatalogPackageManagerSource;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/sources/CatalogPackageManagerSource.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPackageManager.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPackageManager.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPackageManager.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogPackageManager.scss\n ** module id = 662\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogPackageManager {\\n  overflow: hidden;\\n}\\n\\n.CatalogPackageManager > .items {\\n  margin: 4px;\\n  border: 1px solid transparent;\\n  padding: 4px;\\n  white-space: nowrap;\\n  overflow: auto;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  -ms-overflow-style: none;\\n  display: flex;\\n  flex-wrap: wrap;\\n  align-items: flex-start;\\n  align-content: flex-start;\\n  justify-content: flex-start;\\n}\\n\\n.CatalogPackageManager > .items > .item {\\n  overflow: hidden;\\n  position: relative;\\n  font-size: 12px;\\n  font-weight: 200;\\n  font-style: normal;\\n  height: 40px;\\n  width: 100%;\\n  max-width: 400px;\\n  margin: 5px;\\n  border-radius: 5px;\\n  padding: 4px 8px;\\n  color: #3a3a3a;\\n  background-color: #ffffff;\\n}\\n\\n.CatalogPackageManager > .items > .item.-error {\\n  background-color: rgba(139, 0, 0, 0.1);\\n}\\n\\n.CatalogPackageManager > .items > .item.-success {\\n  background-color: rgba(0, 139, 0, 0.1);\\n}\\n\\n.CatalogPackageManager > .items > .item h2 {\\n  font-size: 12px;\\n  font-weight: 400;\\n  padding-top: 0;\\n  padding-bottom: 0;\\n  padding-left: 30px;\\n}\\n\\n.CatalogPackageManager > .items > .item img {\\n  width: 25px;\\n  height: 25px;\\n  position: absolute;\\n  top: 4px;\\n  left: 5px;\\n}\\n\\n.CatalogPackageManager > .items > .item .message {\\n  padding-left: 30px;\\n}\\n\\n.CatalogPackageManager > .items > .item span {\\n  display: inline-block;\\n}\\n\\n.CatalogPackageManager > .items > .item em {\\n  display: none;\\n  color: #3C0808;\\n  font-weight: 100;\\n  margin-right: 4px;\\n}\\n\\n.CatalogPackageManager > .items > .item var {\\n  font-family: monospace, serif;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-progress {\\n  display: block;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-progress-indicator {\\n  position: absolute;\\n  left: 30px;\\n  right: 3px;\\n  bottom: 0;\\n  margin: 3px;\\n  border: 1px solid rgba(81, 102, 147, 0.87);\\n  border-radius: 3px;\\n  padding: 0;\\n  height: 3px;\\n  background-color: white;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-progress-indicator-value {\\n  height: 1px;\\n  border-radius: 3px;\\n  background-color: #64F106;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-download-link {\\n  display: inline;\\n  margin-left: 24px;\\n  padding: 3px;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-preview {\\n  display: block;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-preview em {\\n  display: none;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-error {\\n  display: block;\\n  position: absolute;\\n  z-index: 99;\\n  background-color: black;\\n  top: 18px;\\n  left: 30px;\\n  right: 10px;\\n  border-radius: 3px;\\n  padding: 1px 4px !important;\\n}\\n\\n.CatalogPackageManager > .items > .item .file-success {\\n  display: block;\\n  position: absolute;\\n  z-index: 99;\\n  background-color: black;\\n  top: 18px;\\n  left: 30px;\\n  right: 10px;\\n  border-radius: 3px;\\n  padding: 1px 4px !important;\\n}\\n\\n.CatalogPackageManager > .items > .item .item-actions {\\n  background-color: rgba(255, 255, 255, 0.5);\\n  display: none;\\n  position: absolute;\\n  top: 0;\\n  right: 0;\\n  bottom: 0;\\n  padding: 4px;\\n  text-align: right;\\n}\\n\\n.CatalogPackageManager > .items > .item .item-actions .Button:hover {\\n  background-color: transparent;\\n  border-color: transparent;\\n}\\n\\n.CatalogPackageManager > .items > .item:hover .item-actions {\\n  display: block;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogPackageManager.scss\n ** module id = 663\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"d7be54ed5a2c1e585d0e6dbbe6f9515a.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/video167.svg\n ** module id = 664\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"0e4ad838e307e9be620594b675fcb345.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/zipped2.svg\n ** module id = 665\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"b1f076ba136f3a89ffd6a75b3b4c4011.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/file87.svg\n ** module id = 666\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"25be2988aedefcf0940009c1b91846c0.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/cross95.svg\n ** module id = 667\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport alt from '../alt'\nimport CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'\n\nclass CatalogPanelStore {\n\n\tconstructor() {\n\t\tthis.isTrayOpen = 0;\n\t\tthis.bindAction(CatalogPanelTrayActions.OPEN, this.openTray);\n\t\tthis.bindAction(CatalogPanelTrayActions.CLOSE, this.closeTray);\n\t\tthis.bindAction(CatalogPanelTrayActions.TOGGLE_OPEN_CLOSE, this.toggleTrayOpenClose);\n\t}\n\n\topenTray() {\n\t\t// note incrementing integer will force a state change needed to redraw tray drop zones\n\t\tthis.setState({isTrayOpen: this.isTrayOpen + 1});\n\t}\n\n\tcloseTray() {\n\t\tthis.setState({isTrayOpen: 0});\n\t}\n\n\ttoggleTrayOpenClose() {\n\t\tthis.setState({isTrayOpen: this.isTrayOpen === 0 ? 1 : 0});\n\t}\n\n}\n\nexport default alt.createStore(CatalogPanelStore, 'CatalogPanelStore');\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/stores/CatalogPanelStore.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport '../../node_modules/loaders.css/src/animations/line-scale-pulse-out-rapid.scss';\nimport '../styles/LoadingIndicator.scss';\n\nexport default class Loader extends React.Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t}\n\trender() {\n\t\tlet loader = '';\n\t\tvar style = {\n\t\t\theight: this.props.size + 'rem',\n\t\t\twidth: this.props.size * 0.15 + 'rem',\n\t\t\tbackgroundColor: this.props.color || 'white'\n\t\t}\n\t\tif (this.props.show) {\n\t\t\tloader = (\n\t\t\t\t<div className = {\"line-scale-pulse-out-rapid\"}>\n\t\t\t\t\t<div style={style} ></div>\n\t\t\t\t\t<div style={style} ></div>\n\t\t\t\t\t<div style={style} ></div>\n\t\t\t\t\t<div style={style} ></div>\n\t\t\t\t\t<div style={style} ></div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\t\treturn loader;\n\t}\n}\nLoader.defaultProps = {\n\tshow: true,\n\tsize: '5'\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/LoadingIndicator.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../../css-loader/index.js!./../../../sass-loader/index.js?outputStyle=expanded!./line-scale-pulse-out-rapid.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../../style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../css-loader/index.js!./../../../sass-loader/index.js?outputStyle=expanded!./line-scale-pulse-out-rapid.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../../css-loader/index.js!./../../../sass-loader/index.js?outputStyle=expanded!./line-scale-pulse-out-rapid.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/loaders.css/src/animations/line-scale-pulse-out-rapid.scss\n ** module id = 670\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../../css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@keyframes line-scale-pulse-out-rapid {\\n  0% {\\n    transform: scaley(1);\\n  }\\n  80% {\\n    transform: scaley(0.3);\\n  }\\n  90% {\\n    transform: scaley(1);\\n  }\\n}\\n\\n.line-scale-pulse-out-rapid > div {\\n  background-color: #fff;\\n  width: 4px;\\n  height: 35px;\\n  border-radius: 2px;\\n  margin: 2px;\\n  animation-fill-mode: both;\\n  display: inline-block;\\n  animation: line-scale-pulse-out-rapid 0.9s -0.5s infinite cubic-bezier(0.11, 0.49, 0.38, 0.78);\\n}\\n\\n.line-scale-pulse-out-rapid > div:nth-child(2), .line-scale-pulse-out-rapid > div:nth-child(4) {\\n  animation-delay: -0.25s !important;\\n}\\n\\n.line-scale-pulse-out-rapid > div:nth-child(1), .line-scale-pulse-out-rapid > div:nth-child(5) {\\n  animation-delay: 0s !important;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./~/loaders.css/src/animations/line-scale-pulse-out-rapid.scss\n ** module id = 671\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./LoadingIndicator.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./LoadingIndicator.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./LoadingIndicator.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/LoadingIndicator.scss\n ** module id = 672\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.line-scale-pulse-out-rapid > div {\\n  background-color: #fff;\\n  width: 4px;\\n  height: 2rem;\\n  border-radius: 2px;\\n  margin: 2px;\\n  animation-fill-mode: both;\\n  display: inline-block;\\n  animation: line-scale-pulse-out-rapid 0.9s -0.5s infinite cubic-bezier(0.11, 0.49, 0.38, 0.78);\\n}\\n\\n.line-scale-pulse-out-rapid > div:nth-child(2), .line-scale-pulse-out-rapid > div:nth-child(4) {\\n  animation-delay: -0.25s !important;\\n}\\n\\n.line-scale-pulse-out-rapid > div:nth-child(1), .line-scale-pulse-out-rapid > div:nth-child(5) {\\n  animation-delay: 0s !important;\\n}\\n\\n.loader-animation-enter, .loader-animation-appear {\\n  opacity: 0.01;\\n}\\n\\n.loader-animation-enter.loader-animation-enter-active, .loader-animation-appear.loader-animation-appear-active {\\n  opacity: 1.0;\\n  transition: opacity 300ms ease-in;\\n}\\n\\n.loader-animation-leave {\\n  visibility: hidden;\\n  height: 0px;\\n  width: 0px;\\n  opacity: 1.0;\\n}\\n\\n.loader-animation-leave.loader-animation-leave-active {\\n  opacity: 0;\\n  transition: opacity 300ms ease-in;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/LoadingIndicator.scss\n ** module id = 673\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanel.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanel.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogPanel.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogPanel.scss\n ** module id = 674\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@charset \\\"UTF-8\\\";\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Thin-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-ThinItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Medium-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-MediumItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Black-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BlackItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\nhtml, body {\\n  background: #f1f1f1;\\n  cursor: auto;\\n  font-family: Roboto, Helvetica, Arial, sans-serif;\\n  overflow: hidden;\\n}\\n\\n::-webkit-scrollbar {\\n  display: none;\\n}\\n\\nhtml {\\n  -webkit-box-sizing: border-box;\\n  -moz-box-sizing: border-box;\\n  box-sizing: border-box;\\n}\\n\\n* {\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n  border-collapse: collapse;\\n}\\n\\n*, *:before, *:after {\\n  -webkit-box-sizing: inherit;\\n  -moz-box-sizing: inherit;\\n  box-sizing: inherit;\\n}\\n\\nh1 {\\n  margin: 0;\\n  padding: 3px 6px;\\n  color: #323232;\\n  font-size: 0.75em;\\n  font-weight: normal;\\n  text-align: center;\\n  font-variant-caps: all-small-caps;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n}\\n\\nbutton,\\ninput[type=\\\"image\\\"] {\\n  /*font-variant: small-caps;\\n\\ttext-transform: lowercase;\\n\\ttext-align: center;\\n\\tmargin: 4px 0;\\n\\tborder-radius: 0;\\n\\tborder-collapse: collapse;\\n\\tpadding: 2px 24px;\\n\\toutline: none;\\n\\tbackground-color: transparent;*/\\n  box-shadow: 2px 2px rgba(0, 0, 0, 0.15);\\n  color: #000000;\\n  display: inline-block;\\n  font-size: 12px;\\n  padding: 8px 34px;\\n  text-decoration: none;\\n  text-transform: uppercase;\\n}\\n\\nbutton:hover,\\ninput[type=\\\"image\\\"]:hover {\\n  background-color: #7E9BC1;\\n  color: #ffffff;\\n}\\n\\nbutton:active,\\nbutton:visited,\\ninput[type=\\\"image\\\"]:active, input[type=\\\"image\\\"]:visited {\\n  background-color: #4C5E74;\\n  color: #ffffff;\\n}\\n\\nbutton.-selected,\\ninput[type=\\\"image\\\"].-selected {\\n  background-color: #9fc4f4;\\n}\\n\\ninput[type=\\\"image\\\"] {\\n  width: 28px;\\n  height: 28px;\\n  margin-right: 12px;\\n  border: 0;\\n  border-radius: 4px;\\n  padding: 4px;\\n}\\n\\n.btn-group {\\n  white-space: nowrap;\\n}\\n\\n.btn-group button {\\n  border-right: 1px solid rgba(169, 169, 169, 0.5);\\n}\\n\\n.btn-group button:first-of-type {\\n  border-top-left-radius: 2px;\\n  border-bottom-left-radius: 2px;\\n}\\n\\n.btn-group button:last-of-type {\\n  border-right: none;\\n  border-top-right-radius: 2px;\\n  border-bottom-right-radius: 2px;\\n}\\n\\n.panel {\\n  overflow: hidden;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  background-color: #e5e5e5;\\n}\\n\\n.panel > div {\\n  min-width: 200px;\\n}\\n\\n.panel-header {\\n  /*position: absolute;\\n\\ttop: 0;\\n\\tleft: 0;\\n\\tright: 0;\\n\\theight: 50px;\\n\\tpadding: 8px;\\n\\tbackground-color: $panel-bg-color-contrast;\\n\\tborder-bottom: 1px solid $panel-border-color-light;\\n\\twhite-space: nowrap;*/\\n}\\n\\n.panel-header h1 {\\n  padding: 16px;\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.panel-body, .CatalogPanel .CatalogPanelBody {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  top: 111px;\\n  bottom: 0px;\\n  left: 0;\\n  right: 0;\\n}\\n\\n.panel-footer {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 40px;\\n  padding: 0 12px;\\n  background-color: #cbd1d1;\\n  border-top: 1px solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n}\\n\\n.welcome-message {\\n  margin: 20px;\\n  color: #06173c;\\n  font-size: x-large;\\n  font-weight: 200;\\n}\\n\\n.welcome-message .Button {\\n  display: inline-block;\\n}\\n\\n/* react-tooltip overrides */\\n.__react_component_tooltip {\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !important;\\n}\\n\\n/* simple css-only drop-down menu */\\n.menu {\\n  display: inline-flex;\\n  position: relative;\\n  z-index: 2;\\n}\\n\\n.menu > .Button:after {\\n  content: \\\"\\\\2C7\\\";\\n  position: absolute;\\n  right: 4px;\\n  bottom: -13px;\\n  font-size: 20px;\\n}\\n\\n.menu .sub-menu {\\n  display: none;\\n  position: absolute;\\n  top: 36px;\\n  left: -4px;\\n  padding: 4px;\\n  background-color: #f1f1f1;\\n  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\\n  border-radius: 3px;\\n}\\n\\n.menu .sub-menu .Button {\\n  display: block;\\n  text-align: left;\\n}\\n\\n.menu .sub-menu:hover {\\n  display: block;\\n}\\n\\n.menu > .Button:hover .sub-menu {\\n  display: block;\\n}\\n\\n.menu:hover .sub-menu {\\n  display: block;\\n}\\n\\n.descriptor text.badge {\\n  font-weight: 100;\\n  font-size: 12px;\\n  text-anchor: middle;\\n  fill: white;\\n  /* font color */\\n  stroke: white !important;\\n  /* font color */\\n}\\n\\ninput:focus {\\n  color: white;\\n  background: #000 !important;\\n}\\n\\n.hint {\\n  margin: 5px;\\n}\\n\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogPanel {\\n  border-right: 1px solid rgba(143, 143, 143, 0.5);\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n  bottom: 0;\\n  width: 300px;\\n  min-width: 6px;\\n  overflow: hidden;\\n  z-index: 3;\\n}\\n\\n.CatalogPanel.-is-tray-open .CatalogPanelBody {\\n  bottom: 275px;\\n  /*height of the CatalogPanelTray*/\\n}\\n\\n.CatalogPanel .CatalogPanelBody {\\n  min-width: 300px;\\n}\\n\\n.CatalogPanel .CatalogPanelBody .LoaderWrapper {\\n  display: flex;\\n  justify-content: center;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogPanel.scss\n ** module id = 675\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport _ from 'lodash'\nimport React from 'react';\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport messages from './messages'\nimport serializers from '../libraries/model/DescriptorConfDSerializer'\nimport JSONViewer from './JSONViewer'\nimport PopupWindow from './PopupWindow'\nimport CatalogItemDetailsEditor from './CatalogItemDetailsEditor'\nimport SelectionManager from '../libraries/SelectionManager'\n\nimport '../styles/DetailsPanel.scss'\n\nconst DetailsPanel = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {};\n\t},\n\tgetDefaultProps() {\n\t\treturn {\n\t\t\tcontainers: [],\n\t\t\tshowJSONViewer: false\n\t\t};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\trender() {\n\t\tlet json = '{}';\n\t\tlet bodyComponent =  messages.detailsWelcome();\n\t\tconst selected = this.props.containers.filter(d => SelectionManager.isSelected(d));\n\t\tconst selectedContainer = selected[0];\n\t\tif (selectedContainer) {\n\t\t\tbodyComponent = <CatalogItemDetailsEditor container={selectedContainer} width={this.props.layout.right} />;\n\t\t\tconst edit = _.cloneDeep(selectedContainer.model);\n\t\t\tjson = serializers.serialize(edit) || edit;\n\t\t}\n\t\tconst jsonViewerTitle = selectedContainer ? selectedContainer.model.name : 'nothing selected';\n\t\tconst hasNoCatalogs = this.props.hasNoCatalogs;\n\t\treturn (\n\t\t\t<div className=\"DetailsPanel\" data-resizable=\"left\" style={{width: this.props.layout.right}}>\n\t\t\t\t<div className=\"DetailsPanelBody\">\n\t\t\t\t\t{hasNoCatalogs ? null : bodyComponent}\n\t\t\t\t</div>\n\t\t\t\t<PopupWindow show={this.props.showJSONViewer} title={jsonViewerTitle}><JSONViewer json={json}/></PopupWindow>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default DetailsPanel;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/DetailsPanel.js\n **/","/**\n * Created by onvelocity on 2/2/16.\n */\n\nimport React from 'react'\nimport Prism from 'prismjs'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\n\nimport '../styles/JSONViewer.scss'\n\nconst cssString = `\n\t\t\t\t\t/*\n\t\t\t\t\t copied from node_modules/prismjs/themes/prismjs.css\n\t\t\t\t\t */\n\t\t\t\t\t:not(pre) > code[class*=\"language-\"],\n\t\t\t\t\tpre[class*=\"language-\"] {\n\t\t\t\t\tfont-size: 12px;\n\t\t\t\t\tborder: 1px solid rgba(220, 220, 220, 0.5);\n\t\t\t\t\tborder-radius: 4px;\n\t\t\t\t\tbackground-color: rgba(255, 255, 255, .25);\n\t\t\t\t}\n\n\t\t\t\t\t/* Inline code */\n\t\t\t\t\t:not(pre) > code[class*=\"language-\"] {\n\t\t\t\t\tpadding: .1em;\n\t\t\t\t}\n\n\t\t\t\t\t.token.comment,\n\t\t\t\t\t.token.prolog,\n\t\t\t\t\t.token.doctype,\n\t\t\t\t\t.token.cdata {\n\t\t\t\t\tcolor: slategray;\n\t\t\t\t}\n\n\t\t\t\t\t.token.punctuation {\n\t\t\t\t\tcolor: #333;\n\t\t\t\t}\n\n\t\t\t\t\t.namespace {\n\t\t\t\t\topacity: .7;\n\t\t\t\t}\n\n\t\t\t\t\t.token.property,\n\t\t\t\t\t.token.tag,\n\t\t\t\t\t.token.boolean,\n\t\t\t\t\t.token.number,\n\t\t\t\t\t.token.constant,\n\t\t\t\t\t.token.symbol,\n\t\t\t\t\t.token.deleted {\n\t\t\t\t\tcolor: #905;\n\t\t\t\t}\n\n\t\t\t\t\t.token.selector,\n\t\t\t\t\t.token.attr-name,\n\t\t\t\t\t.token.string,\n\t\t\t\t\t.token.char,\n\t\t\t\t\t.token.builtin,\n\t\t\t\t\t.token.inserted {\n\t\t\t\t\tcolor: #df5000;\n\t\t\t\t}\n\n\t\t\t\t\t.token.operator,\n\t\t\t\t\t.token.entity,\n\t\t\t\t\t.token.url,\n\t\t\t\t\t.language-css .token.string,\n\t\t\t\t\t.style .token.string {\n\t\t\t\t\tcolor: #a67f59;\n\t\t\t\t\tbackground: hsla(0, 0%, 100%, .5);\n\t\t\t\t}\n\n\t\t\t\t\t.token.atrule,\n\t\t\t\t\t.token.attr-value,\n\t\t\t\t\t.token.keyword {\n\t\t\t\t\tcolor: #07a;\n\t\t\t\t}\n\n\t\t\t\t\t.token.function {\n\t\t\t\t\tcolor: #DD4A68;\n\t\t\t\t}\n\n\t\t\t\t\t.token.regex,\n\t\t\t\t\t.token.important,\n\t\t\t\t\t.token.variable {\n\t\t\t\t\tcolor: #e90;\n\t\t\t\t}\n\n\t\t\t\t\t.token.important,\n\t\t\t\t\t.token.bold {\n\t\t\t\t\tfont-weight: bold;\n\t\t\t\t}\n\t\t\t\t\t.token.italic {\n\t\t\t\t\tfont-style: italic;\n\t\t\t\t}\n\n\t\t\t\t\t.token.entity {\n\t\t\t\t\tcursor: help;\n\t\t\t\t}\n`;\n\nconst JSONViewer = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState: function () {\n\t\treturn {};\n\t},\n\tgetDefaultProps: function () {\n\t\treturn {};\n\t},\n\tcomponentWillMount: function () {\n\t},\n\tcomponentDidMount: function () {\n\t},\n\tcomponentDidUpdate: function () {\n\t},\n\tcomponentWillUnmount: function () {\n\t},\n\trender() {\n\t\tconst text = JSON.stringify(this.props.json, undefined, 12).replace(/    /g, ' ');\n\t\tconst result = Prism.highlight(text, Prism.languages.javascript, 'javascript');\n\t\treturn (\n\t\t\t<div className=\"JSONViewer\">\n\t\t\t\t<style dangerouslySetInnerHTML={{__html: cssString}}></style>\n\t\t\t\t<label className=\"descriptor\">\n\t\t\t\t\t<pre className=\"language-js\">\n\t\t\t\t\t\t<code dangerouslySetInnerHTML={{__html: result}} />\n\t\t\t\t\t</pre>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default JSONViewer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/JSONViewer.js\n **/","\n/* **********************************************\n     Begin prism-core.js\n********************************************** */\n\nvar _self = (typeof window !== 'undefined')\n\t? window   // if in browser\n\t: (\n\t\t(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)\n\t\t? self // if in worker\n\t\t: {}   // if in node js\n\t);\n\n/**\n * Prism: Lightweight, robust, elegant syntax highlighting\n * MIT license http://www.opensource.org/licenses/mit-license.php/\n * @author Lea Verou http://lea.verou.me\n */\n\nvar Prism = (function(){\n\n// Private helper vars\nvar lang = /\\blang(?:uage)?-(?!\\*)(\\w+)\\b/i;\n\nvar _ = _self.Prism = {\n\tutil: {\n\t\tencode: function (tokens) {\n\t\t\tif (tokens instanceof Token) {\n\t\t\t\treturn new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);\n\t\t\t} else if (_.util.type(tokens) === 'Array') {\n\t\t\t\treturn tokens.map(_.util.encode);\n\t\t\t} else {\n\t\t\t\treturn tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\\u00a0/g, ' ');\n\t\t\t}\n\t\t},\n\n\t\ttype: function (o) {\n\t\t\treturn Object.prototype.toString.call(o).match(/\\[object (\\w+)\\]/)[1];\n\t\t},\n\n\t\t// Deep clone a language definition (e.g. to extend it)\n\t\tclone: function (o) {\n\t\t\tvar type = _.util.type(o);\n\n\t\t\tswitch (type) {\n\t\t\t\tcase 'Object':\n\t\t\t\t\tvar clone = {};\n\n\t\t\t\t\tfor (var key in o) {\n\t\t\t\t\t\tif (o.hasOwnProperty(key)) {\n\t\t\t\t\t\t\tclone[key] = _.util.clone(o[key]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn clone;\n\n\t\t\t\tcase 'Array':\n\t\t\t\t\t// Check for existence for IE8\n\t\t\t\t\treturn o.map && o.map(function(v) { return _.util.clone(v); });\n\t\t\t}\n\n\t\t\treturn o;\n\t\t}\n\t},\n\n\tlanguages: {\n\t\textend: function (id, redef) {\n\t\t\tvar lang = _.util.clone(_.languages[id]);\n\n\t\t\tfor (var key in redef) {\n\t\t\t\tlang[key] = redef[key];\n\t\t\t}\n\n\t\t\treturn lang;\n\t\t},\n\n\t\t/**\n\t\t * Insert a token before another token in a language literal\n\t\t * As this needs to recreate the object (we cannot actually insert before keys in object literals),\n\t\t * we cannot just provide an object, we need anobject and a key.\n\t\t * @param inside The key (or language id) of the parent\n\t\t * @param before The key to insert before. If not provided, the function appends instead.\n\t\t * @param insert Object with the key/value pairs to insert\n\t\t * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.\n\t\t */\n\t\tinsertBefore: function (inside, before, insert, root) {\n\t\t\troot = root || _.languages;\n\t\t\tvar grammar = root[inside];\n\t\t\t\n\t\t\tif (arguments.length == 2) {\n\t\t\t\tinsert = arguments[1];\n\t\t\t\t\n\t\t\t\tfor (var newToken in insert) {\n\t\t\t\t\tif (insert.hasOwnProperty(newToken)) {\n\t\t\t\t\t\tgrammar[newToken] = insert[newToken];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn grammar;\n\t\t\t}\n\t\t\t\n\t\t\tvar ret = {};\n\n\t\t\tfor (var token in grammar) {\n\n\t\t\t\tif (grammar.hasOwnProperty(token)) {\n\n\t\t\t\t\tif (token == before) {\n\n\t\t\t\t\t\tfor (var newToken in insert) {\n\n\t\t\t\t\t\t\tif (insert.hasOwnProperty(newToken)) {\n\t\t\t\t\t\t\t\tret[newToken] = insert[newToken];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tret[token] = grammar[token];\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// Update references in other language definitions\n\t\t\t_.languages.DFS(_.languages, function(key, value) {\n\t\t\t\tif (value === root[inside] && key != inside) {\n\t\t\t\t\tthis[key] = ret;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn root[inside] = ret;\n\t\t},\n\n\t\t// Traverse a language definition with Depth First Search\n\t\tDFS: function(o, callback, type) {\n\t\t\tfor (var i in o) {\n\t\t\t\tif (o.hasOwnProperty(i)) {\n\t\t\t\t\tcallback.call(o, i, o[i], type || i);\n\n\t\t\t\t\tif (_.util.type(o[i]) === 'Object') {\n\t\t\t\t\t\t_.languages.DFS(o[i], callback);\n\t\t\t\t\t}\n\t\t\t\t\telse if (_.util.type(o[i]) === 'Array') {\n\t\t\t\t\t\t_.languages.DFS(o[i], callback, i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tplugins: {},\n\t\n\thighlightAll: function(async, callback) {\n\t\tvar elements = document.querySelectorAll('code[class*=\"language-\"], [class*=\"language-\"] code, code[class*=\"lang-\"], [class*=\"lang-\"] code');\n\n\t\tfor (var i=0, element; element = elements[i++];) {\n\t\t\t_.highlightElement(element, async === true, callback);\n\t\t}\n\t},\n\n\thighlightElement: function(element, async, callback) {\n\t\t// Find language\n\t\tvar language, grammar, parent = element;\n\n\t\twhile (parent && !lang.test(parent.className)) {\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\tif (parent) {\n\t\t\tlanguage = (parent.className.match(lang) || [,''])[1];\n\t\t\tgrammar = _.languages[language];\n\t\t}\n\n\t\t// Set language on the element, if not present\n\t\telement.className = element.className.replace(lang, '').replace(/\\s+/g, ' ') + ' language-' + language;\n\n\t\t// Set language on the parent, for styling\n\t\tparent = element.parentNode;\n\n\t\tif (/pre/i.test(parent.nodeName)) {\n\t\t\tparent.className = parent.className.replace(lang, '').replace(/\\s+/g, ' ') + ' language-' + language;\n\t\t}\n\n\t\tvar code = element.textContent;\n\n\t\tvar env = {\n\t\t\telement: element,\n\t\t\tlanguage: language,\n\t\t\tgrammar: grammar,\n\t\t\tcode: code\n\t\t};\n\n\t\tif (!code || !grammar) {\n\t\t\t_.hooks.run('complete', env);\n\t\t\treturn;\n\t\t}\n\n\t\t_.hooks.run('before-highlight', env);\n\n\t\tif (async && _self.Worker) {\n\t\t\tvar worker = new Worker(_.filename);\n\n\t\t\tworker.onmessage = function(evt) {\n\t\t\t\tenv.highlightedCode = evt.data;\n\n\t\t\t\t_.hooks.run('before-insert', env);\n\n\t\t\t\tenv.element.innerHTML = env.highlightedCode;\n\n\t\t\t\tcallback && callback.call(env.element);\n\t\t\t\t_.hooks.run('after-highlight', env);\n\t\t\t\t_.hooks.run('complete', env);\n\t\t\t};\n\n\t\t\tworker.postMessage(JSON.stringify({\n\t\t\t\tlanguage: env.language,\n\t\t\t\tcode: env.code,\n\t\t\t\timmediateClose: true\n\t\t\t}));\n\t\t}\n\t\telse {\n\t\t\tenv.highlightedCode = _.highlight(env.code, env.grammar, env.language);\n\n\t\t\t_.hooks.run('before-insert', env);\n\n\t\t\tenv.element.innerHTML = env.highlightedCode;\n\n\t\t\tcallback && callback.call(element);\n\n\t\t\t_.hooks.run('after-highlight', env);\n\t\t\t_.hooks.run('complete', env);\n\t\t}\n\t},\n\n\thighlight: function (text, grammar, language) {\n\t\tvar tokens = _.tokenize(text, grammar);\n\t\treturn Token.stringify(_.util.encode(tokens), language);\n\t},\n\n\ttokenize: function(text, grammar, language) {\n\t\tvar Token = _.Token;\n\n\t\tvar strarr = [text];\n\n\t\tvar rest = grammar.rest;\n\n\t\tif (rest) {\n\t\t\tfor (var token in rest) {\n\t\t\t\tgrammar[token] = rest[token];\n\t\t\t}\n\n\t\t\tdelete grammar.rest;\n\t\t}\n\n\t\ttokenloop: for (var token in grammar) {\n\t\t\tif(!grammar.hasOwnProperty(token) || !grammar[token]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvar patterns = grammar[token];\n\t\t\tpatterns = (_.util.type(patterns) === \"Array\") ? patterns : [patterns];\n\n\t\t\tfor (var j = 0; j < patterns.length; ++j) {\n\t\t\t\tvar pattern = patterns[j],\n\t\t\t\t\tinside = pattern.inside,\n\t\t\t\t\tlookbehind = !!pattern.lookbehind,\n\t\t\t\t\tlookbehindLength = 0,\n\t\t\t\t\talias = pattern.alias;\n\n\t\t\t\tpattern = pattern.pattern || pattern;\n\n\t\t\t\tfor (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop\n\n\t\t\t\t\tvar str = strarr[i];\n\n\t\t\t\t\tif (strarr.length > text.length) {\n\t\t\t\t\t\t// Something went terribly wrong, ABORT, ABORT!\n\t\t\t\t\t\tbreak tokenloop;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (str instanceof Token) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tpattern.lastIndex = 0;\n\n\t\t\t\t\tvar match = pattern.exec(str);\n\n\t\t\t\t\tif (match) {\n\t\t\t\t\t\tif(lookbehind) {\n\t\t\t\t\t\t\tlookbehindLength = match[1].length;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar from = match.index - 1 + lookbehindLength,\n\t\t\t\t\t\t\tmatch = match[0].slice(lookbehindLength),\n\t\t\t\t\t\t\tlen = match.length,\n\t\t\t\t\t\t\tto = from + len,\n\t\t\t\t\t\t\tbefore = str.slice(0, from + 1),\n\t\t\t\t\t\t\tafter = str.slice(to + 1);\n\n\t\t\t\t\t\tvar args = [i, 1];\n\n\t\t\t\t\t\tif (before) {\n\t\t\t\t\t\t\targs.push(before);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias);\n\n\t\t\t\t\t\targs.push(wrapped);\n\n\t\t\t\t\t\tif (after) {\n\t\t\t\t\t\t\targs.push(after);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tArray.prototype.splice.apply(strarr, args);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn strarr;\n\t},\n\n\thooks: {\n\t\tall: {},\n\n\t\tadd: function (name, callback) {\n\t\t\tvar hooks = _.hooks.all;\n\n\t\t\thooks[name] = hooks[name] || [];\n\n\t\t\thooks[name].push(callback);\n\t\t},\n\n\t\trun: function (name, env) {\n\t\t\tvar callbacks = _.hooks.all[name];\n\n\t\t\tif (!callbacks || !callbacks.length) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (var i=0, callback; callback = callbacks[i++];) {\n\t\t\t\tcallback(env);\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar Token = _.Token = function(type, content, alias) {\n\tthis.type = type;\n\tthis.content = content;\n\tthis.alias = alias;\n};\n\nToken.stringify = function(o, language, parent) {\n\tif (typeof o == 'string') {\n\t\treturn o;\n\t}\n\n\tif (_.util.type(o) === 'Array') {\n\t\treturn o.map(function(element) {\n\t\t\treturn Token.stringify(element, language, o);\n\t\t}).join('');\n\t}\n\n\tvar env = {\n\t\ttype: o.type,\n\t\tcontent: Token.stringify(o.content, language, parent),\n\t\ttag: 'span',\n\t\tclasses: ['token', o.type],\n\t\tattributes: {},\n\t\tlanguage: language,\n\t\tparent: parent\n\t};\n\n\tif (env.type == 'comment') {\n\t\tenv.attributes['spellcheck'] = 'true';\n\t}\n\n\tif (o.alias) {\n\t\tvar aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];\n\t\tArray.prototype.push.apply(env.classes, aliases);\n\t}\n\n\t_.hooks.run('wrap', env);\n\n\tvar attributes = '';\n\n\tfor (var name in env.attributes) {\n\t\tattributes += (attributes ? ' ' : '') + name + '=\"' + (env.attributes[name] || '') + '\"';\n\t}\n\n\treturn '<' + env.tag + ' class=\"' + env.classes.join(' ') + '\" ' + attributes + '>' + env.content + '</' + env.tag + '>';\n\n};\n\nif (!_self.document) {\n\tif (!_self.addEventListener) {\n\t\t// in Node.js\n\t\treturn _self.Prism;\n\t}\n \t// In worker\n\t_self.addEventListener('message', function(evt) {\n\t\tvar message = JSON.parse(evt.data),\n\t\t    lang = message.language,\n\t\t    code = message.code,\n\t\t    immediateClose = message.immediateClose;\n\n\t\t_self.postMessage(_.highlight(code, _.languages[lang], lang));\n\t\tif (immediateClose) {\n\t\t\t_self.close();\n\t\t}\n\t}, false);\n\n\treturn _self.Prism;\n}\n\n// Get current script and highlight\nvar script = document.getElementsByTagName('script');\n\nscript = script[script.length - 1];\n\nif (script) {\n\t_.filename = script.src;\n\n\tif (document.addEventListener && !script.hasAttribute('data-manual')) {\n\t\tdocument.addEventListener('DOMContentLoaded', _.highlightAll);\n\t}\n}\n\nreturn _self.Prism;\n\n})();\n\nif (typeof module !== 'undefined' && module.exports) {\n\tmodule.exports = Prism;\n}\n\n// hack for components to work correctly in node.js\nif (typeof global !== 'undefined') {\n\tglobal.Prism = Prism;\n}\n\n\n/* **********************************************\n     Begin prism-markup.js\n********************************************** */\n\nPrism.languages.markup = {\n\t'comment': /<!--[\\w\\W]*?-->/,\n\t'prolog': /<\\?[\\w\\W]+?\\?>/,\n\t'doctype': /<!DOCTYPE[\\w\\W]+?>/,\n\t'cdata': /<!\\[CDATA\\[[\\w\\W]*?]]>/i,\n\t'tag': {\n\t\tpattern: /<\\/?(?!\\d)[^\\s>\\/=.$<]+(?:\\s+[^\\s>\\/=]+(?:=(?:(\"|')(?:\\\\\\1|\\\\?(?!\\1)[\\w\\W])*\\1|[^\\s'\">=]+))?)*\\s*\\/?>/i,\n\t\tinside: {\n\t\t\t'tag': {\n\t\t\t\tpattern: /^<\\/?[^\\s>\\/]+/i,\n\t\t\t\tinside: {\n\t\t\t\t\t'punctuation': /^<\\/?/,\n\t\t\t\t\t'namespace': /^[^\\s>\\/:]+:/\n\t\t\t\t}\n\t\t\t},\n\t\t\t'attr-value': {\n\t\t\t\tpattern: /=(?:('|\")[\\w\\W]*?(\\1)|[^\\s>]+)/i,\n\t\t\t\tinside: {\n\t\t\t\t\t'punctuation': /[=>\"']/\n\t\t\t\t}\n\t\t\t},\n\t\t\t'punctuation': /\\/?>/,\n\t\t\t'attr-name': {\n\t\t\t\tpattern: /[^\\s>\\/]+/,\n\t\t\t\tinside: {\n\t\t\t\t\t'namespace': /^[^\\s>\\/:]+:/\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t},\n\t'entity': /&#?[\\da-z]{1,8};/i\n};\n\n// Plugin to make entity title show the real entity, idea by Roman Komarov\nPrism.hooks.add('wrap', function(env) {\n\n\tif (env.type === 'entity') {\n\t\tenv.attributes['title'] = env.content.replace(/&amp;/, '&');\n\t}\n});\n\nPrism.languages.xml = Prism.languages.markup;\nPrism.languages.html = Prism.languages.markup;\nPrism.languages.mathml = Prism.languages.markup;\nPrism.languages.svg = Prism.languages.markup;\n\n\n/* **********************************************\n     Begin prism-css.js\n********************************************** */\n\nPrism.languages.css = {\n\t'comment': /\\/\\*[\\w\\W]*?\\*\\//,\n\t'atrule': {\n\t\tpattern: /@[\\w-]+?.*?(;|(?=\\s*\\{))/i,\n\t\tinside: {\n\t\t\t'rule': /@[\\w-]+/\n\t\t\t// See rest below\n\t\t}\n\t},\n\t'url': /url\\((?:([\"'])(\\\\(?:\\r\\n|[\\w\\W])|(?!\\1)[^\\\\\\r\\n])*\\1|.*?)\\)/i,\n\t'selector': /[^\\{\\}\\s][^\\{\\};]*?(?=\\s*\\{)/,\n\t'string': /(\"|')(\\\\(?:\\r\\n|[\\w\\W])|(?!\\1)[^\\\\\\r\\n])*\\1/,\n\t'property': /(\\b|\\B)[\\w-]+(?=\\s*:)/i,\n\t'important': /\\B!important\\b/i,\n\t'function': /[-a-z0-9]+(?=\\()/i,\n\t'punctuation': /[(){};:]/\n};\n\nPrism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css);\n\nif (Prism.languages.markup) {\n\tPrism.languages.insertBefore('markup', 'tag', {\n\t\t'style': {\n\t\t\tpattern: /(<style[\\w\\W]*?>)[\\w\\W]*?(?=<\\/style>)/i,\n\t\t\tlookbehind: true,\n\t\t\tinside: Prism.languages.css,\n\t\t\talias: 'language-css'\n\t\t}\n\t});\n\t\n\tPrism.languages.insertBefore('inside', 'attr-value', {\n\t\t'style-attr': {\n\t\t\tpattern: /\\s*style=(\"|').*?\\1/i,\n\t\t\tinside: {\n\t\t\t\t'attr-name': {\n\t\t\t\t\tpattern: /^\\s*style/i,\n\t\t\t\t\tinside: Prism.languages.markup.tag.inside\n\t\t\t\t},\n\t\t\t\t'punctuation': /^\\s*=\\s*['\"]|['\"]\\s*$/,\n\t\t\t\t'attr-value': {\n\t\t\t\t\tpattern: /.+/i,\n\t\t\t\t\tinside: Prism.languages.css\n\t\t\t\t}\n\t\t\t},\n\t\t\talias: 'language-css'\n\t\t}\n\t}, Prism.languages.markup.tag);\n}\n\n/* **********************************************\n     Begin prism-clike.js\n********************************************** */\n\nPrism.languages.clike = {\n\t'comment': [\n\t\t{\n\t\t\tpattern: /(^|[^\\\\])\\/\\*[\\w\\W]*?\\*\\//,\n\t\t\tlookbehind: true\n\t\t},\n\t\t{\n\t\t\tpattern: /(^|[^\\\\:])\\/\\/.*/,\n\t\t\tlookbehind: true\n\t\t}\n\t],\n\t'string': /([\"'])(\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1/,\n\t'class-name': {\n\t\tpattern: /((?:\\b(?:class|interface|extends|implements|trait|instanceof|new)\\s+)|(?:catch\\s+\\())[a-z0-9_\\.\\\\]+/i,\n\t\tlookbehind: true,\n\t\tinside: {\n\t\t\tpunctuation: /(\\.|\\\\)/\n\t\t}\n\t},\n\t'keyword': /\\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\\b/,\n\t'boolean': /\\b(true|false)\\b/,\n\t'function': /[a-z0-9_]+(?=\\()/i,\n\t'number': /\\b-?(?:0x[\\da-f]+|\\d*\\.?\\d+(?:e[+-]?\\d+)?)\\b/i,\n\t'operator': /--?|\\+\\+?|!=?=?|<=?|>=?|==?=?|&&?|\\|\\|?|\\?|\\*|\\/|~|\\^|%/,\n\t'punctuation': /[{}[\\];(),.:]/\n};\n\n\n/* **********************************************\n     Begin prism-javascript.js\n********************************************** */\n\nPrism.languages.javascript = Prism.languages.extend('clike', {\n\t'keyword': /\\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\\b/,\n\t'number': /\\b-?(0x[\\dA-Fa-f]+|0b[01]+|0o[0-7]+|\\d*\\.?\\d+([Ee][+-]?\\d+)?|NaN|Infinity)\\b/,\n\t// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)\n\t'function': /[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*(?=\\()/i\n});\n\nPrism.languages.insertBefore('javascript', 'keyword', {\n\t'regex': {\n\t\tpattern: /(^|[^/])\\/(?!\\/)(\\[.+?]|\\\\.|[^/\\\\\\r\\n])+\\/[gimyu]{0,5}(?=\\s*($|[\\r\\n,.;})]))/,\n\t\tlookbehind: true\n\t}\n});\n\nPrism.languages.insertBefore('javascript', 'class-name', {\n\t'template-string': {\n\t\tpattern: /`(?:\\\\`|\\\\?[^`])*`/,\n\t\tinside: {\n\t\t\t'interpolation': {\n\t\t\t\tpattern: /\\$\\{[^}]+\\}/,\n\t\t\t\tinside: {\n\t\t\t\t\t'interpolation-punctuation': {\n\t\t\t\t\t\tpattern: /^\\$\\{|\\}$/,\n\t\t\t\t\t\talias: 'punctuation'\n\t\t\t\t\t},\n\t\t\t\t\trest: Prism.languages.javascript\n\t\t\t\t}\n\t\t\t},\n\t\t\t'string': /[\\s\\S]+/\n\t\t}\n\t}\n});\n\nif (Prism.languages.markup) {\n\tPrism.languages.insertBefore('markup', 'tag', {\n\t\t'script': {\n\t\t\tpattern: /(<script[\\w\\W]*?>)[\\w\\W]*?(?=<\\/script>)/i,\n\t\t\tlookbehind: true,\n\t\t\tinside: Prism.languages.javascript,\n\t\t\talias: 'language-javascript'\n\t\t}\n\t});\n}\n\nPrism.languages.js = Prism.languages.javascript;\n\n/* **********************************************\n     Begin prism-file-highlight.js\n********************************************** */\n\n(function () {\n\tif (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {\n\t\treturn;\n\t}\n\n\tself.Prism.fileHighlight = function() {\n\n\t\tvar Extensions = {\n\t\t\t'js': 'javascript',\n\t\t\t'html': 'markup',\n\t\t\t'svg': 'markup',\n\t\t\t'xml': 'markup',\n\t\t\t'py': 'python',\n\t\t\t'rb': 'ruby',\n\t\t\t'ps1': 'powershell',\n\t\t\t'psm1': 'powershell'\n\t\t};\n\n\t\tif(Array.prototype.forEach) { // Check to prevent error in IE8\n\t\t\tArray.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {\n\t\t\t\tvar src = pre.getAttribute('data-src');\n\n\t\t\t\tvar language, parent = pre;\n\t\t\t\tvar lang = /\\blang(?:uage)?-(?!\\*)(\\w+)\\b/i;\n\t\t\t\twhile (parent && !lang.test(parent.className)) {\n\t\t\t\t\tparent = parent.parentNode;\n\t\t\t\t}\n\n\t\t\t\tif (parent) {\n\t\t\t\t\tlanguage = (pre.className.match(lang) || [, ''])[1];\n\t\t\t\t}\n\n\t\t\t\tif (!language) {\n\t\t\t\t\tvar extension = (src.match(/\\.(\\w+)$/) || [, ''])[1];\n\t\t\t\t\tlanguage = Extensions[extension] || extension;\n\t\t\t\t}\n\n\t\t\t\tvar code = document.createElement('code');\n\t\t\t\tcode.className = 'language-' + language;\n\n\t\t\t\tpre.textContent = '';\n\n\t\t\t\tcode.textContent = 'Loading…';\n\n\t\t\t\tpre.appendChild(code);\n\n\t\t\t\tvar xhr = new XMLHttpRequest();\n\n\t\t\t\txhr.open('GET', src, true);\n\n\t\t\t\txhr.onreadystatechange = function () {\n\t\t\t\t\tif (xhr.readyState == 4) {\n\n\t\t\t\t\t\tif (xhr.status < 400 && xhr.responseText) {\n\t\t\t\t\t\t\tcode.textContent = xhr.responseText;\n\n\t\t\t\t\t\t\tPrism.highlightElement(code);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (xhr.status >= 400) {\n\t\t\t\t\t\t\tcode.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tcode.textContent = '✖ Error: File does not exist or is empty';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\txhr.send(null);\n\t\t\t});\n\t\t}\n\n\t};\n\n\tself.Prism.fileHighlight();\n\n})();\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/prismjs/prism.js\n ** module id = 678\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./JSONViewer.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./JSONViewer.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./JSONViewer.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/JSONViewer.scss\n ** module id = 679\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".JSONViewer {\\n  /*\\n\\tcopied from node_modules/prismjs/themes/prismjs.css\\n*/\\n  /* Inline code */\\n}\\n\\n.JSONViewer :not(pre) > code[class*=\\\"language-\\\"],\\n.JSONViewer pre[class*=\\\"language-\\\"] {\\n  font-size: 12px;\\n  border: 1px solid rgba(220, 220, 220, 0.5);\\n  border-radius: 4px;\\n  background-color: rgba(255, 255, 255, 0.25);\\n}\\n\\n.JSONViewer :not(pre) > code[class*=\\\"language-\\\"] {\\n  padding: .1em;\\n}\\n\\n.JSONViewer .token.comment,\\n.JSONViewer .token.prolog,\\n.JSONViewer .token.doctype,\\n.JSONViewer .token.cdata {\\n  color: slategray;\\n}\\n\\n.JSONViewer .token.punctuation {\\n  color: #333;\\n}\\n\\n.JSONViewer .namespace {\\n  opacity: .7;\\n}\\n\\n.JSONViewer .token.property,\\n.JSONViewer .token.tag,\\n.JSONViewer .token.boolean,\\n.JSONViewer .token.number,\\n.JSONViewer .token.constant,\\n.JSONViewer .token.symbol,\\n.JSONViewer .token.deleted {\\n  color: #905;\\n}\\n\\n.JSONViewer .token.selector,\\n.JSONViewer .token.attr-name,\\n.JSONViewer .token.string,\\n.JSONViewer .token.char,\\n.JSONViewer .token.builtin,\\n.JSONViewer .token.inserted {\\n  color: #df5000;\\n}\\n\\n.JSONViewer .token.operator,\\n.JSONViewer .token.entity,\\n.JSONViewer .token.url,\\n.JSONViewer .language-css .token.string,\\n.JSONViewer .style .token.string {\\n  color: #a67f59;\\n  background: rgba(255, 255, 255, 0.5);\\n}\\n\\n.JSONViewer .token.atrule,\\n.JSONViewer .token.attr-value,\\n.JSONViewer .token.keyword {\\n  color: #07a;\\n}\\n\\n.JSONViewer .token.function {\\n  color: #DD4A68;\\n}\\n\\n.JSONViewer .token.regex,\\n.JSONViewer .token.important,\\n.JSONViewer .token.variable {\\n  color: #e90;\\n}\\n\\n.JSONViewer .token.important,\\n.JSONViewer .token.bold {\\n  font-weight: bold;\\n}\\n\\n.JSONViewer .token.italic {\\n  font-style: italic;\\n}\\n\\n.JSONViewer .token.entity {\\n  cursor: help;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/JSONViewer.scss\n ** module id = 680\n ** module chunks = 0\n **/","/**\n * Created by onvelocity on 2/2/16.\n */\n\nimport React from 'react'\nimport OpenWindow from 'react-popout'\nimport JSONViewer from './JSONViewer'\nimport ComposerAppActions from '../actions/ComposerAppActions'\n\nimport '../styles/JSONViewer.scss'\n\nwindow._open = window.open.bind(window);\nwindow.open = function monkeyPatchOpen(url, name, options) {\n\tconst popupWindow = this._open(url, name, options);\n\tpopupWindow.document.getElementsByTagName('body')[0].focus();\n\treturn popupWindow;\n};\n\nexport default function (props) {\n\tif (!props.show) {\n\t\treturn <div></div>;\n\t}\n\tfunction onClose() {\n\t\tComposerAppActions.closeJsonViewer();\n\t}\n\treturn (\n\t\t<OpenWindow title={\"RIFT.ware Popup\"} onClosing={onClose}>\n\t\t\t<div>\n\t\t\t\t<h1>{props.title}</h1>\n\t\t\t\t{props.children}\n\t\t\t</div>\n\t\t</OpenWindow>\n\t);\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/PopupWindow.js\n **/","!function(t,n){if(\"object\"==typeof exports&&\"object\"==typeof module)module.exports=n(require(\"react\"),require(\"react-dom\"));else if(\"function\"==typeof define&&define.amd)define([\"react\",\"react-dom\"],n);else{var r=\"object\"==typeof exports?n(require(\"react\"),require(\"react-dom\")):n(t.React,t.ReactDOM);for(var e in r)(\"object\"==typeof exports?exports:t)[e]=r[e]}}(this,function(t,n){return function(t){function n(e){if(r[e])return r[e].exports;var o=r[e]={exports:{},id:e,loaded:!1};return t[e].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var r={};return n.m=t,n.c=r,n.p=\"\",n(0)}([function(t,n,r){t.exports=r(1)},function(t,n,r){\"use strict\";function e(t){return t&&t.__esModule?t:{\"default\":t}}function o(t,n){if(!(t instanceof n))throw new TypeError(\"Cannot call a class as a function\")}function u(t,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof n);t.prototype=Object.create(n&&n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),n&&(t.__proto__=n)}Object.defineProperty(n,\"__esModule\",{value:!0});var i=function(){function t(t,n){for(var r=0;r<n.length;r++){var e=n[r];e.enumerable=e.enumerable||!1,e.configurable=!0,\"value\"in e&&(e.writable=!0),Object.defineProperty(t,e.key,e)}}return function(n,r,e){return r&&t(n.prototype,r),e&&t(n,e),n}}(),c=function(t,n,r){for(var e=!0;e;){var o=t,u=n,i=r;c=l=f=void 0,e=!1,null===o&&(o=Function.prototype);var c=Object.getOwnPropertyDescriptor(o,u);if(void 0!==c){if(\"value\"in c)return c.value;var f=c.get;return void 0===f?void 0:f.call(i)}var l=Object.getPrototypeOf(o);if(null===l)return void 0;t=l,n=u,r=i,e=!0}},f=r(2),l=e(f),a=r(3),p=e(a),s=r(4),v=e(s),y=r(15),d=e(y),b=r(16),g=e(b),h=\"popout-content-container\",j=function(t){function n(t){o(this,n),c(Object.getPrototypeOf(n.prototype),\"constructor\",this).call(this,t),this.windowClosing=this.windowClosing.bind(this),this.defaultOptions={toolbar:\"no\",location:\"no\",directories:\"no\",status:\"no\",menubar:\"no\",scrollbars:\"yes\",resizable:\"yes\",width:500,height:400,top:function(t,n){return(n.innerHeight-t.height)/2+n.screenY},left:function(t,n){return(n.innerWidth-t.width)/2+n.screenX}},this.state={openedWindow:null}}return u(n,t),i(n,[{key:\"componentWillUnmount\",value:function(){this.closeWindow()}},{key:\"componentDidMount\",value:function(){var t,n,r=this,e={update:function(){},close:function(){}},o=v[\"default\"]({},this.defaultOptions,this.props.options),u=this.props.window||window,i=g[\"default\"](o,function(t,n,r){var e=void 0;e=d[\"default\"](n)?n(o,u):n;var i=r+\"=\"+e;return t?t+\",\"+i:i},\"\");t=u.open(this.props.url||\"about:blank\",this.props.title,i),t.onbeforeunload=function(){n&&p[\"default\"].unmountComponentAtNode(n),r.windowClosing()};var c=function(){if(n){var o=t.document.getElementById(h);if(o)return;p[\"default\"].unmountComponentAtNode(n),n=null}t.document.title=r.props.title,n=t.document.createElement(\"div\"),n.id=h,t.document.body.appendChild(n),p[\"default\"].render(r.props.children,n),e.update=function(t){p[\"default\"].render(t,n)},e.close=function(){return t.close()}};t.onload=c,c(),this.setState({openedWindow:e})}},{key:\"closeWindow\",value:function(){this.state.openedWindow&&this.state.openedWindow.close()}},{key:\"windowClosing\",value:function(){this.props.onClosing&&this.props.onClosing()}},{key:\"componentDidUpdate\",value:function(){this.state.openedWindow.update(this.props.children)}},{key:\"render\",value:function(){return l[\"default\"].createElement(\"div\",null)}}]),n}(l[\"default\"].Component);n[\"default\"]=j,j.propTypes={title:l[\"default\"].PropTypes.string.isRequired,url:l[\"default\"].PropTypes.string,onClosing:l[\"default\"].PropTypes.func,options:l[\"default\"].PropTypes.object,window:l[\"default\"].PropTypes.object},t.exports=n[\"default\"]},function(n,r){n.exports=t},function(t,r){t.exports=n},function(t,n,r){function e(t,n,r){for(var e=-1,o=i(n),u=o.length;++e<u;){var c=o[e],f=t[c],l=r(f,n[c],c,t,n);(l===l?l===f:f!==f)&&(void 0!==f||c in t)||(t[c]=l)}return t}var o=r(5),u=r(11),i=r(7),c=u(function(t,n,r){return r?e(t,n,r):o(t,n)});t.exports=c},function(t,n,r){function e(t,n){return null==n?t:o(n,u(n),t)}var o=r(6),u=r(7);t.exports=e},function(t,n){function r(t,n,r){r||(r={});for(var e=-1,o=n.length;++e<o;){var u=n[e];r[u]=t[u]}return r}t.exports=r},function(t,n,r){function e(t){return function(n){return null==n?void 0:n[t]}}function o(t){return null!=t&&i(h(t))}function u(t,n){return t=\"number\"==typeof t||v.test(t)?+t:-1,n=null==n?g:n,t>-1&&t%1==0&&n>t}function i(t){return\"number\"==typeof t&&t>-1&&t%1==0&&g>=t}function c(t){for(var n=l(t),r=n.length,e=r&&t.length,o=!!e&&i(e)&&(s(t)||p(t)),c=-1,f=[];++c<r;){var a=n[c];(o&&u(a,e)||d.call(t,a))&&f.push(a)}return f}function f(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}function l(t){if(null==t)return[];f(t)||(t=Object(t));var n=t.length;n=n&&i(n)&&(s(t)||p(t))&&n||0;for(var r=t.constructor,e=-1,o=\"function\"==typeof r&&r.prototype===t,c=Array(n),l=n>0;++e<n;)c[e]=e+\"\";for(var a in t)l&&u(a,n)||\"constructor\"==a&&(o||!d.call(t,a))||c.push(a);return c}var a=r(8),p=r(9),s=r(10),v=/^\\d+$/,y=Object.prototype,d=y.hasOwnProperty,b=a(Object,\"keys\"),g=9007199254740991,h=e(\"length\"),j=b?function(t){var n=null==t?null:t.constructor;return\"function\"==typeof n&&n.prototype===t||\"function\"!=typeof t&&o(t)?c(t):f(t)?b(t):[]}:c;t.exports=j},function(t,n){function r(t){return\"string\"==typeof t?t:null==t?\"\":t+\"\"}function e(t){return!!t&&\"object\"==typeof t}function o(t,n){var r=null==t?void 0:t[n];return u(r)?r:void 0}function u(t){return null==t?!1:y.call(t)==c?d.test(s.call(t)):e(t)&&a.test(t)}function i(t){return t=r(t),t&&l.test(t)?t.replace(f,\"\\\\$&\"):t}var c=\"[object Function]\",f=/[.*+?^${}()|[\\]\\/\\\\]/g,l=RegExp(f.source),a=/^\\[object .+?Constructor\\]$/,p=Object.prototype,s=Function.prototype.toString,v=p.hasOwnProperty,y=p.toString,d=RegExp(\"^\"+i(s.call(v)).replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\");t.exports=o},function(t,n){function r(t){return!!t&&\"object\"==typeof t}function e(t){return function(n){return null==n?void 0:n[t]}}function o(t){return null!=t&&u(p(t))}function u(t){return\"number\"==typeof t&&t>-1&&t%1==0&&a>=t}function i(t){return r(t)&&o(t)&&l.call(t)==c}var c=\"[object Arguments]\",f=Object.prototype,l=f.toString,a=9007199254740991,p=e(\"length\");t.exports=i},function(t,n){function r(t){return\"string\"==typeof t?t:null==t?\"\":t+\"\"}function e(t){return!!t&&\"object\"==typeof t}function o(t,n){var r=null==t?void 0:t[n];return i(r)?r:void 0}function u(t){return\"number\"==typeof t&&t>-1&&t%1==0&&j>=t}function i(t){return null==t?!1:b.call(t)==l?g.test(y.call(t)):e(t)&&s.test(t)}function c(t){return t=r(t),t&&p.test(t)?t.replace(a,\"\\\\$&\"):t}var f=\"[object Array]\",l=\"[object Function]\",a=/[.*+?^${}()|[\\]\\/\\\\]/g,p=RegExp(a.source),s=/^\\[object .+?Constructor\\]$/,v=Object.prototype,y=Function.prototype.toString,d=v.hasOwnProperty,b=v.toString,g=RegExp(\"^\"+c(y.call(d)).replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\"),h=o(Array,\"isArray\"),j=9007199254740991,m=h||function(t){return e(t)&&u(t.length)&&b.call(t)==f};t.exports=m},function(t,n,r){function e(t){return i(function(n,r){var e=-1,i=null==n?0:r.length,c=i>2?r[i-2]:void 0,f=i>2?r[2]:void 0,l=i>1?r[i-1]:void 0;for(\"function\"==typeof c?(c=o(c,l,5),i-=2):(c=\"function\"==typeof l?l:void 0,i-=c?1:0),f&&u(r[0],r[1],f)&&(c=3>i?void 0:c,i=1);++e<i;){var a=r[e];a&&t(n,a,c)}return n})}var o=r(12),u=r(13),i=r(14);t.exports=e},function(t,n){function r(t,n,r){if(\"function\"!=typeof t)return e;if(void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 3:return function(r,e,o){return t.call(n,r,e,o)};case 4:return function(r,e,o,u){return t.call(n,r,e,o,u)};case 5:return function(r,e,o,u,i){return t.call(n,r,e,o,u,i)}}return function(){return t.apply(n,arguments)}}function e(t){return t}t.exports=r},function(t,n){function r(t){return function(n){return null==n?void 0:n[t]}}function e(t){return null!=t&&i(a(t))}function o(t,n){return t=\"number\"==typeof t||f.test(t)?+t:-1,n=null==n?l:n,t>-1&&t%1==0&&n>t}function u(t,n,r){if(!c(r))return!1;var u=typeof n;if(\"number\"==u?e(r)&&o(n,r.length):\"string\"==u&&n in r){var i=r[n];return t===t?t===i:i!==i}return!1}function i(t){return\"number\"==typeof t&&t>-1&&t%1==0&&l>=t}function c(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}var f=/^\\d+$/,l=9007199254740991,a=r(\"length\");t.exports=u},function(t,n){function r(t,n){if(\"function\"!=typeof t)throw new TypeError(e);return n=o(void 0===n?t.length-1:+n||0,0),function(){for(var r=arguments,e=-1,u=o(r.length-n,0),i=Array(u);++e<u;)i[e]=r[n+e];switch(n){case 0:return t.call(this,i);case 1:return t.call(this,r[0],i);case 2:return t.call(this,r[0],r[1],i)}var c=Array(n+1);for(e=-1;++e<n;)c[e]=r[e];return c[n]=i,t.apply(this,c)}}var e=\"Expected a function\",o=Math.max;t.exports=r},function(t,n){(function(n){function r(t){return\"function\"==typeof t||!1}function e(t){return\"string\"==typeof t?t:null==t?\"\":t+\"\"}function o(t){return!!t&&\"object\"==typeof t}function u(t,n){var r=null==t?void 0:t[n];return i(r)?r:void 0}function i(t){return null==t?!1:d.call(t)==f?b.test(v.call(t)):o(t)&&p.test(t)}function c(t){return t=e(t),t&&a.test(t)?t.replace(l,\"\\\\$&\"):t}var f=\"[object Function]\",l=/[.*+?^${}()|[\\]\\/\\\\]/g,a=RegExp(l.source),p=/^\\[object .+?Constructor\\]$/,s=Object.prototype,v=Function.prototype.toString,y=s.hasOwnProperty,d=s.toString,b=RegExp(\"^\"+c(v.call(y)).replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\"),g=u(n,\"Uint8Array\"),h=r(/x/)||g&&!r(g)?function(t){return d.call(t)==f}:r;t.exports=h}).call(n,function(){return this}())},function(t,n,r){function e(t,n,r,e){var o=-1,u=t.length;for(e&&u&&(r=t[++o]);++o<u;)r=n(r,t[o],o,t);return r}function o(t,n){return function(r,e,o,i){var l=arguments.length<3;return\"function\"==typeof e&&void 0===i&&f(r)?t(r,e,o,l):c(r,u(e,i,4),o,l,n)}}var u=r(17),i=r(26),c=r(27),f=r(19),l=o(e,i);t.exports=l},function(t,n,r){function e(t){return\"string\"==typeof t?t:null==t?\"\":t+\"\"}function o(t,n,r){var e=typeof t;return\"function\"==e?void 0===n?t:w(t,n,r):null==t?j:\"object\"==e?c(t):void 0===n?m(t):f(t,n)}function u(t,n,r){if(null!=t){void 0!==r&&r in d(t)&&(n=[r]);for(var e=0,o=n.length;null!=t&&o>e;)t=t[n[e++]];return e&&e==o?t:void 0}}function i(t,n,r){var e=n.length,o=e,u=!r;if(null==t)return!o;for(t=d(t);e--;){var i=n[e];if(u&&i[2]?i[1]!==t[i[0]]:!(i[0]in t))return!1}for(;++e<o;){i=n[e];var c=i[0],f=t[c],l=i[1];if(u&&i[2]){if(void 0===f&&!(c in t))return!1}else{var a=r?r(f,l,c):void 0;if(!(void 0===a?x(l,f,r,!0):a))return!1}}return!0}function c(t){var n=s(t);if(1==n.length&&n[0][2]){var r=n[0][0],e=n[0][1];return function(t){return null==t?!1:t[r]===e&&(void 0!==e||r in d(t))}}return function(t){return i(t,n)}}function f(t,n){var r=O(t),e=v(t)&&y(n),o=t+\"\";return t=b(t),function(i){if(null==i)return!1;var c=o;if(i=d(i),!(!r&&e||c in i)){if(i=1==t.length?i:u(i,p(t,0,-1)),null==i)return!1;c=g(t),i=d(i)}return i[c]===n?void 0!==n||c in i:x(n,i[c],void 0,!0)}}function l(t){return function(n){return null==n?void 0:n[t]}}function a(t){var n=t+\"\";return t=b(t),function(r){return u(r,t,n)}}function p(t,n,r){var e=-1,o=t.length;n=null==n?0:+n||0,0>n&&(n=-n>o?0:o+n),r=void 0===r||r>o?o:+r||0,0>r&&(r+=o),o=n>r?0:r-n>>>0,n>>>=0;for(var u=Array(o);++e<o;)u[e]=t[e+n];return u}function s(t){for(var n=A(t),r=n.length;r--;)n[r][2]=y(n[r][1]);return n}function v(t,n){var r=typeof t;if(\"string\"==r&&P.test(t)||\"number\"==r)return!0;if(O(t))return!1;var e=!$.test(t);return e||null!=n&&t in d(n)}function y(t){return t===t&&!h(t)}function d(t){return h(t)?t:Object(t)}function b(t){if(O(t))return t;var n=[];return e(t).replace(E,function(t,r,e,o){n.push(e?o.replace(S,\"$1\"):r||t)}),n}function g(t){var n=t?t.length:0;return n?t[n-1]:void 0}function h(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}function j(t){return t}function m(t){return v(t)?l(t):a(t)}var x=r(18),w=r(24),O=r(19),A=r(25),$=/\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\n\\\\]|\\\\.)*?\\1)\\]/,P=/^\\w*$/,E=/[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\n\\\\]|\\\\.)*?)\\2)\\]/g,S=/\\\\(\\\\)?/g;t.exports=o},function(t,n,r){function e(t){return!!t&&\"object\"==typeof t}function o(t,n){for(var r=-1,e=t.length;++r<e;)if(n(t[r],r,t))return!0;return!1}function u(t,n,r,o,c,f){return t===n?!0:null==t||null==n||!a(t)&&!e(n)?t!==t&&n!==n:i(t,n,u,r,o,c,f)}function i(t,n,r,e,o,u,i){var a=p(t),v=p(n),b=d,g=d;a||(b=$.call(t),b==y?b=m:b!=m&&(a=s(t))),v||(g=$.call(n),g==y?g=m:g!=m&&(v=s(n)));var h=b==m,j=g==m,x=b==g;if(x&&!a&&!h)return f(t,n,b);if(!o){var w=h&&A.call(t,\"__wrapped__\"),O=j&&A.call(n,\"__wrapped__\");if(w||O)return r(w?t.value():t,O?n.value():n,e,o,u,i)}if(!x)return!1;u||(u=[]),i||(i=[]);for(var P=u.length;P--;)if(u[P]==t)return i[P]==n;u.push(t),i.push(n);var E=(a?c:l)(t,n,r,e,o,u,i);return u.pop(),i.pop(),E}function c(t,n,r,e,u,i,c){var f=-1,l=t.length,a=n.length;if(l!=a&&!(u&&a>l))return!1;for(;++f<l;){var p=t[f],s=n[f],v=e?e(u?s:p,u?p:s,f):void 0;if(void 0!==v){if(v)continue;return!1}if(u){if(!o(n,function(t){return p===t||r(p,t,e,u,i,c)}))return!1}else if(p!==s&&!r(p,s,e,u,i,c))return!1}return!0}function f(t,n,r){switch(r){case b:case g:return+t==+n;case h:return t.name==n.name&&t.message==n.message;case j:return t!=+t?n!=+n:t==+n;case x:case w:return t==n+\"\"}return!1}function l(t,n,r,e,o,u,i){var c=v(t),f=c.length,l=v(n),a=l.length;if(f!=a&&!o)return!1;for(var p=f;p--;){var s=c[p];if(!(o?s in n:A.call(n,s)))return!1}for(var y=o;++p<f;){s=c[p];var d=t[s],b=n[s],g=e?e(o?b:d,o?d:b,s):void 0;if(!(void 0===g?r(d,b,e,o,u,i):g))return!1;y||(y=\"constructor\"==s)}if(!y){var h=t.constructor,j=n.constructor;if(h!=j&&\"constructor\"in t&&\"constructor\"in n&&!(\"function\"==typeof h&&h instanceof h&&\"function\"==typeof j&&j instanceof j))return!1}return!0}function a(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}var p=r(19),s=r(20),v=r(21),y=\"[object Arguments]\",d=\"[object Array]\",b=\"[object Boolean]\",g=\"[object Date]\",h=\"[object Error]\",j=\"[object Number]\",m=\"[object Object]\",x=\"[object RegExp]\",w=\"[object String]\",O=Object.prototype,A=O.hasOwnProperty,$=O.toString;t.exports=u},function(t,n){function r(t){return\"string\"==typeof t?t:null==t?\"\":t+\"\"}function e(t){return!!t&&\"object\"==typeof t}function o(t,n){var r=null==t?void 0:t[n];return i(r)?r:void 0}function u(t){return\"number\"==typeof t&&t>-1&&t%1==0&&j>=t}function i(t){return null==t?!1:b.call(t)==l?g.test(y.call(t)):e(t)&&s.test(t)}function c(t){return t=r(t),t&&p.test(t)?t.replace(a,\"\\\\$&\"):t}var f=\"[object Array]\",l=\"[object Function]\",a=/[.*+?^${}()|[\\]\\/\\\\]/g,p=RegExp(a.source),s=/^\\[object .+?Constructor\\]$/,v=Object.prototype,y=Function.prototype.toString,d=v.hasOwnProperty,b=v.toString,g=RegExp(\"^\"+c(y.call(d)).replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\"),h=o(Array,\"isArray\"),j=9007199254740991,m=h||function(t){return e(t)&&u(t.length)&&b.call(t)==f};t.exports=m},function(t,n){function r(t){return!!t&&\"object\"==typeof t}function e(t){return\"number\"==typeof t&&t>-1&&t%1==0&&R>=t}function o(t){return r(t)&&e(t.length)&&!!S[_.call(t)]}var u=\"[object Arguments]\",i=\"[object Array]\",c=\"[object Boolean]\",f=\"[object Date]\",l=\"[object Error]\",a=\"[object Function]\",p=\"[object Map]\",s=\"[object Number]\",v=\"[object Object]\",y=\"[object RegExp]\",d=\"[object Set]\",b=\"[object String]\",g=\"[object WeakMap]\",h=\"[object ArrayBuffer]\",j=\"[object Float32Array]\",m=\"[object Float64Array]\",x=\"[object Int8Array]\",w=\"[object Int16Array]\",O=\"[object Int32Array]\",A=\"[object Uint8Array]\",$=\"[object Uint8ClampedArray]\",P=\"[object Uint16Array]\",E=\"[object Uint32Array]\",S={};S[j]=S[m]=S[x]=S[w]=S[O]=S[A]=S[$]=S[P]=S[E]=!0,S[u]=S[i]=S[h]=S[c]=S[f]=S[l]=S[a]=S[p]=S[s]=S[v]=S[y]=S[d]=S[b]=S[g]=!1;var C=Object.prototype,_=C.toString,R=9007199254740991;t.exports=o},function(t,n,r){function e(t){return function(n){return null==n?void 0:n[t]}}function o(t){return null!=t&&i(h(t))}function u(t,n){return t=\"number\"==typeof t||v.test(t)?+t:-1,n=null==n?g:n,t>-1&&t%1==0&&n>t}function i(t){return\"number\"==typeof t&&t>-1&&t%1==0&&g>=t}function c(t){for(var n=l(t),r=n.length,e=r&&t.length,o=!!e&&i(e)&&(s(t)||p(t)),c=-1,f=[];++c<r;){var a=n[c];(o&&u(a,e)||d.call(t,a))&&f.push(a)}return f}function f(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}function l(t){if(null==t)return[];f(t)||(t=Object(t));var n=t.length;n=n&&i(n)&&(s(t)||p(t))&&n||0;for(var r=t.constructor,e=-1,o=\"function\"==typeof r&&r.prototype===t,c=Array(n),l=n>0;++e<n;)c[e]=e+\"\";for(var a in t)l&&u(a,n)||\"constructor\"==a&&(o||!d.call(t,a))||c.push(a);return c}var a=r(22),p=r(23),s=r(19),v=/^\\d+$/,y=Object.prototype,d=y.hasOwnProperty,b=a(Object,\"keys\"),g=9007199254740991,h=e(\"length\"),j=b?function(t){var n=null==t?null:t.constructor;return\"function\"==typeof n&&n.prototype===t||\"function\"!=typeof t&&o(t)?c(t):f(t)?b(t):[]}:c;t.exports=j},function(t,n){function r(t){return\"string\"==typeof t?t:null==t?\"\":t+\"\"}function e(t){return!!t&&\"object\"==typeof t}function o(t,n){var r=null==t?void 0:t[n];return u(r)?r:void 0}function u(t){return null==t?!1:y.call(t)==c?d.test(s.call(t)):e(t)&&a.test(t)}function i(t){return t=r(t),t&&l.test(t)?t.replace(f,\"\\\\$&\"):t}var c=\"[object Function]\",f=/[.*+?^${}()|[\\]\\/\\\\]/g,l=RegExp(f.source),a=/^\\[object .+?Constructor\\]$/,p=Object.prototype,s=Function.prototype.toString,v=p.hasOwnProperty,y=p.toString,d=RegExp(\"^\"+i(s.call(v)).replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\");t.exports=o},function(t,n){function r(t){return!!t&&\"object\"==typeof t}function e(t){return function(n){return null==n?void 0:n[t]}}function o(t){return null!=t&&u(p(t))}function u(t){return\"number\"==typeof t&&t>-1&&t%1==0&&a>=t}function i(t){return r(t)&&o(t)&&l.call(t)==c}var c=\"[object Arguments]\",f=Object.prototype,l=f.toString,a=9007199254740991,p=e(\"length\");t.exports=i},function(t,n){function r(t,n,r){if(\"function\"!=typeof t)return e;if(void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 3:return function(r,e,o){return t.call(n,r,e,o)};case 4:return function(r,e,o,u){return t.call(n,r,e,o,u)};case 5:return function(r,e,o,u,i){return t.call(n,r,e,o,u,i)}}return function(){return t.apply(n,arguments)}}function e(t){return t}t.exports=r},function(t,n,r){function e(t){return o(t)?t:Object(t)}function o(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}function u(t){t=e(t);for(var n=-1,r=i(t),o=r.length,u=Array(o);++n<o;){var c=r[n];u[n]=[c,t[c]]}return u}var i=r(21);t.exports=u},function(t,n,r){function e(t,n){return v(t,n,a)}function o(t){return function(n){return null==n?void 0:n[t]}}function u(t,n){return function(r,e){var o=r?y(r):0;if(!c(o))return t(r,e);for(var u=n?o:-1,i=f(r);(n?u--:++u<o)&&e(i[u],u,i)!==!1;);return r}}function i(t){return function(n,r,e){for(var o=f(n),u=e(n),i=u.length,c=t?i:-1;t?c--:++c<i;){var l=u[c];if(r(o[l],l,o)===!1)break}return n}}function c(t){return\"number\"==typeof t&&t>-1&&t%1==0&&p>=t}function f(t){return l(t)?t:Object(t)}function l(t){var n=typeof t;return!!t&&(\"object\"==n||\"function\"==n)}var a=r(21),p=9007199254740991,s=u(e),v=i(),y=o(\"length\");t.exports=s},function(t,n){function r(t,n,r,e,o){return o(t,function(t,o,u){r=e?(e=!1,t):n(r,t,o,u)}),r}t.exports=r}])});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react-popout/dist/react-popout.min.js\n ** module id = 682\n ** module chunks = 0\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport utils from '../libraries/utils'\nimport changeCase from 'change-case'\nimport ClassNames from 'classnames'\nimport React from 'react'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport buildDescriptorModelFormEditor from '../libraries/model/DescriptorModelFormEditor'\n\nimport '../styles/CatalogItemDetailsEditor.scss'\n\nconst CatalogItemDetailsEditor = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {\n\t\t\thtml: ''\n\t\t};\n\t},\n\tgetDefaultProps() {\n\t\treturn {\n\t\t\tcontainer: null,\n\t\t\twidth: 0\n\t\t};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\tnotifyCatalogItemChanged(item) {\n\t\tCatalogItemsActions.catalogItemDescriptorChanged(item);\n\t},\n\trender() {\n\n\t\tconst container = this.props.container || {model: {}, meta: {}};\n\t\tif (!(container && container.model && container.meta)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst props = {\n\t\t\tcontainer: this.props.container,\n\t\t\twidth: this.props.width\n\t\t};\n\n\t\treturn (\n\t\t\t<div className=\"CatalogItemDetailsEditor\">\n\t\t\t\t<form name=\"details-descriptor-editor-form\">\n\t\t\t\t\t<div className=\"properties-group\">\n\t\t\t\t\t\t{buildDescriptorModelFormEditor(props)}\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</div>\n\t\t);\n\n\t}\n});\n\nexport default CatalogItemDetailsEditor;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/CatalogItemDetailsEditor.js\n **/","/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 1/18/16.\n *\n * This class generates the form fields used to edit the CONFD JSON model.\n */\n'use strict';\n\nimport alt from '../../alt'\nimport _ from 'lodash'\nimport utils from './../utils'\nimport React from 'react'\nimport ClassNames from 'classnames'\nimport changeCase from 'change-case'\nimport DescriptorModel from './DescriptorModel'\nimport toggle from './../ToggleElementHandler'\nimport Button from '../../components/Button'\nimport Property from './DescriptorModelMetaProperty'\nimport ComposerAppActions from '../../actions/ComposerAppActions'\nimport CatalogItemsActions from '../../actions/CatalogItemsActions'\nimport DESCRIPTOR_MODEL_FIELDS from './DescriptorModelFields'\nimport DescriptorModelMetaFactory from './DescriptorModelMetaFactory'\nimport SelectionManager from '../SelectionManager'\nimport DeletionManager from '../DeletionManager'\n\nimport imgAdd from '../../images/add175.svg'\nimport imgRemove from '../../images/recycle69.svg'\n\nfunction getDescriptorMetaBasicForType(type) {\n\tconst basicPropertiesFilter = d => _.contains(DESCRIPTOR_MODEL_FIELDS[type], d.name);\n\treturn DescriptorModelMetaFactory.getModelMetaForType(type, basicPropertiesFilter) || {properties: []};\n}\n\nfunction getDescriptorMetaAdvancedForType(type) {\n\tconst advPropertiesFilter = d => !_.contains(DESCRIPTOR_MODEL_FIELDS[type], d.name);\n\treturn DescriptorModelMetaFactory.getModelMetaForType(type, advPropertiesFilter) || {properties: []};\n}\n\nexport default function buildDescriptorModelFormEditor(props) {\n\n\tconst container = props.container;\n\n\tif (!(container instanceof DescriptorModel)) {\n\t\treturn null;\n\t}\n\n\tfunction startEditing() {\n\t\tSelectionManager.pause();\n\t\tDeletionManager.removeEventListeners();\n\t}\n\n\tfunction endEditing() {\n\t\tSelectionManager.resume();\n\t\tDeletionManager.addEventListeners();\n\t}\n\n\tfunction onFocusPropertyFormInputElement(property, path, value, event) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\tstartEditing();\n\t\tthis.getRoot().meta.focusedPropertyPath = path.join('.');\n\t\tconsole.log('property selected', path.join('.'));\n\t\tComposerAppActions.propertySelected([path.join('.')]);\n\t}\n\n\tfunction buildAddPropertyAction(container, property, path) {\n\t\tfunction onClickAddProperty(property, path, event) {\n\t\t\tevent.preventDefault();\n\t\t\tconst create = Property.getContainerCreateMethod(property, this);\n\t\t\tif (create) {\n\t\t\t\tcreate(path, property);\n\t\t\t} else {\n\t\t\t\tconst name = path.join('.');\n\t\t\t\tconst value = Property.createModelInstance(property);\n\t\t\t\tutils.assignPathValue(this.model, name, value);\n\t\t\t}\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());\n\t\t}\n\t\treturn (\n\t\t\t<div className=\"actions\">\n\t\t\t\t<button className=\"-add-property\" onClick={onClickAddProperty.bind(container, property, path)}>Add</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tfunction buildRemovePropertyAction(container, property, path) {\n\t\tfunction onClickRemoveProperty(property, path, event) {\n\t\t\tevent.preventDefault();\n\t\t\tconst name = path.join('.');\n\t\t\tconst removeMethod = Property.getContainerMethod(property, this, 'remove');\n\t\t\tif (removeMethod) {\n\t\t\t\tremoveMethod(utils.resolvePath(this.model, name));\n\t\t\t} else {\n\t\t\t\tutils.removePathValue(this.model, name);\n\t\t\t}\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());\n\t\t}\n\t\treturn (\n\t\t\t<div className=\"actions\">\n\t\t\t\t<Button className=\"-remove-property\" title=\"Remove\" onClick={onClickRemoveProperty.bind(container, property, path)} src={imgRemove}/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tfunction onFormFieldValueChanged(event) {\n\t\tif (this instanceof DescriptorModel) {\n\t\t\tevent.preventDefault();\n\t\t\tconst name = event.target.name;\n\t\t\tconst value = event.target.value;\n\t\t\tutils.assignPathValue(this.model, name, value);\n\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());\n\t\t}\n\t}\n\n\tfunction buildField(container, property, path, value, fieldKey) {\n\n\t\tconst name = path.join('.');\n\t\tconst isEditable = true;\n\t\tconst onChange = onFormFieldValueChanged.bind(container);\n\t\tconst isEnumeration = Property.isEnumeration(property);\n\t\tconst onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);\n\t\tif (isEnumeration) {\n\t\t\tconst enumeration = Property.getEnumeration(property, value);\n\t\t\tconst options = enumeration.map((d, i) => {\n\t\t\t\t// note yangforge generates values for enums but the system does not use them\n\t\t\t\t// so we categorically ignore them\n\t\t\t\t// https://trello.com/c/uzEwVx6W/230-bug-enum-should-not-use-index-only-name\n\t\t\t\t//return <option key={fieldKey + ':' + i} value={d.value}>{d.name}</option>;\n\t\t\t\treturn <option key={fieldKey + ':' + i} value={d.name}>{d.name}</option>;\n\t\t\t});\n\t\t\tconst isValueSet = enumeration.filter(d => d.isSelected).length > 0;\n\t\t\tif (!isValueSet || property.cardinality === '0..1') {\n\t\t\t\tconst noValueDisplayText = '';\n\t\t\t\toptions.unshift(<option key={'(value-not-in-enum)' + fieldKey} value=\"\">{noValueDisplayText}</option>);\n\t\t\t}\n\t\t\treturn <select key={fieldKey} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={SelectionManager.resume} onMouseLeave={SelectionManager.resume} readOnly={!isEditable}>{options}</select>;\n\t\t}\n\n\t\tif (property['preserve-line-breaks']) {\n\t\t\treturn <textarea key={fieldKey} name={name} value={value} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!isEditable} />;\n\t\t}\n\n\t\treturn <input key={fieldKey} type=\"text\" name={name} value={value} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!isEditable}/>;\n\n\t}\n\n\tfunction buildElement(container, property, valuePath, value) {\n\t\treturn property.properties.map((property, index) => {\n\t\t\tlet childValue;\n\t\t\tconst childPath = valuePath.slice();\n\t\t\tif (typeof value === 'object') {\n\t\t\t\tchildValue = value[property.name];\n\t\t\t}\n\t\t\tchildPath.push(property.name);\n\n\t\t\treturn build(container, property, childPath, childValue);\n\n\t\t});\n\t}\n\n\tfunction buildChoice(container, property, path, value, key) {\n\n\t\tfunction onFormFieldValueChanged(event) {\n\t\t\tif (this instanceof DescriptorModel) {\n\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tconst name = event.target.name;\n\t\t\t\tconst value = event.target.value;\n\n\t\t\t\t/*\n\t\t\t\t\tTransient State is stored for convenience in the meta field.\n\t\t\t\t\tThe choice yang type uses case elements to describe the \"options\".\n\t\t\t\t\tA choice can only ever have one option selected which allows\n\t\t\t\t\tthe system to determine which type is selected by the name of\n\t\t\t\t\tthe element contained within the field.\n\t\t\t\t */\n\n\t\t\t\t//const stateExample = {\n\t\t\t\t//\tmeta: {\n\t\t\t\t//\t\tchoice: {\n\t\t\t\t//\t\t\t'conf-config': {\n\t\t\t\t//\t\t\t\tselected: 'rest',\n\t\t\t\t//\t\t\t\t'case': {\n\t\t\t\t//\t\t\t\t\trest: {},\n\t\t\t\t//\t\t\t\t\tnetconf: {},\n\t\t\t\t//\t\t\t\t\tscript: {}\n\t\t\t\t//\t\t\t\t}\n\t\t\t\t//\t\t\t}\n\t\t\t\t//\t\t}\n\t\t\t\t//\t}\n\t\t\t\t//};\n\n\t\t\t\tconst statePath = ['meta.choice'].concat(name);\n\t\t\t\tconst stateObject = utils.resolvePath(this.model, statePath.join('.')) || {};\n\t\t\t\t// write state back to the model so the new state objects are captured\n\t\t\t\tutils.assignPathValue(this.model, statePath.join('.'), stateObject);\n\n\t\t\t\t// write the current choice value into the state\n\t\t\t\tconst choiceObject = utils.resolvePath(this.model, [name, stateObject.selected].join('.'));\n\t\t\t\tif (choiceObject) {\n\t\t\t\t\tutils.assignPathValue(stateObject, ['case', stateObject.selected].join('.'), _.cloneDeep(choiceObject));\n\t\t\t\t}\n\n\t\t\t\t// remove the current choice value from the model\n\t\t\t\tutils.removePathValue(this.model, [name, stateObject.selected].join('.'));\n\n\t\t\t\t// get any state for the new selected choice\n\t\t\t\tconst newChoiceObject = utils.resolvePath(stateObject, ['case', value].join('.')) || {};\n\n\t\t\t\t// assign new choice value to the model\n\t\t\t\tutils.assignPathValue(this.model, [name, value].join('.'), newChoiceObject);\n\n\t\t\t\t// update the selected name\n\t\t\t\tutils.assignPathValue(this.model, statePath.concat('selected').join('.'), value);\n\n\t\t\t\tCatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());\n\t\t\t}\n\t\t}\n\n\t\tconst caseByNameMap = {};\n\n\t\tconst onChange = onFormFieldValueChanged.bind(container);\n\n\t\tconst cases = property.properties.map(d => {\n\t\t\tif (d.type === 'case') {\n\t\t\t\tcaseByNameMap[d.name] = d.properties[0];\n\t\t\t\treturn {optionName: d.name, optionTitle: d.description};\n\t\t\t}\n\t\t\tcaseByNameMap[d.name] = d;\n\t\t\treturn {optionName: d.name};\n\t\t});\n\n\t\tconst options = [{/*create a blank option*/}].concat(cases).map((d, i) => {\n\t\t\treturn (\n\t\t\t\t<option key={i} value={d.optionName} title={d.optionTitle}>{d.optionName}</option>\n\t\t\t);\n\t\t});\n\n\t\tconst selectName = path.join('.');\n\t\tconst selectedOptionPath = ['meta.choice', selectName, 'selected'].join('.');\n\t\tconst selectedOptionValue = utils.resolvePath(container.model, selectedOptionPath);\n\t\tconst valueProperty = caseByNameMap[selectedOptionValue] || {properties: []};\n\n\t\tconst valueResponse = valueProperty.properties.map((d, i) => {\n\t\t\tconst childPath = path.concat(valueProperty.name, d.name);\n\t\t\tconst childValue = utils.resolvePath(container.model, childPath.join('.'));\n\t\t\treturn (\n\t\t\t\t<div key={childPath.concat('index', i).join(':')}>\n\t\t\t\t\t{build(container, d, childPath, childValue, props)}\n\t\t\t\t</div>\n\t\t\t);\n\t\t});\n\n\t\tconst onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);\n\n\t\treturn (\n\t\t\t<div key={key} className=\"choice\">\n\t\t\t\t<select key={Date.now()} name={selectName} value={selectedOptionValue} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing}>\n\t\t\t\t\t{options}\n\t\t\t\t</select>\n\t\t\t\t{valueResponse}\n\t\t\t</div>\n\t\t);\n\n\t}\n\n\tfunction buildListItem(container, property, path, value, key) {\n\t\tfunction onClickSelectItem(property, path, value, event) {\n\t\t\tevent.preventDefault();\n\t\t\tconst root = this.getRoot();\n\t\t\tif (SelectionManager.select(value)) {\n\t\t\t\tCatalogItemsActions.catalogItemMetaDataChanged(root.model);\n\t\t\t}\n\t\t\tComposerAppActions.outlineModel(value);\n\t\t}\n\t\t// todo need to abstract this better\n\t\tconst title = value && (value.name || (value.meta && value.meta.displayName));\n\t\treturn (\n\t\t\t<div key={Date.now()} className=\"simple-list-item\" onClick={onClickSelectItem.bind(container, property, path, value)}>{title}</div>\n\t\t);\n\t}\n\n\tfunction build(container, property, path, value, props = {}) {\n\n\t\tconst fields = [];\n\t\tconst isLeaf = Property.isLeaf(property);\n\t\tconst isArray = Property.isArray(property);\n\t\tconst isObject = Property.isObject(property);\n\t\tconst fieldKey = [container.id].concat(path);\n\t\tconst isRequired = Property.isRequired(property);\n\t\tconst title = changeCase.titleCase(property.name);\n\t\tconst columnCount = property.properties.length || 1;\n\t\tconst isColumnar = isArray && (Math.round(props.width / columnCount) > 155);\n\t\tconst classNames = {'-is-required': isRequired, '-is-columnar': isColumnar};\n\n\t\tif (!property.properties && isObject) {\n\t\t\tconst meta = DescriptorModelMetaFactory.getModelMetaForType(property.name) || {};\n\t\t\tproperty.properties = meta.properties;\n\t\t}\n\n\t\tconst hasProperties = _.isArray(property.properties) && property.properties.length;\n\t\tconst isMissingDescriptorMeta = !hasProperties && property.type !== 'leaf';\n\n\t\t// ensure value is not undefined for non-leaf property types\n\t\tif (isObject) {\n\t\t\tif (typeof value !== 'object') {\n\t\t\t\tvalue = isArray ? [] : {};\n\t\t\t}\n\t\t}\n\t\tconst valueAsArray = _.isArray(value) ? value : [value];\n\t\tconst titleInfo = isArray ? valueAsArray.filter(d => d).length + ' items' : '';\n\n\t\tconst isCVNFD = property.name === 'constituent-vnfd';\n\t\tconst isSimpleListView = Property.isSimpleList(property);\n\t\tconst showAddAction = isArray && !isSimpleListView;\n\n\t\tvalueAsArray.forEach((value, index) => {\n\n\t\t\tlet field;\n\t\t\tconst valuePath = path.slice();\n\t\t\tconst key = fieldKey.concat([index]).join(':');\n\n\t\t\tif (isArray) {\n\t\t\t\tvaluePath.push(index);\n\t\t\t}\n\n\t\t\tif (isMissingDescriptorMeta) {\n\t\t\t\tfield = <small key={fieldKey.concat('warning', index).join(':')} className=\"warning\">No Descriptor Meta for {property.name}</small>;\n\t\t\t} else if (property.type === 'choice') {\n\t\t\t\tfield = buildChoice(container, property, valuePath, value, key);\n\t\t\t} else if (isSimpleListView) {\n\t\t\t\tfield = buildListItem(container, property, valuePath, value, key);\n\t\t\t} else {\n\t\t\t\tfield = hasProperties ?\n\t\t\t\t\tbuildElement(container, property, valuePath, value, key) :\n\t\t\t\t\tbuildField(container, property, valuePath, value, key);\n\t\t\t}\n\n\t\t\tfunction onClickLeaf(property, path, value, event) {\n\t\t\t\tif (event.isDefaultPrevented()) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tthis.getRoot().meta.focusedPropertyPath = path.join('.');\n\t\t\t\tconsole.log('property selected', path.join('.'));\n\t\t\t\tComposerAppActions.propertySelected([path.join('.')]);\n\t\t\t}\n\n\t\t\tconst clickHandler = isLeaf ? onClickLeaf : () => {};\n\n\t\t\tfields.push(\n\t\t\t\t<div key={fieldKey.concat(['property-group', index]).join(':')} onClick={clickHandler.bind(container, property, valuePath, value)} className={ClassNames('property-group', {'simple-list': isSimpleListView})}>\n\t\t\t\t\t{field}\n\t\t\t\t\t{isArray ? buildRemovePropertyAction(container, property, valuePath, fieldKey.concat([index]).join(':')) : null}\n\t\t\t\t</div>\n\t\t\t);\n\n\t\t});\n\n\t\tclassNames['col-' + columnCount] = isColumnar;\n\n\t\tif (property.type === 'choice') {\n\t\t\tvalue = utils.resolvePath(container.model, ['meta.choice'].concat(path, 'selected').join('.'));\n\t\t}\n\n\t\tconst isToggled = false;\n\n\t\treturn (\n\t\t\t<div key={fieldKey.join(':')} className={ClassNames(property.type, classNames)}>\n\t\t\t\t<h2 className={ClassNames('label', {'-is-toggled': isToggled})} data-toggle={isToggled ? 'true' : 'false'} onClick={toggle}>\n\t\t\t\t\t{title}\n\t\t\t\t\t<small className=\"info\">{titleInfo}</small>\n\t\t\t\t\t{isLeaf ? <small className=\"value\">{value}</small> : null}\n\t\t\t\t</h2>\n\t\t\t\t<div className=\"toggleable\">\n\t\t\t\t\t<span className=\"description\">{property.description}</span>\n\t\t\t\t\t{isCVNFD ? <small>Drag a VNFD from the Catalog to add more.</small> : null}\n\t\t\t\t\t{showAddAction ? buildAddPropertyAction(container, property, path.concat(valueAsArray.length)) : null}\n\t\t\t\t\t{fields}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\n\t}\n\n\tconst containerType = container.meta['qualified-type'] || container.meta.type;\n\tconst basicProperties = getDescriptorMetaBasicForType(containerType).properties;\n\n\tfunction buildBasicGroup() {\n\t\tif (basicProperties.length === 0) {\n\t\t\treturn null;\n\t\t}\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t<h1 data-toggle=\"false\" onClick={toggle}>Basic</h1>\n\t\t\t\t<div className=\"basic-properties-group toggleable\">\n\t\t\t\t\t{basicProperties.map(property => {\n\t\t\t\t\t\tconst path = [property.name];\n\t\t\t\t\t\tconst value = container.model[property.name];\n\t\t\t\t\t\treturn build(container, property, path, value);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tfunction buildAdvancedGroup() {\n\t\tconst properties = getDescriptorMetaAdvancedForType(containerType).properties;\n\t\tif (properties.length === 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst closeGroup = basicProperties.length > 0;\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t<h1 data-toggle={closeGroup} className={ClassNames({'-is-toggled': closeGroup})} onClick={toggle}>Advanced</h1>\n\t\t\t\t<div className=\"advanced-properties-group toggleable\">\n\t\t\t\t\t{properties.map(property => {\n\t\t\t\t\t\tconst path = [property.name];\n\t\t\t\t\t\tconst value = container.model[property.name];\n\t\t\t\t\t\treturn build(container, property, path, value, {toggle: true, width: props.width});\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"DescriptorModelFormEditor\">\n\t\t\t<h1><small>{container.title}</small></h1>\n\t\t\t{buildBasicGroup()}\n\t\t\t{buildAdvancedGroup()}\n\t\t</div>\n\t);\n\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/model/DescriptorModelFormEditor.js\n **/","/**\n * Created by onvelocity on 1/28/16.\n *\n * This function expects a React SyntheticEvent e.g. onClick and toggles the data-toggle element and adds the class '-is-toggled'.\n *\n * <h1 data-toggle=\"false\" onClick={toggle}>Basic</h1>\n + <div className=\"toggleable\">more info here</div>\n */\n\n'use strict';\n\nimport getEventPath from './getEventPath'\n\nimport '../styles/ToggleElement.scss'\n\n\nexport default function toggle(event) {\n\tconst target = getEventPath(event).reduce((r, node) => {\n\t\tif (r) {\n\t\t\treturn r;\n\t\t}\n\t\tif (node && node.dataset && node.dataset.hasOwnProperty('toggle')) {\n\t\t\treturn node;\n\t\t}\n\t}, false);\n\tif (target) {\n\t\tconst value = String(target.dataset.toggle) !== 'true';\n\t\ttarget.dataset.toggle = value;\n\t\ttarget.classList.toggle('-is-toggled', value);\n\t}\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/ToggleElementHandler.js\n **/","/**\n * Created by onvelocity on 2/3/16.\n */\n'use strict';\nexport default function getEventPath(event) {\n\tif (event.path) {\n\t\treturn event.path;\n\t}\n\tif (event.nativeEvent && event.nativeEvent.path) {\n\t\treturn event.nativeEvent.path;\n\t}\n\t// for browsers, like IE, that don't have event.path\n\tlet node = event.target;\n\tconst path = [];\n\t// Array.unshift means put the value on the top of the array\n\tconst addToPath = (value) => path.unshift(value);\n\t// warn: some browsers set the root's parent to itself\n\twhile (node && node !== node.parent) {\n\t\taddToPath(node);\n\t\tnode = node.parentNode;\n\t}\n\treturn path;\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/libraries/getEventPath.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ToggleElement.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ToggleElement.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ToggleElement.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/ToggleElement.scss\n ** module id = 687\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/* simple toggle behavior (requires js to change data-toggle value to 'true' or add class '-is-toggled' */\\n[data-toggle] {\\n  position: relative;\\n}\\n\\n[data-toggle]:before {\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n  bottom: 0;\\n  width: 20px;\\n  content: '-';\\n  text-align: left;\\n}\\n\\n[data-toggle=\\\"true\\\"] + .toggleable,\\n[data-toggle].-is-toggled + .toggleable {\\n  display: none !important;\\n}\\n\\n[data-toggle=\\\"true\\\"]:before,\\n[data-toggle].-is-toggled:before {\\n  content: '+';\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/ToggleElement.scss\n ** module id = 688\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItemDetailsEditor.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItemDetailsEditor.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./CatalogItemDetailsEditor.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/CatalogItemDetailsEditor.scss\n ** module id = 689\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.CatalogItemDetailsEditor {\\n  border: 1px solid transparent;\\n  transform: translate3d(0, 0, 0);\\n  height: 100%;\\n}\\n\\n.CatalogItemDetailsEditor div,\\n.CatalogItemDetailsEditor label {\\n  display: block;\\n  position: relative;\\n  margin: 8px 4px 16px 4px;\\n  border: none;\\n  border-radius: 1px;\\n  line-height: 16px;\\n}\\n\\n.CatalogItemDetailsEditor div div,\\n.CatalogItemDetailsEditor label div {\\n  margin: 0px;\\n}\\n\\n.CatalogItemDetailsEditor div .label,\\n.CatalogItemDetailsEditor label .label {\\n  display: block;\\n  width: 100%;\\n  white-space: nowrap;\\n  padding: 0 0 0 14px;\\n  text-align: left;\\n  color: #aeaeae;\\n  font-size: 12px;\\n  font-style: normal;\\n  line-height: 16px;\\n  text-transform: uppercase;\\n  position: relative;\\n  white-space: nowrap;\\n  overflow: hidden;\\n  text-overflow: ellipsis;\\n}\\n\\n.CatalogItemDetailsEditor div .label small,\\n.CatalogItemDetailsEditor label .label small {\\n  margin-left: 4px;\\n}\\n\\n.CatalogItemDetailsEditor div .label small.value,\\n.CatalogItemDetailsEditor label .label small.value {\\n  text-transform: none;\\n}\\n\\n.CatalogItemDetailsEditor div .description,\\n.CatalogItemDetailsEditor label .description {\\n  display: none;\\n  font-size: xx-small;\\n  padding: 0 0 0 8px;\\n  color: rgba(35, 16, 16, 0.67);\\n}\\n\\n.CatalogItemDetailsEditor div.-is-required:before,\\n.CatalogItemDetailsEditor label.-is-required:before {\\n  content: \\\"*\\\";\\n  padding: 4px;\\n  font-size: x-small;\\n  color: rgba(255, 95, 95, 0.75);\\n}\\n\\n.CatalogItemDetailsEditor div.property-group .property-group,\\n.CatalogItemDetailsEditor label.property-group .property-group {\\n  border: none;\\n}\\n\\n.CatalogItemDetailsEditor div.property-group .property-group div,\\n.CatalogItemDetailsEditor div.property-group .property-group label,\\n.CatalogItemDetailsEditor label.property-group .property-group div, .CatalogItemDetailsEditor label.property-group .property-group label {\\n  margin-left: 0px;\\n}\\n\\n.CatalogItemDetailsEditor div small.warning,\\n.CatalogItemDetailsEditor label small.warning {\\n  font-size: xx-small;\\n}\\n\\n.CatalogItemDetailsEditor input,\\n.CatalogItemDetailsEditor select,\\n.CatalogItemDetailsEditor textarea {\\n  appearance: none;\\n  -webkit-appearance: none;\\n  -moz-appearance: none;\\n  width: 100%;\\n  border: 1px solid rgba(220, 220, 220, 0.5);\\n  border-radius: 4px;\\n  padding: 10px 8px;\\n  font-weight: 400;\\n  font-size: 14px;\\n  background-color: white;\\n}\\n\\n.CatalogItemDetailsEditor input::-webkit-input-placeholder,\\n.CatalogItemDetailsEditor select::-webkit-input-placeholder,\\n.CatalogItemDetailsEditor textarea::-webkit-input-placeholder {\\n  color: #bfbfbf;\\n  font-size: 11px;\\n}\\n\\n.CatalogItemDetailsEditor input:-moz-placeholder,\\n.CatalogItemDetailsEditor select:-moz-placeholder,\\n.CatalogItemDetailsEditor textarea:-moz-placeholder {\\n  /* Firefox 18- */\\n  color: #bfbfbf;\\n  font-size: 11px;\\n}\\n\\n.CatalogItemDetailsEditor input::-moz-placeholder,\\n.CatalogItemDetailsEditor select::-moz-placeholder,\\n.CatalogItemDetailsEditor textarea::-moz-placeholder {\\n  /* Firefox 19+ */\\n  color: #bfbfbf;\\n  font-size: 11px;\\n}\\n\\n.CatalogItemDetailsEditor input:-ms-input-placeholder,\\n.CatalogItemDetailsEditor select:-ms-input-placeholder,\\n.CatalogItemDetailsEditor textarea:-ms-input-placeholder {\\n  color: #bfbfbf;\\n  font-size: 11px;\\n}\\n\\n.CatalogItemDetailsEditor input[readonly],\\n.CatalogItemDetailsEditor select[readonly],\\n.CatalogItemDetailsEditor textarea[readonly] {\\n  background-color: rgba(255, 255, 255, 0.25);\\n}\\n\\n.CatalogItemDetailsEditor select {\\n  background: white url(\" + require(\"../images/arrow614.svg\") + \") 96% center no-repeat;\\n  background-size: 10px;\\n}\\n\\n.CatalogItemDetailsEditor .basic-properties-group {\\n  padding-bottom: 8px;\\n}\\n\\n.CatalogItemDetailsEditor [data-toggle] {\\n  cursor: pointer;\\n}\\n\\n.CatalogItemDetailsEditor [data-toggle] small.value {\\n  visibility: hidden;\\n}\\n\\n.CatalogItemDetailsEditor [data-toggle].-is-toggled small.value {\\n  visibility: visible;\\n}\\n\\n.CatalogItemDetailsEditor h1[data-toggle] {\\n  border-top: 1px solid silver;\\n  border-top-left-radius: 5px;\\n  border-top-right-radius: 5px;\\n}\\n\\n.CatalogItemDetailsEditor h1[data-toggle]:before {\\n  border-top-left-radius: 4px;\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group:nth-child(odd) {\\n  border-left: 2px solid #5b5b5b;\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group:nth-child(odd).simple-list {\\n  border-left-color: transparent;\\n  background-color: rgba(255, 248, 220, 0.33);\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group:nth-child(even) {\\n  border-left: 2px solid #ffffff;\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group:nth-child(even).simple-list {\\n  border-left-color: transparent;\\n  background-color: rgba(248, 248, 255, 0.33);\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group.simple-list {\\n  margin: 4px;\\n  position: relative;\\n  cursor: pointer;\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group.simple-list > div {\\n  display: inline-block;\\n  margin: 14px 5px 14px 14px;\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group.simple-list .actions {\\n  position: absolute;\\n  top: 4px;\\n  right: 0;\\n  margin: 0;\\n}\\n\\n.CatalogItemDetailsEditor .list > div > .property-group.simple-list .actions .Button img {\\n  width: 15px;\\n  margin: 5px;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/CatalogItemDetailsEditor.scss\n ** module id = 690\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"ac9f1709c8d88fe5339eddd1d6829cd3.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/arrow614.svg\n ** module id = 691\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DetailsPanel.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DetailsPanel.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./DetailsPanel.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/DetailsPanel.scss\n ** module id = 692\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@charset \\\"UTF-8\\\";\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Thin-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-ThinItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Medium-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-MediumItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Black-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BlackItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\nhtml, body {\\n  background: #f1f1f1;\\n  cursor: auto;\\n  font-family: Roboto, Helvetica, Arial, sans-serif;\\n  overflow: hidden;\\n}\\n\\n::-webkit-scrollbar {\\n  display: none;\\n}\\n\\nhtml {\\n  -webkit-box-sizing: border-box;\\n  -moz-box-sizing: border-box;\\n  box-sizing: border-box;\\n}\\n\\n* {\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n  border-collapse: collapse;\\n}\\n\\n*, *:before, *:after {\\n  -webkit-box-sizing: inherit;\\n  -moz-box-sizing: inherit;\\n  box-sizing: inherit;\\n}\\n\\nh1 {\\n  margin: 0;\\n  padding: 3px 6px;\\n  color: #323232;\\n  font-size: 0.75em;\\n  font-weight: normal;\\n  text-align: center;\\n  font-variant-caps: all-small-caps;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n}\\n\\nbutton,\\ninput[type=\\\"image\\\"] {\\n  /*font-variant: small-caps;\\n\\ttext-transform: lowercase;\\n\\ttext-align: center;\\n\\tmargin: 4px 0;\\n\\tborder-radius: 0;\\n\\tborder-collapse: collapse;\\n\\tpadding: 2px 24px;\\n\\toutline: none;\\n\\tbackground-color: transparent;*/\\n  box-shadow: 2px 2px rgba(0, 0, 0, 0.15);\\n  color: #000000;\\n  display: inline-block;\\n  font-size: 12px;\\n  padding: 8px 34px;\\n  text-decoration: none;\\n  text-transform: uppercase;\\n}\\n\\nbutton:hover,\\ninput[type=\\\"image\\\"]:hover {\\n  background-color: #7E9BC1;\\n  color: #ffffff;\\n}\\n\\nbutton:active,\\nbutton:visited,\\ninput[type=\\\"image\\\"]:active, input[type=\\\"image\\\"]:visited {\\n  background-color: #4C5E74;\\n  color: #ffffff;\\n}\\n\\nbutton.-selected,\\ninput[type=\\\"image\\\"].-selected {\\n  background-color: #9fc4f4;\\n}\\n\\ninput[type=\\\"image\\\"] {\\n  width: 28px;\\n  height: 28px;\\n  margin-right: 12px;\\n  border: 0;\\n  border-radius: 4px;\\n  padding: 4px;\\n}\\n\\n.btn-group {\\n  white-space: nowrap;\\n}\\n\\n.btn-group button {\\n  border-right: 1px solid rgba(169, 169, 169, 0.5);\\n}\\n\\n.btn-group button:first-of-type {\\n  border-top-left-radius: 2px;\\n  border-bottom-left-radius: 2px;\\n}\\n\\n.btn-group button:last-of-type {\\n  border-right: none;\\n  border-top-right-radius: 2px;\\n  border-bottom-right-radius: 2px;\\n}\\n\\n.panel, .DetailsPanel {\\n  overflow: hidden;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  background-color: #e5e5e5;\\n}\\n\\n.panel > div, .DetailsPanel > div {\\n  min-width: 200px;\\n}\\n\\n.panel-header {\\n  /*position: absolute;\\n\\ttop: 0;\\n\\tleft: 0;\\n\\tright: 0;\\n\\theight: 50px;\\n\\tpadding: 8px;\\n\\tbackground-color: $panel-bg-color-contrast;\\n\\tborder-bottom: 1px solid $panel-border-color-light;\\n\\twhite-space: nowrap;*/\\n}\\n\\n.panel-header h1 {\\n  padding: 16px;\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.panel-body, .DetailsPanel .DetailsPanelBody {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  top: 111px;\\n  bottom: 0px;\\n  left: 0;\\n  right: 0;\\n}\\n\\n.panel-footer {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 40px;\\n  padding: 0 12px;\\n  background-color: #cbd1d1;\\n  border-top: 1px solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n}\\n\\n.welcome-message {\\n  margin: 20px;\\n  color: #06173c;\\n  font-size: x-large;\\n  font-weight: 200;\\n}\\n\\n.welcome-message .Button {\\n  display: inline-block;\\n}\\n\\n/* react-tooltip overrides */\\n.__react_component_tooltip {\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !important;\\n}\\n\\n/* simple css-only drop-down menu */\\n.menu {\\n  display: inline-flex;\\n  position: relative;\\n  z-index: 2;\\n}\\n\\n.menu > .Button:after {\\n  content: \\\"\\\\2C7\\\";\\n  position: absolute;\\n  right: 4px;\\n  bottom: -13px;\\n  font-size: 20px;\\n}\\n\\n.menu .sub-menu {\\n  display: none;\\n  position: absolute;\\n  top: 36px;\\n  left: -4px;\\n  padding: 4px;\\n  background-color: #f1f1f1;\\n  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\\n  border-radius: 3px;\\n}\\n\\n.menu .sub-menu .Button {\\n  display: block;\\n  text-align: left;\\n}\\n\\n.menu .sub-menu:hover {\\n  display: block;\\n}\\n\\n.menu > .Button:hover .sub-menu {\\n  display: block;\\n}\\n\\n.menu:hover .sub-menu {\\n  display: block;\\n}\\n\\n.descriptor text.badge {\\n  font-weight: 100;\\n  font-size: 12px;\\n  text-anchor: middle;\\n  fill: white;\\n  /* font color */\\n  stroke: white !important;\\n  /* font color */\\n}\\n\\ninput:focus {\\n  color: white;\\n  background: #000 !important;\\n}\\n\\n.hint {\\n  margin: 5px;\\n}\\n\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n.DetailsPanel {\\n  border-left: 1px solid rgba(143, 143, 143, 0.5);\\n  position: absolute;\\n  top: 109px;\\n  right: 0;\\n  bottom: 0;\\n  width: 300px;\\n  min-width: 6px;\\n  z-index: 2;\\n}\\n\\n.DetailsPanel .DetailsPanelBody {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  bottom: 0;\\n  top: 0;\\n  left: 0;\\n  right: 0;\\n  min-width: 200px;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/DetailsPanel.scss\n ** module id = 693\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/14/15.\n */\n'use strict';\n\nimport React from 'react'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport ClassNames from 'classnames'\n\nimport ModalOverlayStore from '../stores/ModalOverlayStore'\n\nimport '../styles/ModalOverlay.scss'\n\nconst ModalOverlay = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn ModalOverlayStore.getState();\n\t},\n\tgetDefaultProps() {\n\t},\n\tcomponentWillMount() {\n\t\tModalOverlayStore.listen(this.onChange);\n\t},\n\tcomponentDidMount() {\n\t\twindow.addEventListener('resize', this.onResizeCapture, true);\n\t\twindow.addEventListener('mousemove', this.onMouseMoveCapture, true);\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t\tModalOverlayStore.unlisten(this.onChange);\n\t\twindow.removeEventListener('resize', this.onResize, true);\n\t\twindow.removeEventListener('mousemove', this.onMouseMoveCapture, true);\n\t},\n\tonChange(state) {\n\t\tthis.setState(state);\n\t},\n\tonResizeCapture(event) {\n\t\tif (event.detail && event.detail.side) {\n\t\t\tif (this.state.visible) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t}\n\t},\n\tonMouseMoveCapture(event) {\n\t\tif (this.state.visible) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t},\n\trender() {\n\t\tconst className = ClassNames('ModalOverlay', {'-is-visible': this.state.visible});\n\t\treturn (\n\t\t\t<div className={className}>\n\t\t\t\t<div className=\"background\" onMouseMoveCapture={this.onMouseMoveCapture}></div>\n\t\t\t\t{this.state.ui ? <div className=\"foreground\" onMouseMoveCapture={this.onMouseMoveCapture}><div className=\"ui\">{this.state.ui}</div></div> : null}\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default ModalOverlay;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/ModalOverlay.js\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n/**\n * Created by onvelocity on 10/14/15.\n */\n'use strict';\n\nimport alt from '../alt'\nimport React from 'react'\nimport ModalOverlayActions from '../actions/ModalOverlayActions'\nimport LoadingIndicator from '../components/LoadingIndicator'\n\nclass ModalOverlayStore {\n\n\tconstructor() {\n\t\tthis.ui = <LoadingIndicator/>;\n\t\tthis.visible = false;\n\t\tthis.bindActions(ModalOverlayActions);\n\t}\n\n\tshowModalOverlay(ui = <LoadingIndicator/>) {\n\t\tthis.setState({visible: true, ui: ui});\n\t}\n\n\thideModalOverlay() {\n\t\tthis.setState({visible: false, ui: null});\n\t}\n\n}\n\nModalOverlayStore.config = {\n\tonSerialize: function() {\n\t\treturn {};\n\t}\n};\n\nexport default alt.createStore(ModalOverlayStore, 'ModalOverlayStore');\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/stores/ModalOverlayStore.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ModalOverlay.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ModalOverlay.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ModalOverlay.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/ModalOverlay.scss\n ** module id = 696\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@charset \\\"UTF-8\\\";\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Thin-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-ThinItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Medium-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-MediumItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Black-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BlackItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\nhtml, body {\\n  background: #f1f1f1;\\n  cursor: auto;\\n  font-family: Roboto, Helvetica, Arial, sans-serif;\\n  overflow: hidden;\\n}\\n\\n::-webkit-scrollbar {\\n  display: none;\\n}\\n\\nhtml {\\n  -webkit-box-sizing: border-box;\\n  -moz-box-sizing: border-box;\\n  box-sizing: border-box;\\n}\\n\\n* {\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n  border-collapse: collapse;\\n}\\n\\n*, *:before, *:after {\\n  -webkit-box-sizing: inherit;\\n  -moz-box-sizing: inherit;\\n  box-sizing: inherit;\\n}\\n\\nh1 {\\n  margin: 0;\\n  padding: 3px 6px;\\n  color: #323232;\\n  font-size: 0.75em;\\n  font-weight: normal;\\n  text-align: center;\\n  font-variant-caps: all-small-caps;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n}\\n\\nbutton,\\ninput[type=\\\"image\\\"] {\\n  /*font-variant: small-caps;\\n\\ttext-transform: lowercase;\\n\\ttext-align: center;\\n\\tmargin: 4px 0;\\n\\tborder-radius: 0;\\n\\tborder-collapse: collapse;\\n\\tpadding: 2px 24px;\\n\\toutline: none;\\n\\tbackground-color: transparent;*/\\n  box-shadow: 2px 2px rgba(0, 0, 0, 0.15);\\n  color: #000000;\\n  display: inline-block;\\n  font-size: 12px;\\n  padding: 8px 34px;\\n  text-decoration: none;\\n  text-transform: uppercase;\\n}\\n\\nbutton:hover,\\ninput[type=\\\"image\\\"]:hover {\\n  background-color: #7E9BC1;\\n  color: #ffffff;\\n}\\n\\nbutton:active,\\nbutton:visited,\\ninput[type=\\\"image\\\"]:active, input[type=\\\"image\\\"]:visited {\\n  background-color: #4C5E74;\\n  color: #ffffff;\\n}\\n\\nbutton.-selected,\\ninput[type=\\\"image\\\"].-selected {\\n  background-color: #9fc4f4;\\n}\\n\\ninput[type=\\\"image\\\"] {\\n  width: 28px;\\n  height: 28px;\\n  margin-right: 12px;\\n  border: 0;\\n  border-radius: 4px;\\n  padding: 4px;\\n}\\n\\n.btn-group {\\n  white-space: nowrap;\\n}\\n\\n.btn-group button {\\n  border-right: 1px solid rgba(169, 169, 169, 0.5);\\n}\\n\\n.btn-group button:first-of-type {\\n  border-top-left-radius: 2px;\\n  border-bottom-left-radius: 2px;\\n}\\n\\n.btn-group button:last-of-type {\\n  border-right: none;\\n  border-top-right-radius: 2px;\\n  border-bottom-right-radius: 2px;\\n}\\n\\n.panel {\\n  overflow: hidden;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  background-color: #e5e5e5;\\n}\\n\\n.panel > div {\\n  min-width: 200px;\\n}\\n\\n.panel-header {\\n  /*position: absolute;\\n\\ttop: 0;\\n\\tleft: 0;\\n\\tright: 0;\\n\\theight: 50px;\\n\\tpadding: 8px;\\n\\tbackground-color: $panel-bg-color-contrast;\\n\\tborder-bottom: 1px solid $panel-border-color-light;\\n\\twhite-space: nowrap;*/\\n}\\n\\n.panel-header h1 {\\n  padding: 16px;\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.panel-body {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  top: 111px;\\n  bottom: 0px;\\n  left: 0;\\n  right: 0;\\n}\\n\\n.panel-footer {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 40px;\\n  padding: 0 12px;\\n  background-color: #cbd1d1;\\n  border-top: 1px solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n}\\n\\n.welcome-message {\\n  margin: 20px;\\n  color: #06173c;\\n  font-size: x-large;\\n  font-weight: 200;\\n}\\n\\n.welcome-message .Button {\\n  display: inline-block;\\n}\\n\\n/* react-tooltip overrides */\\n.__react_component_tooltip {\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !important;\\n}\\n\\n/* simple css-only drop-down menu */\\n.menu {\\n  display: inline-flex;\\n  position: relative;\\n  z-index: 2;\\n}\\n\\n.menu > .Button:after {\\n  content: \\\"\\\\2C7\\\";\\n  position: absolute;\\n  right: 4px;\\n  bottom: -13px;\\n  font-size: 20px;\\n}\\n\\n.menu .sub-menu {\\n  display: none;\\n  position: absolute;\\n  top: 36px;\\n  left: -4px;\\n  padding: 4px;\\n  background-color: #f1f1f1;\\n  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\\n  border-radius: 3px;\\n}\\n\\n.menu .sub-menu .Button {\\n  display: block;\\n  text-align: left;\\n}\\n\\n.menu .sub-menu:hover {\\n  display: block;\\n}\\n\\n.menu > .Button:hover .sub-menu {\\n  display: block;\\n}\\n\\n.menu:hover .sub-menu {\\n  display: block;\\n}\\n\\n.descriptor text.badge {\\n  font-weight: 100;\\n  font-size: 12px;\\n  text-anchor: middle;\\n  fill: white;\\n  /* font color */\\n  stroke: white !important;\\n  /* font color */\\n}\\n\\ninput:focus {\\n  color: white;\\n  background: #000 !important;\\n}\\n\\n.hint {\\n  margin: 5px;\\n}\\n\\n.ModalOverlay {\\n  display: none;\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n  right: 0;\\n  bottom: 0;\\n  background-color: transparent;\\n}\\n\\n.ModalOverlay .panel-body {\\n  position: static;\\n  padding: 1.25em;\\n}\\n\\n.ModalOverlay.-is-visible {\\n  display: block;\\n  z-index: 100;\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n  right: 0;\\n  bottom: 0;\\n}\\n\\n.ModalOverlay .background {\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n  right: 0;\\n  bottom: 0;\\n  background-color: #323232;\\n  opacity: 0.8;\\n  z-index: 0;\\n}\\n\\n.ModalOverlay .foreground {\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n  right: 0;\\n  bottom: 0;\\n  z-index: 1;\\n}\\n\\n.ModalOverlay .foreground .ui {\\n  position: fixed;\\n  top: 50%;\\n  left: 50%;\\n  transform: translate(-50%, -50%);\\n  display: inline-block;\\n  font-size: 1.5em;\\n  border-radius: 8px;\\n}\\n\\n.ModalOverlay .foreground .ui h1 {\\n  background-color: white;\\n}\\n\\n.ModalOverlay .foreground .ui .actions {\\n  position: fixed;\\n  top: 50%;\\n  left: 50%;\\n  transform: translate(-50%, -50%);\\n  display: inline-block;\\n  font-size: 1em;\\n  border-radius: 8px;\\n}\\n\\n.ModalOverlay .foreground .ui .actions .action {\\n  white-space: nowrap;\\n  cursor: pointer;\\n  margin: 12px;\\n}\\n\\n.ModalOverlay .foreground .ui .actions h1 {\\n  background-color: white;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/ModalOverlay.scss\n ** module id = 697\n ** module chunks = 0\n **/","\n/*\n * STANDARD_RIFT_IO_COPYRIGHT\n */\n'use strict';\n\nimport React from 'react'\nimport messages from './messages'\nimport ClassNames from 'classnames'\nimport PureRenderMixin from 'react-addons-pure-render-mixin'\nimport Button from './Button'\nimport CatalogItemsActions from '../actions/CatalogItemsActions'\nimport CanvasEditorActions from '../actions/CanvasEditorActions'\nimport ComposerAppActions from '../actions/ComposerAppActions'\nimport SelectionManager from '../libraries/SelectionManager'\nimport DeletionManager from '../libraries/DeletionManager'\n\nimport '../styles/ComposerAppToolbar.scss'\n\nimport imgSave from '../images/floppy13.svg'\nimport imgCancel from '../images/cross95.svg'\nimport imgLayout from '../images/cascade.svg'\nimport imgVLD from '../images/link56.svg'\nimport imgJSONViewer from '../images/code41.svg'\nimport imgFG from '../images/iconmonstr-infinity-4-icon.svg'\nimport imgDelete from '../images/recycle69.svg'\n\nconst ComposerAppToolbar = React.createClass({\n\tmixins: [PureRenderMixin],\n\tgetInitialState() {\n\t\treturn {};\n\t},\n\tgetDefaultProps() {\n\t\treturn {\n\t\t\tdisabled: true,\n\t\t\tshowMore: false,\n\t\t\tlayout: {left: 300},\n\t\t\tisModified: false,\n\t\t\tisEditingNSD: false,\n\t\t\tisEditingVNFD: false,\n\t\t\tshowJSONViewer: false,\n\t\t\tisNew: false\n\t\t};\n\t},\n\tcomponentWillMount() {\n\t},\n\tcomponentDidMount() {\n\t},\n\tcomponentDidUpdate() {\n\t},\n\tcomponentWillUnmount() {\n\t},\n\tonClickSave() {\n\t\tCatalogItemsActions.saveCatalogItem();\n\t},\n\tonClickCancel() {\n\t\tCatalogItemsActions.cancelCatalogItemChanges();\n\t},\n\tonClickToggleShowMoreInfo() {\n\t\tCanvasEditorActions.toggleShowMoreInfo();\n\t},\n\tonClickAutoLayout() {\n\t\tCanvasEditorActions.applyDefaultLayout();\n\t},\n\tonClickAddVld() {\n\t\tCanvasEditorActions.addVirtualLinkDescriptor();\n\t},\n\tonClickAddVnffg() {\n\t\tCanvasEditorActions.addForwardingGraphDescriptor();\n\t},\n\tonDragStartAddVld(event) {\n\t\tconst data = {type: 'action', action: 'add-vld'};\n\t\tevent.dataTransfer.effectAllowed = 'copy';\n\t\tevent.dataTransfer.setData('text', JSON.stringify(data));\n\t\tComposerAppActions.setDragState(data);\n\t},\n\tonDragStartAddVnffg(event) {\n\t\tconst data = {type: 'action', action: 'add-vnffgd'};\n\t\tevent.dataTransfer.effectAllowed = 'copy';\n\t\tevent.dataTransfer.setData('text', JSON.stringify(data));\n\t\tComposerAppActions.setDragState(data);\n\t},\n\tonClickDeleteSelected(event) {\n\t\tevent.preventDefault();\n\t\tDeletionManager.deleteSelected(event);\n\t},\n\ttoggleJSONViewer(event) {\n\t\tevent.preventDefault();\n\t\tif (this.props.showJSONViewer) {\n\t\t\tComposerAppActions.closeJsonViewer();\n\t\t} else {\n\t\t\tComposerAppActions.closeJsonViewer();\n\t\t\tComposerAppActions.showJsonViewer.defer();\n\t\t}\n\t},\n\trender() {\n\t\tconst style = {left: this.props.layout.left};\n\t\tconst saveClasses = ClassNames('ComposerAppSave', {'primary-action': this.props.isModified || this.props.isNew});\n\t\tconst cancelClasses = ClassNames('ComposerAppCancel', {'secondary-action': this.props.isModified});\n\t\tif (this.props.disabled) {\n\t\t\treturn (\n\t\t\t\t<div className=\"ComposerAppToolbar\" style={style}></div>\n\t\t\t);\n\t\t}\n\t\tconst hasSelection = SelectionManager.getSelections().length > 0;\n\t\treturn (\n\t\t\t<div className=\"ComposerAppToolbar\" style={style}>\n\t\t\t\t{(()=>{\n\t\t\t\t\tif (this.props.isEditingNSD || this.props.isEditingVNFD) {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div className=\"FileActions\">\n\t\t\t\t\t\t\t\t<Button className={saveClasses} onClick={this.onClickSave} label={messages.getSaveActionLabel(this.props.isNew)} src={imgSave} />\n\t\t\t\t\t\t\t\t<Button className={cancelClasses} onClick={this.onClickCancel} label=\"Cancel\" src={imgCancel} />\n\t\t\t\t\t\t\t\t<Button className=\"ComposerAppToggleJSONViewerAction\" onClick={this.toggleJSONViewer} onMouseDown={() => SelectionManager.pause()} onMouseOver={() => SelectionManager.pause()} onMouseOut={() => SelectionManager.resume()} onMouseLeave={() => SelectionManager.resume()} label=\"JSON Viewer\" src={imgJSONViewer} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t})()}\n\t\t\t\t<div className=\"LayoutActions\">\n\t\t\t\t\t<Button className=\"action-auto-layout\" onClick={this.onClickAutoLayout} label=\"Auto Layout\" src={imgLayout} />\n\t\t\t\t\t{this.props.isEditingNSD ? <Button className=\"action-add-vld\" draggable=\"true\" onDragStart={this.onDragStartAddVld} onClick={this.onClickAddVld} label=\"Add VLD\" src={imgVLD} /> : null}\n\t\t\t\t\t{this.props.isEditingNSD ? <Button className=\"action-add-vnffg\" draggable=\"true\" onDragStart={this.onDragStartAddVnffg} onClick={this.onClickAddVnffg} label=\"Add VNFFG\" src={imgFG} /> : null}\n\t\t\t\t\t<Button type=\"image\" title=\"Delete selected items\" className=\"action-delete-selected-items\" disabled={!hasSelection} onClick = {this.onClickDeleteSelected} src={imgDelete} label=\"Delete\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default ComposerAppToolbar;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/components/ComposerAppToolbar.js\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ComposerAppToolbar.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ComposerAppToolbar.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./ComposerAppToolbar.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/ComposerAppToolbar.scss\n ** module id = 699\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@charset \\\"UTF-8\\\";\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Thin-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-ThinItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Medium-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-MediumItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Black-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BlackItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\nhtml, body {\\n  background: #f1f1f1;\\n  cursor: auto;\\n  font-family: Roboto, Helvetica, Arial, sans-serif;\\n  overflow: hidden;\\n}\\n\\n::-webkit-scrollbar {\\n  display: none;\\n}\\n\\nhtml {\\n  -webkit-box-sizing: border-box;\\n  -moz-box-sizing: border-box;\\n  box-sizing: border-box;\\n}\\n\\n* {\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n  border-collapse: collapse;\\n}\\n\\n*, *:before, *:after {\\n  -webkit-box-sizing: inherit;\\n  -moz-box-sizing: inherit;\\n  box-sizing: inherit;\\n}\\n\\nh1 {\\n  margin: 0;\\n  padding: 3px 6px;\\n  color: #323232;\\n  font-size: 0.75em;\\n  font-weight: normal;\\n  text-align: center;\\n  font-variant-caps: all-small-caps;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n}\\n\\nbutton,\\ninput[type=\\\"image\\\"] {\\n  /*font-variant: small-caps;\\n\\ttext-transform: lowercase;\\n\\ttext-align: center;\\n\\tmargin: 4px 0;\\n\\tborder-radius: 0;\\n\\tborder-collapse: collapse;\\n\\tpadding: 2px 24px;\\n\\toutline: none;\\n\\tbackground-color: transparent;*/\\n  box-shadow: 2px 2px rgba(0, 0, 0, 0.15);\\n  color: #000000;\\n  display: inline-block;\\n  font-size: 12px;\\n  padding: 8px 34px;\\n  text-decoration: none;\\n  text-transform: uppercase;\\n}\\n\\nbutton:hover,\\ninput[type=\\\"image\\\"]:hover {\\n  background-color: #7E9BC1;\\n  color: #ffffff;\\n}\\n\\nbutton:active,\\nbutton:visited,\\ninput[type=\\\"image\\\"]:active, input[type=\\\"image\\\"]:visited {\\n  background-color: #4C5E74;\\n  color: #ffffff;\\n}\\n\\nbutton.-selected,\\ninput[type=\\\"image\\\"].-selected {\\n  background-color: #9fc4f4;\\n}\\n\\ninput[type=\\\"image\\\"] {\\n  width: 28px;\\n  height: 28px;\\n  margin-right: 12px;\\n  border: 0;\\n  border-radius: 4px;\\n  padding: 4px;\\n}\\n\\n.btn-group {\\n  white-space: nowrap;\\n}\\n\\n.btn-group button {\\n  border-right: 1px solid rgba(169, 169, 169, 0.5);\\n}\\n\\n.btn-group button:first-of-type {\\n  border-top-left-radius: 2px;\\n  border-bottom-left-radius: 2px;\\n}\\n\\n.btn-group button:last-of-type {\\n  border-right: none;\\n  border-top-right-radius: 2px;\\n  border-bottom-right-radius: 2px;\\n}\\n\\n.panel {\\n  overflow: hidden;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  background-color: #e5e5e5;\\n}\\n\\n.panel > div {\\n  min-width: 200px;\\n}\\n\\n.panel-header, .ComposerAppToolbar {\\n  /*position: absolute;\\n\\ttop: 0;\\n\\tleft: 0;\\n\\tright: 0;\\n\\theight: 50px;\\n\\tpadding: 8px;\\n\\tbackground-color: $panel-bg-color-contrast;\\n\\tborder-bottom: 1px solid $panel-border-color-light;\\n\\twhite-space: nowrap;*/\\n}\\n\\n.panel-header h1, .ComposerAppToolbar h1 {\\n  padding: 16px;\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.panel-body {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  top: 111px;\\n  bottom: 0px;\\n  left: 0;\\n  right: 0;\\n}\\n\\n.panel-footer {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 40px;\\n  padding: 0 12px;\\n  background-color: #cbd1d1;\\n  border-top: 1px solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n}\\n\\n.welcome-message {\\n  margin: 20px;\\n  color: #06173c;\\n  font-size: x-large;\\n  font-weight: 200;\\n}\\n\\n.welcome-message .Button {\\n  display: inline-block;\\n}\\n\\n/* react-tooltip overrides */\\n.__react_component_tooltip {\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !important;\\n}\\n\\n/* simple css-only drop-down menu */\\n.menu {\\n  display: inline-flex;\\n  position: relative;\\n  z-index: 2;\\n}\\n\\n.menu > .Button:after {\\n  content: \\\"\\\\2C7\\\";\\n  position: absolute;\\n  right: 4px;\\n  bottom: -13px;\\n  font-size: 20px;\\n}\\n\\n.menu .sub-menu {\\n  display: none;\\n  position: absolute;\\n  top: 36px;\\n  left: -4px;\\n  padding: 4px;\\n  background-color: #f1f1f1;\\n  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\\n  border-radius: 3px;\\n}\\n\\n.menu .sub-menu .Button {\\n  display: block;\\n  text-align: left;\\n}\\n\\n.menu .sub-menu:hover {\\n  display: block;\\n}\\n\\n.menu > .Button:hover .sub-menu {\\n  display: block;\\n}\\n\\n.menu:hover .sub-menu {\\n  display: block;\\n}\\n\\n.descriptor text.badge {\\n  font-weight: 100;\\n  font-size: 12px;\\n  text-anchor: middle;\\n  fill: white;\\n  /* font color */\\n  stroke: white !important;\\n  /* font color */\\n}\\n\\ninput:focus {\\n  color: white;\\n  background: #000 !important;\\n}\\n\\n.hint {\\n  margin: 5px;\\n}\\n\\n.ComposerAppToolbar {\\n  top: 56px;\\n  left: 300px;\\n  right: 0;\\n  height: 55px;\\n  z-index: 4;\\n  position: absolute;\\n  padding: 10px 20px;\\n  background-color: #cbd1d1;\\n  white-space: nowrap;\\n}\\n\\n.ComposerAppToolbar div {\\n  display: inline-block;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/ComposerAppToolbar.scss\n ** module id = 700\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"198052a02c6a3d7cc928e8e325f6fe9e.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/floppy13.svg\n ** module id = 701\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"214ac134993482532f023e62fac056fa.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/cascade.svg\n ** module id = 702\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"5d4493bdaa7c83a657a2b0cc8989f354.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/link56.svg\n ** module id = 703\n ** module chunks = 0\n **/","module.exports = __webpack_public_path__ + \"bab052b7ac94af16f9fb1cd4ecfc7c55.svg\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/images/code41.svg\n ** module id = 704\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../css-loader/index.js!./normalize.css\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../css-loader/index.js!./normalize.css\", function() {\n\t\t\tvar newContent = require(\"!!./../css-loader/index.js!./normalize.css\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/normalize.css/normalize.css\n ** module id = 705\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\\n\\n/**\\n * 1. Set default font family to sans-serif.\\n * 2. Prevent iOS and IE text size adjust after device orientation change,\\n *    without disabling user zoom.\\n */\\n\\nhtml {\\n  font-family: sans-serif; /* 1 */\\n  -ms-text-size-adjust: 100%; /* 2 */\\n  -webkit-text-size-adjust: 100%; /* 2 */\\n}\\n\\n/**\\n * Remove default margin.\\n */\\n\\nbody {\\n  margin: 0;\\n}\\n\\n/* HTML5 display definitions\\n   ========================================================================== */\\n\\n/**\\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\\n * and Firefox.\\n * Correct `block` display not defined for `main` in IE 11.\\n */\\n\\narticle,\\naside,\\ndetails,\\nfigcaption,\\nfigure,\\nfooter,\\nheader,\\nhgroup,\\nmain,\\nmenu,\\nnav,\\nsection,\\nsummary {\\n  display: block;\\n}\\n\\n/**\\n * 1. Correct `inline-block` display not defined in IE 8/9.\\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\\n */\\n\\naudio,\\ncanvas,\\nprogress,\\nvideo {\\n  display: inline-block; /* 1 */\\n  vertical-align: baseline; /* 2 */\\n}\\n\\n/**\\n * Prevent modern browsers from displaying `audio` without controls.\\n * Remove excess height in iOS 5 devices.\\n */\\n\\naudio:not([controls]) {\\n  display: none;\\n  height: 0;\\n}\\n\\n/**\\n * Address `[hidden]` styling not present in IE 8/9/10.\\n * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\\n */\\n\\n[hidden],\\ntemplate {\\n  display: none;\\n}\\n\\n/* Links\\n   ========================================================================== */\\n\\n/**\\n * Remove the gray background color from active links in IE 10.\\n */\\n\\na {\\n  background-color: transparent;\\n}\\n\\n/**\\n * Improve readability of focused elements when they are also in an\\n * active/hover state.\\n */\\n\\na:active,\\na:hover {\\n  outline: 0;\\n}\\n\\n/* Text-level semantics\\n   ========================================================================== */\\n\\n/**\\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\\n */\\n\\nabbr[title] {\\n  border-bottom: 1px dotted;\\n}\\n\\n/**\\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\\n */\\n\\nb,\\nstrong {\\n  font-weight: bold;\\n}\\n\\n/**\\n * Address styling not present in Safari and Chrome.\\n */\\n\\ndfn {\\n  font-style: italic;\\n}\\n\\n/**\\n * Address variable `h1` font-size and margin within `section` and `article`\\n * contexts in Firefox 4+, Safari, and Chrome.\\n */\\n\\nh1 {\\n  font-size: 2em;\\n  margin: 0.67em 0;\\n}\\n\\n/**\\n * Address styling not present in IE 8/9.\\n */\\n\\nmark {\\n  background: #ff0;\\n  color: #000;\\n}\\n\\n/**\\n * Address inconsistent and variable font size in all browsers.\\n */\\n\\nsmall {\\n  font-size: 80%;\\n}\\n\\n/**\\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\\n */\\n\\nsub,\\nsup {\\n  font-size: 75%;\\n  line-height: 0;\\n  position: relative;\\n  vertical-align: baseline;\\n}\\n\\nsup {\\n  top: -0.5em;\\n}\\n\\nsub {\\n  bottom: -0.25em;\\n}\\n\\n/* Embedded content\\n   ========================================================================== */\\n\\n/**\\n * Remove border when inside `a` element in IE 8/9/10.\\n */\\n\\nimg {\\n  border: 0;\\n}\\n\\n/**\\n * Correct overflow not hidden in IE 9/10/11.\\n */\\n\\nsvg:not(:root) {\\n  overflow: hidden;\\n}\\n\\n/* Grouping content\\n   ========================================================================== */\\n\\n/**\\n * Address margin not present in IE 8/9 and Safari.\\n */\\n\\nfigure {\\n  margin: 1em 40px;\\n}\\n\\n/**\\n * Address differences between Firefox and other browsers.\\n */\\n\\nhr {\\n  box-sizing: content-box;\\n  height: 0;\\n}\\n\\n/**\\n * Contain overflow in all browsers.\\n */\\n\\npre {\\n  overflow: auto;\\n}\\n\\n/**\\n * Address odd `em`-unit font size rendering in all browsers.\\n */\\n\\ncode,\\nkbd,\\npre,\\nsamp {\\n  font-family: monospace, monospace;\\n  font-size: 1em;\\n}\\n\\n/* Forms\\n   ========================================================================== */\\n\\n/**\\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\\n * styling of `select`, unless a `border` property is set.\\n */\\n\\n/**\\n * 1. Correct color not being inherited.\\n *    Known issue: affects color of disabled elements.\\n * 2. Correct font properties not being inherited.\\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\\n */\\n\\nbutton,\\ninput,\\noptgroup,\\nselect,\\ntextarea {\\n  color: inherit; /* 1 */\\n  font: inherit; /* 2 */\\n  margin: 0; /* 3 */\\n}\\n\\n/**\\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\\n */\\n\\nbutton {\\n  overflow: visible;\\n}\\n\\n/**\\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\\n * All other form control elements do not inherit `text-transform` values.\\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\\n * Correct `select` style inheritance in Firefox.\\n */\\n\\nbutton,\\nselect {\\n  text-transform: none;\\n}\\n\\n/**\\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\\n *    and `video` controls.\\n * 2. Correct inability to style clickable `input` types in iOS.\\n * 3. Improve usability and consistency of cursor style between image-type\\n *    `input` and others.\\n */\\n\\nbutton,\\nhtml input[type=\\\"button\\\"], /* 1 */\\ninput[type=\\\"reset\\\"],\\ninput[type=\\\"submit\\\"] {\\n  -webkit-appearance: button; /* 2 */\\n  cursor: pointer; /* 3 */\\n}\\n\\n/**\\n * Re-set default cursor for disabled elements.\\n */\\n\\nbutton[disabled],\\nhtml input[disabled] {\\n  cursor: default;\\n}\\n\\n/**\\n * Remove inner padding and border in Firefox 4+.\\n */\\n\\nbutton::-moz-focus-inner,\\ninput::-moz-focus-inner {\\n  border: 0;\\n  padding: 0;\\n}\\n\\n/**\\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\\n * the UA stylesheet.\\n */\\n\\ninput {\\n  line-height: normal;\\n}\\n\\n/**\\n * It's recommended that you don't attempt to style these elements.\\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\\n *\\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\\n * 2. Remove excess padding in IE 8/9/10.\\n */\\n\\ninput[type=\\\"checkbox\\\"],\\ninput[type=\\\"radio\\\"] {\\n  box-sizing: border-box; /* 1 */\\n  padding: 0; /* 2 */\\n}\\n\\n/**\\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\\n * `font-size` values of the `input`, it causes the cursor style of the\\n * decrement button to change from `default` to `text`.\\n */\\n\\ninput[type=\\\"number\\\"]::-webkit-inner-spin-button,\\ninput[type=\\\"number\\\"]::-webkit-outer-spin-button {\\n  height: auto;\\n}\\n\\n/**\\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\\n */\\n\\ninput[type=\\\"search\\\"] {\\n  -webkit-appearance: textfield; /* 1 */\\n  box-sizing: content-box; /* 2 */\\n}\\n\\n/**\\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\\n * Safari (but not Chrome) clips the cancel button when the search input has\\n * padding (and `textfield` appearance).\\n */\\n\\ninput[type=\\\"search\\\"]::-webkit-search-cancel-button,\\ninput[type=\\\"search\\\"]::-webkit-search-decoration {\\n  -webkit-appearance: none;\\n}\\n\\n/**\\n * Define consistent border, margin, and padding.\\n */\\n\\nfieldset {\\n  border: 1px solid #c0c0c0;\\n  margin: 0 2px;\\n  padding: 0.35em 0.625em 0.75em;\\n}\\n\\n/**\\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\\n */\\n\\nlegend {\\n  border: 0; /* 1 */\\n  padding: 0; /* 2 */\\n}\\n\\n/**\\n * Remove default vertical scrollbar in IE 8/9/10/11.\\n */\\n\\ntextarea {\\n  overflow: auto;\\n}\\n\\n/**\\n * Don't inherit the `font-weight` (applied by a rule above).\\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\\n */\\n\\noptgroup {\\n  font-weight: bold;\\n}\\n\\n/* Tables\\n   ========================================================================== */\\n\\n/**\\n * Remove most spacing between table cells.\\n */\\n\\ntable {\\n  border-collapse: collapse;\\n  border-spacing: 0;\\n}\\n\\ntd,\\nth {\\n  padding: 0;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/normalize.css/normalize.css\n ** module id = 706\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./AppRoot.scss\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./AppRoot.scss\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js!./../../node_modules/sass-loader/index.js?outputStyle=expanded!./AppRoot.scss\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/styles/AppRoot.scss\n ** module id = 707\n ** module chunks = 0\n **/","exports = module.exports = require(\"./../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"@charset \\\"UTF-8\\\";\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n/*\\n * STANDARD_RIFT_IO_COPYRIGHT\\n */\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Thin-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-ThinItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 200;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Medium-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-MediumItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 500;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-Black-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'Roboto';\\n  src: url(\" + require(\"../assets/Roboto-BlackItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 800;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Light-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-LightItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 100;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Regular-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Italic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 400;\\n  font-style: italic;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-Bold-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: normal;\\n}\\n\\n@font-face {\\n  font-family: 'RobotoCondensed';\\n  src: url(\" + require(\"../assets/RobotoCondensed-BoldItalic-webfont.woff\") + \") format(\\\"woff\\\");\\n  font-weight: 700;\\n  font-style: italic;\\n}\\n\\nhtml, body {\\n  background: #f1f1f1;\\n  cursor: auto;\\n  font-family: Roboto, Helvetica, Arial, sans-serif;\\n  overflow: hidden;\\n}\\n\\n::-webkit-scrollbar {\\n  display: none;\\n}\\n\\nhtml {\\n  -webkit-box-sizing: border-box;\\n  -moz-box-sizing: border-box;\\n  box-sizing: border-box;\\n}\\n\\n* {\\n  margin: 0;\\n  border: 0;\\n  padding: 0;\\n  border-collapse: collapse;\\n}\\n\\n*, *:before, *:after {\\n  -webkit-box-sizing: inherit;\\n  -moz-box-sizing: inherit;\\n  box-sizing: inherit;\\n}\\n\\nh1 {\\n  margin: 0;\\n  padding: 3px 6px;\\n  color: #323232;\\n  font-size: 0.75em;\\n  font-weight: normal;\\n  text-align: center;\\n  font-variant-caps: all-small-caps;\\n  font-variant: small-caps;\\n  text-transform: uppercase;\\n}\\n\\nbutton,\\ninput[type=\\\"image\\\"] {\\n  /*font-variant: small-caps;\\n\\ttext-transform: lowercase;\\n\\ttext-align: center;\\n\\tmargin: 4px 0;\\n\\tborder-radius: 0;\\n\\tborder-collapse: collapse;\\n\\tpadding: 2px 24px;\\n\\toutline: none;\\n\\tbackground-color: transparent;*/\\n  box-shadow: 2px 2px rgba(0, 0, 0, 0.15);\\n  color: #000000;\\n  display: inline-block;\\n  font-size: 12px;\\n  padding: 8px 34px;\\n  text-decoration: none;\\n  text-transform: uppercase;\\n}\\n\\nbutton:hover,\\ninput[type=\\\"image\\\"]:hover {\\n  background-color: #7E9BC1;\\n  color: #ffffff;\\n}\\n\\nbutton:active,\\nbutton:visited,\\ninput[type=\\\"image\\\"]:active, input[type=\\\"image\\\"]:visited {\\n  background-color: #4C5E74;\\n  color: #ffffff;\\n}\\n\\nbutton.-selected,\\ninput[type=\\\"image\\\"].-selected {\\n  background-color: #9fc4f4;\\n}\\n\\ninput[type=\\\"image\\\"] {\\n  width: 28px;\\n  height: 28px;\\n  margin-right: 12px;\\n  border: 0;\\n  border-radius: 4px;\\n  padding: 4px;\\n}\\n\\n.btn-group {\\n  white-space: nowrap;\\n}\\n\\n.btn-group button {\\n  border-right: 1px solid rgba(169, 169, 169, 0.5);\\n}\\n\\n.btn-group button:first-of-type {\\n  border-top-left-radius: 2px;\\n  border-bottom-left-radius: 2px;\\n}\\n\\n.btn-group button:last-of-type {\\n  border-right: none;\\n  border-top-right-radius: 2px;\\n  border-bottom-right-radius: 2px;\\n}\\n\\n.panel, .AppRoot .AppBody {\\n  overflow: hidden;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  background-color: #e5e5e5;\\n}\\n\\n.panel > div, .AppRoot .AppBody > div {\\n  min-width: 200px;\\n}\\n\\n.panel-header {\\n  /*position: absolute;\\n\\ttop: 0;\\n\\tleft: 0;\\n\\tright: 0;\\n\\theight: 50px;\\n\\tpadding: 8px;\\n\\tbackground-color: $panel-bg-color-contrast;\\n\\tborder-bottom: 1px solid $panel-border-color-light;\\n\\twhite-space: nowrap;*/\\n}\\n\\n.panel-header h1 {\\n  padding: 16px;\\n  white-space: nowrap;\\n  text-align: center;\\n}\\n\\n.panel-body {\\n  position: absolute;\\n  overflow: scroll;\\n  -ms-overflow-style: -ms-autohiding-scrollbar;\\n  top: 111px;\\n  bottom: 0px;\\n  left: 0;\\n  right: 0;\\n}\\n\\n.panel-footer {\\n  position: absolute;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  height: 40px;\\n  padding: 0 12px;\\n  background-color: #cbd1d1;\\n  border-top: 1px solid rgba(220, 220, 220, 0.5);\\n  white-space: nowrap;\\n}\\n\\n.welcome-message {\\n  margin: 20px;\\n  color: #06173c;\\n  font-size: x-large;\\n  font-weight: 200;\\n}\\n\\n.welcome-message .Button {\\n  display: inline-block;\\n}\\n\\n/* react-tooltip overrides */\\n.__react_component_tooltip {\\n  transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !important;\\n}\\n\\n/* simple css-only drop-down menu */\\n.menu {\\n  display: inline-flex;\\n  position: relative;\\n  z-index: 2;\\n}\\n\\n.menu > .Button:after {\\n  content: \\\"\\\\2C7\\\";\\n  position: absolute;\\n  right: 4px;\\n  bottom: -13px;\\n  font-size: 20px;\\n}\\n\\n.menu .sub-menu {\\n  display: none;\\n  position: absolute;\\n  top: 36px;\\n  left: -4px;\\n  padding: 4px;\\n  background-color: #f1f1f1;\\n  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\\n  border-radius: 3px;\\n}\\n\\n.menu .sub-menu .Button {\\n  display: block;\\n  text-align: left;\\n}\\n\\n.menu .sub-menu:hover {\\n  display: block;\\n}\\n\\n.menu > .Button:hover .sub-menu {\\n  display: block;\\n}\\n\\n.menu:hover .sub-menu {\\n  display: block;\\n}\\n\\n.descriptor text.badge {\\n  font-weight: 100;\\n  font-size: 12px;\\n  text-anchor: middle;\\n  fill: white;\\n  /* font color */\\n  stroke: white !important;\\n  /* font color */\\n}\\n\\ninput:focus {\\n  color: white;\\n  background: #000 !important;\\n}\\n\\n.hint {\\n  margin: 5px;\\n}\\n\\n.AppRoot {\\n  position: absolute;\\n  top: 0;\\n  bottom: 0;\\n  right: 0;\\n  left: 0;\\n  /* General */\\n}\\n\\n.AppRoot .crouton {\\n  color: #FFF;\\n  line-height: 140%;\\n  border-radius: 3px;\\n  position: fixed;\\n  top: 0px;\\n  left: 0px;\\n  right: 0px;\\n  max-width: 700px;\\n  width: 90%;\\n  text-align: center;\\n  z-index: 99999;\\n  margin: 0 auto;\\n}\\n\\n.AppRoot .crouton div {\\n  padding: 20px;\\n}\\n\\n.AppRoot .crouton div.info {\\n  background-color: #1F8DD6;\\n}\\n\\n.AppRoot .crouton div.success {\\n  background-color: #50CD84;\\n}\\n\\n.AppRoot .crouton div.warning {\\n  background-color: #FF8859;\\n}\\n\\n.AppRoot .crouton div.error {\\n  background-color: #FF5F5F;\\n}\\n\\n.AppRoot .crouton div span {\\n  display: block;\\n  margin-bottom: 0;\\n  margin-left: 0px;\\n}\\n\\n.AppRoot .crouton div .buttons {\\n  text-align: right;\\n}\\n\\n.AppRoot .crouton div .buttons button.btn, .AppRoot .crouton div .buttons button.retry, .AppRoot .crouton div .buttons button.close, .AppRoot .crouton div .buttons button.cancel, .AppRoot .crouton div .buttons button.ignore {\\n  padding: 0px;\\n  border: 1px solid transparent;\\n  border-radius: 3px;\\n}\\n\\n.AppRoot .crouton div .buttons button:hover {\\n  opacity: .75;\\n}\\n\\n.AppRoot .crouton div .buttons button.retry {\\n  border-color: #FFF;\\n}\\n\\n.AppRoot .crouton div .buttons button.btn.close {\\n  border-color: #FF5F5F;\\n  margin-left: 10px;\\n}\\n\\n.AppRoot .AppHeader {\\n  position: absolute;\\n  top: 0;\\n  right: 0;\\n  left: 0;\\n  height: 157px;\\n}\\n\\n.AppRoot .AppBody {\\n  position: absolute;\\n  top: 157px;\\n  right: 20px;\\n  bottom: 20px;\\n  left: 20px;\\n  background-color: #e5e5e5;\\n  margin: 0.5rem 1rem;\\n}\\n\\n.AppRoot .corner-accent {\\n  border: 1px solid #000000;\\n  display: block;\\n  height: 4px;\\n  position: absolute;\\n  width: 4px;\\n  z-index: 999;\\n}\\n\\n.AppRoot .corner-accent.top {\\n  border-bottom: 0 none;\\n  top: 164px;\\n}\\n\\n.AppRoot .corner-accent.bottom {\\n  border-top: 0 none;\\n  bottom: 27px;\\n}\\n\\n.AppRoot .corner-accent.right {\\n  border-left: 0 none;\\n  right: 35px;\\n}\\n\\n.AppRoot .corner-accent.left {\\n  border-right: 0 none;\\n  left: 35px;\\n}\\n\\n.AppRoot button:focus {\\n  outline: 0;\\n}\\n\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/sass-loader?outputStyle=expanded!./src/styles/AppRoot.scss\n ** module id = 708\n ** module chunks = 0\n **/"],"sourceRoot":""}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/package.json b/skyquake/plugins/composer/package.json
new file mode 100644 (file)
index 0000000..1cf415a
--- /dev/null
@@ -0,0 +1,94 @@
+{
+  "name": "composer",
+  "version": "0.0.79",
+  "description": "",
+  "repository": "",
+  "private": true,
+  "scripts": {
+    "start": "webpack --config webpack.dist.config.js --watch"
+  },
+  "src": "src",
+  "test": "test",
+  "dist": "dist",
+  "mainInput": "ComposerApp",
+  "mainOutput": "main",
+  "dependencies": {
+    "alt": "^0.17.9",
+    "babel-polyfill": "^6.2.0",
+    "bluebird": "^3.4.1",
+    "change-case": "^2.3.0",
+    "classnames": "^2.2.1",
+    "d3": "^3.5.10",
+    "dropzone": "^4.2.0",
+    "es5-shim": "^4.3.1",
+    "events": "^1.1.0",
+    "flux": "^2.1.1",
+    "grunt-cli": "^0.1.13",
+    "jquery": "^2.1.4",
+    "loaders.css": "^0.1.1",
+    "lodash": "^3.10.1",
+    "moment": "^2.10.6",
+    "normalize.css": "^3.0.3",
+    "numeral": "^1.5.3",
+    "object-assign": "^4.0.1",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.3.0",
+    "react": "^0.14.7",
+    "react-addons-css-transition-group": "^0.14.7",
+    "react-addons-pure-render-mixin": "^0.14.7",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.3",
+    "react-popout": "^0.4.0",
+    "request-promise": "^3.0.0",
+    "require-json": "0.0.1"
+  },
+  "devDependencies": {
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "css-loader": "^0.23.0",
+    "eslint": "^1.10.2",
+    "eslint-loader": "^1.1.1",
+    "eslint-plugin-react": "^3.11.1",
+    "grunt": "^0.4.5",
+    "grunt-contrib-clean": "^0.7.0",
+    "grunt-contrib-connect": "^0.11.2",
+    "grunt-contrib-copy": "^0.8.2",
+    "grunt-karma": "^0.12.1",
+    "grunt-open": "^0.2.3",
+    "grunt-version": "^1.0.0",
+    "grunt-webpack": "^1.0.11",
+    "html-webpack-plugin": "^2.12.0",
+    "image-webpack-loader": "^1.6.2",
+    "imagemin": "^4.0.0",
+    "install": "^0.4.2",
+    "jasmine-core": "^2.4.1",
+    "json-loader": "^0.5.4",
+    "json2yaml": "^1.1.0",
+    "karma": "^0.13.15",
+    "karma-chrome-launcher": "^0.2.2",
+    "karma-es6-shim": "^0.2.3",
+    "karma-jasmine": "^0.3.6",
+    "karma-phantomjs-launcher": "^0.2.1",
+    "karma-phantomjs-shim": "^1.2.0",
+    "karma-script-launcher": "^0.1.0",
+    "karma-sourcemap-loader": "^0.3.7",
+    "karma-webpack": "^1.7.0",
+    "load-grunt-tasks": "^3.3.0",
+    "node-sass": "^3.4.2",
+    "npm": "^3.7.1",
+    "phantomjs": "^1.9.19",
+    "react-addons-test-utils": "^0.14.7",
+    "react-hot-loader": "^1.3.0",
+    "react-inlinesvg": "^0.5.3",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "url-loader": "^0.5.7",
+    "webpack": "^1.3.0",
+    "webpack-dev-server": "^1.14.0",
+    "yamljs": "^0.2.8"
+  }
+}
diff --git a/skyquake/plugins/composer/routes.js b/skyquake/plugins/composer/routes.js
new file mode 100644 (file)
index 0000000..af67bfa
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var router = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js')
+var Composer = require('./api/composer.js');
+router.get('/api/catalog', cors(), function(req, res) {
+    Composer.get(req).then(function(data) {
+        utils.sendSuccessResponse(data, res);
+    }, function(error) {
+        utils.sendErrorResponse(error, res);
+    });
+});
+router.delete('/api/catalog/:catalogType/:id', cors(), function(req, res) {
+    Composer.delete(req).then(function(response) {
+        res.status(response.statusCode);
+        res.send({});
+    }, function(error) {
+        res.status(error.statusCode);
+        res.send(error.errorMessage);
+    });
+});
+router.post('/api/catalog/:catalogType', cors(), function(req, res) {
+    Composer.create(req).then(function(data) {
+        res.send(data);
+    }, function(error) {
+        res.status(error.statusCode);
+        res.send(error.errorMessage);
+    });
+});
+router.put('/api/catalog/:catalogType/:id', cors(), function(req, res) {
+    Composer.update(req).then(function(data) {
+        res.send(data);
+    }, function(error) {
+        res.status(error.statusCode);
+        res.send(error.errorMessage);
+    });
+});
+
+module.exports = router;
diff --git a/skyquake/plugins/composer/scripts/build.sh b/skyquake/plugins/composer/scripts/build.sh
new file mode 100755 (executable)
index 0000000..eb17e4e
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=composer
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/composer/scripts/build.sh.old b/skyquake/plugins/composer/scripts/build.sh.old
new file mode 100755 (executable)
index 0000000..e905bcb
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo "DIR is"
+pwd
+echo "Building composer webapp"
+npm rebuild
+./node_modules/.bin/grunt build
+
+
diff --git a/skyquake/plugins/composer/scripts/install.sh b/skyquake/plugins/composer/scripts/install.sh
new file mode 100755 (executable)
index 0000000..abba7f5
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=composer
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
diff --git a/skyquake/plugins/composer/scripts/launch_composer.sh b/skyquake/plugins/composer/scripts/launch_composer.sh
new file mode 100755 (executable)
index 0000000..770d32a
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+usage() {
+       echo "usage: launch_ui.sh [--enable-https --keyfile-path=<keyfile_path> --certfile-path=<certfile-path>]"
+}
+
+start_servers() {
+       cd $THIS_DIR
+       echo "Killing any previous instance of server_composer_ui.py"
+       ps -ef | awk '/[s]cripts\/server_composer_ui.py/{print $2}' | xargs kill -9
+       
+       echo "Running Python webserver. HTTPS Enabled: ${ENABLE_HTTPS}"
+       cd ../dist
+       if [ ! -z "${ENABLE_HTTPS}" ]; then
+               ../scripts/server_composer_ui.py --enable-https --keyfile-path="${KEYFILE_PATH}" --certfile-path="${CERTFILE_PATH}"&
+       else
+               ../scripts/server_composer_ui.py
+       fi
+}
+
+# Begin work
+for i in "$@"
+do
+case $i in
+    -k=*|--keyfile-path=*)
+    KEYFILE_PATH="${i#*=}"
+    shift # past argument=value
+    ;;
+    -c=*|--certfile-path=*)
+    CERTFILE_PATH="${i#*=}"
+    shift # past argument=value
+    ;;
+    -h|--help)
+    usage
+    exit
+    ;;
+    -e|--enable-https)
+    ENABLE_HTTPS=YES
+    shift # past argument=value
+    ;;
+    *)
+        # unknown option
+    ;;
+esac
+done
+
+if [[ ! -z "${ENABLE_HTTPS}" ]]; then
+       if [ -z "${KEYFILE_PATH}" ] || [ -z "{CERTFILE_PATH}" ]; then
+               usage
+               exit
+       fi
+fi
+
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+
+# Call function to start web and API servers
+start_servers
+
+while true; do
+  sleep 5
+done
diff --git a/skyquake/plugins/composer/scripts/server_composer_ui.py b/skyquake/plugins/composer/scripts/server_composer_ui.py
new file mode 100755 (executable)
index 0000000..e3c01e9
--- /dev/null
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from http.server import BaseHTTPRequestHandler, HTTPServer, SimpleHTTPRequestHandler
+import socketserver
+import mimetypes
+import argparse
+import sys
+import os
+import ssl
+
+PORT = 9000
+
+enable_https = False
+keyfile_path = None
+certfile_path = None
+
+DEFAULT_ENABLE_HTTPS = False
+DEFAULT_KEYFILE_PATH = None
+DEFAULT_CERTFILE_PATH = None
+
+def start_server(
+               enable_https=DEFAULT_ENABLE_HTTPS,
+               keyfile_path=DEFAULT_KEYFILE_PATH,
+               certfile_path=DEFAULT_CERTFILE_PATH):
+    Handler = SimpleHTTPRequestHandler
+    Handler.extensions_map['.svg'] = 'image/svg+xml'
+    httpd = socketserver.TCPServer(('', PORT), Handler)
+
+    if enable_https:
+
+        httpd.socket = ssl.wrap_socket(httpd.socket, 
+                                        server_side=True,
+                                        certfile=certfile_path,
+                                        keyfile=keyfile_path)
+
+    print("Serving at port: {}. HTTPS Enabled: {}".format(PORT, enable_https))
+    httpd.serve_forever()
+
+
+def main(argv=sys.argv[1:]):
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-p", "--port",
+                                       default=PORT,
+                                       help="Run on the given port")
+    parser.add_argument("-e", "--enable-https",
+                                       action="store_true",
+                                       default=False,
+                                       help="Enable HTTPS. Make sure certfile-path and keyfile-path are also specified")
+    parser.add_argument("-k", "--keyfile-path",
+                                       default=DEFAULT_KEYFILE_PATH,
+                                       help="Path to the key file")
+    parser.add_argument("-c", "--certfile-path",
+                                       default=DEFAULT_CERTFILE_PATH,
+                                       help="Path to the cert file")
+
+    args = parser.parse_args()
+
+    # When you want to use the debugger, unremark this before the line you want
+    #import pdb; pdb.set_trace()
+
+    if args.enable_https:
+        if not (args.keyfile_path and args.certfile_path):
+            parser.print_help()
+            sys.exit(2)
+    
+    start_server(args.enable_https, args.keyfile_path, args.certfile_path)
+
+
+if __name__ == '__main__':
+    main()
+
diff --git a/skyquake/plugins/composer/scripts/update-node-modules.sh b/skyquake/plugins/composer/scripts/update-node-modules.sh
new file mode 100755 (executable)
index 0000000..e60cf97
--- /dev/null
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+# the order of the install is important
+
+#npm install -g grunt-cli
+
+npm cache clean
+
+rm -R node_modules
+
+# dependencies
+npm install --save alt
+npm install --save change-case
+npm install --save classnames
+npm install --save d3
+npm install --save dropzone
+npm install --save es5-shim
+npm install --save events
+npm install --save flux
+npm install --save highlight.js
+npm install --save jquery
+npm install --save lodash
+npm install --save moment
+npm install --save normalize.css
+npm install --save numeral
+npm install --save object-assign
+npm install --save react
+npm install --save react-dom
+npm install --save react-addons-pure-render-mixin
+npm install --save react-highlight
+npm install --save react-tooltip
+npm install --save babel-polyfill
+
+# dev-dependencies
+npm install --save-dev imagemin
+npm install --save-dev jasmine-core
+npm install --save-dev babel
+npm install --save-dev babel-core
+npm install --save-dev eslint
+npm install --save-dev karma
+npm install --save-dev grunt
+npm install --save-dev webpack
+npm install --save-dev node-sass
+npm install --save-dev phantomjs
+
+npm install --save-dev grunt-contrib-clean
+npm install --save-dev grunt-contrib-connect
+npm install --save-dev grunt-contrib-copy
+npm install --save-dev grunt-karma
+npm install --save-dev grunt-open
+npm install --save-dev load-grunt-tasks
+
+npm install --save-dev karma-jasmine
+npm install --save-dev karma-phantomjs-launcher
+npm install --save-dev karma-script-launcher
+npm install --save-dev karma-webpack
+
+npm install --save-dev webpack-dev-server
+npm install --save-dev grunt-webpack
+npm install --save-dev react-hot-loader
+npm install --save-dev image-webpack-loader
+npm install --save-dev sass-loader
+npm install --save-dev style-loader
+npm install --save-dev url-loader
+npm install --save-dev babel-preset-es2015
+npm install --save-dev babel-preset-react
+npm install --save-dev json-loader
+npm install --save-dev babel-loader
+npm install --save-dev css-loader
+npm install --save-dev eslint-loader
+npm install --save-dev eslint-plugin-react
+
+grunt build
+grunt serve
diff --git a/skyquake/plugins/composer/src/index.js b/skyquake/plugins/composer/src/index.js
new file mode 100644 (file)
index 0000000..e0e8ac9
--- /dev/null
@@ -0,0 +1,13 @@
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('../config.json');
+
+// let context = require.context('./', true, /^\.\/.*\.(js|jsx|json)$/);
+let context = require.context('./', true, /^\.\/.*\.(js|jsx)$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
+
diff --git a/skyquake/plugins/composer/src/schemas/yang/README.md b/skyquake/plugins/composer/src/schemas/yang/README.md
new file mode 100644 (file)
index 0000000..6efa710
--- /dev/null
@@ -0,0 +1,45 @@
+The backend system is managed by CONFD YANG files. These files contain details about what inputs the backend systems accept.
+
+We generate a domain specific language (DSL) in JSON to drive rendering a "model driven" editor in the composer.
+
+
+One Step:
+
+Accomplish the below steps in one script `./generate-model-meta-json.sh`.
+
+If you need to run the steps manually for debugging, etc. Then do the following.
+
+
+Multi Step:
+
+To generate this DSL, we take the following steps:
+
+1. Collect the latest .yang files from the backend code bases and put them into this directory.
+
+2. Run `yang2json.sh`
+
+Requires yangforge to be installed `npm install -g yangforge`
+
+This is brittle and requires removing any dependencies that fail. Usually, mano-types.yang has typedef references that do not have the 'manotype' prefix.
+For example, 'type param-type-value' should be 'type manotypes:param-type-value'.
+
+3. Run `node confd2model.js`
+
+Review output to make sure it looks good.
+
+4. Run `node confd2model.js > ./model-meta.json`
+
+5. Copy the contents of ./model-meta.json into /webapp/src/libraries/DescriptorModelMeta.json
+
+Verify the composer details editor is working properly.
+
+Note:
+
+The build servers do not like our .yang files so we append .src to the file names.
+
+The yang2json.sh script does this for you now so you don' have to do the following. However, make sure you do not commit
+.yang files because it will break the build.
+
+Before committing these yang files, run `./src-append.sh` to append .src to the .yang files.
+
+Before running the above steps remove the .src with `./src-remove.sh`.
diff --git a/skyquake/plugins/composer/src/schemas/yang/confd2model.js b/skyquake/plugins/composer/src/schemas/yang/confd2model.js
new file mode 100644 (file)
index 0000000..ecaddf4
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+'use strict';
+
+// the models to be transformed into the output DSL JSON meta file
+var yang = [require('./json-nsd.json'), require('./json-vnfd.json')];
+
+var _ = require('lodash');
+var inet = require('./ietf-inet-types.yang.json');
+
+var utils = {
+       resolvePath(obj, path) {
+               // supports a.b, a[1] and foo[bar], etc.
+               // where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]
+               // then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;
+               path = path.split(/[\.\[\]]/).filter(d => d);
+               return path.reduce((r, p) => {
+                       if (r) {
+                               return r[p];
+                       }
+               }, obj);
+       },
+       assignPathValue(obj, path, value) {
+               path = path.split(/[\.\[\]]/).filter(d => d);
+               // enable look-ahead to determine if type is array or object
+               const pathCopy = path.slice();
+               // last item in path used to assign value on the resolved object
+               const name = path.pop();
+               const resolvedObj = path.reduce((r, p, i) => {
+                       if (typeof(r[p]) !== 'object') {
+                               // look-ahead to see if next path item is a number
+                               const isArray = !isNaN(parseInt(pathCopy[i + 1], 10));
+                               r[p] = isArray ? [] : {}
+                       }
+                       return r[p];
+               }, obj);
+               resolvedObj[name] = value;
+       }
+};
+
+var isType = d => /^(leaf|leaf-list|list|container|choice|case|uses)$/.test(d);
+
+function deriveCardinalityFromProperty(property, typeName) {
+       if (String(property.mandatory) === 'true') {
+               return '1';
+       }
+       let min = 0, max = Infinity;
+       if (property.hasOwnProperty('min-elements')) {
+               min = parseInt(property['min-elements'], 10) || 0;
+       }
+       if (property.hasOwnProperty('max-elements')) {
+               max = parseInt(property['max-elements'], 10) || Infinity;
+       } else {
+               if (!/^(list|leaf-list)$/.test(typeName)) {
+                       max = '1';
+               }
+       }
+       if (min > max) {
+               return String(min);
+       }
+       if (min === max) {
+               return String(min);
+       }
+       return String(min) + '..' + (max === Infinity ? 'N' : max);
+}
+
+function cleanWhitespace(text) {
+       if (typeof text === 'string') {
+               return text.replace(/\s+/g, ' ');
+       }
+       return text;
+}
+
+function buildProperties(typeData, typeName) {
+       var properties = [];
+       Object.keys(typeData).forEach(name => {
+               var property = typeData[name];
+               var listKey = typeName === 'list' ? String(property.key).split(/\s/).filter(k => k && k !== 'undefined') : false;
+               var meta = {
+                       name: name,
+                       type: typeName,
+                       description: cleanWhitespace(property.description),
+                       cardinality: deriveCardinalityFromProperty(property, typeName),
+                       'data-type': property.type,
+                       properties: Object.keys(property).filter(isType).reduce((r, childType) => {
+                               return r.concat(buildProperties(property[childType], childType));
+                       }, [])
+               };
+               if (listKey) {
+                       meta.key = listKey;
+               }
+               properties.push(meta);
+       });
+       return properties;
+}
+
+function lookupUses(uses, yang) {
+       function doLookup(lookupTypeName) {
+               var key;
+               // warn: hardcoded prefix support for mano-types - other prefixes will be ignored
+               if (/^manotypes:/.test(lookupTypeName)) {
+                       var moduleName = lookupTypeName.split(':')[1];
+                       key = ['dependencies.mano-types.module.mano-types.grouping', moduleName].join('.');
+               } else {
+                       var name = yang.name.replace(/^rw-/, '');
+                       key = ['dependencies', name, 'module', name, 'grouping', lookupTypeName].join('.');
+               }
+               return utils.resolvePath(yang, key);
+       }
+       if (typeof uses === 'object') {
+               return Object.keys(uses).reduce((result, key) => {
+                       var found = doLookup(key);
+                       Object.keys(found).filter(isType).forEach(type => {
+                               var property = result[type] || (result[type] = {});
+                               Object.assign(property, found[type]);
+                       });
+                       return result;
+               }, {});
+       } else if (typeof uses === 'string') {
+               return doLookup(uses);
+       }
+       return {};
+}
+
+function lookupTypedef(property, yang) {
+       var key;
+       var lookupTypeName = property.type;
+       // warn: hardcoded prefix support - other prefixes will be ignored
+       if (/^manotypes:/.test(lookupTypeName)) {
+               var lookupName = lookupTypeName.split(':')[1];
+               key = ['dependencies.mano-types.module.mano-types.typedef', lookupName].join('.');
+       } else if (/^inet:/.test(lookupTypeName)) {
+               var lookupName = lookupTypeName.split(':')[1];
+               yang = inet;
+               key = ['schema.module.ietf-inet-types.typedef', lookupName].join('.');
+       }
+       if (key) {
+               return utils.resolvePath(yang, key);
+       }
+}
+
+function resolveUses(property, yang) {
+       var childData = property.uses;
+       var resolved = lookupUses(childData, yang);
+       //console.log('uses', childData, 'found', resolved);
+       Object.keys(resolved).forEach(type => {
+               var parentTypes = property[type] || (property[type] = {});
+               // copy types into the parent types bucket
+               Object.assign(parentTypes, resolveReferences(yang, resolved[type]));
+       });
+       delete property.uses;
+}
+
+function resolveTypedef(property, yang) {
+       if (/:/.test(property.type)) {
+               var found = lookupTypedef(property, yang);
+               if (found) {
+                       Object.assign(property, found);
+               }
+       }
+}
+
+function resolveReferences(yang, data) {
+       var dataClone = _.cloneDeep(data);
+       function doResolve(typeData) {
+               Object.keys(typeData).forEach(name => {
+                       var property = typeData[name];
+                       resolveTypedef(property, yang);
+                       Object.keys(property).filter(isType).forEach(childType => {
+                               if (childType === 'uses') {
+                                       resolveUses(property, yang);
+                               } else {
+                                       doResolve(property[childType]);
+                               }
+                       });
+               });
+       }
+       doResolve(dataClone);
+       return dataClone;
+}
+
+function module(yang) {
+       let module;
+       var name = yang.name.replace(/^rw-/, '');
+       if (!name) {
+               throw 'no name given in json yang';
+       }
+       const path = ['container', name + '-catalog'].join('.');
+       module = utils.resolvePath(yang, path);
+
+       if (!module) {
+               module = utils.resolvePath(yang, ['schema', 'module', name, path].join('.'));
+       }
+       if (!module) {
+               module = utils.resolvePath(yang, ['dependencies', name, 'module', name, path].join('.'));
+       }
+       if (!module) {
+               throw 'cannot find the module' + name;
+       }
+
+       // module/agument/nsd:nsd-catalog/nsd:nsd/meta
+       const augLeafPath = ['schema.module', 'rw-' + name, 'augment', '/' + name + ':' + name + '-catalog/' + name + ':' + name, 'leaf'];
+       const meta = utils.resolvePath(yang, augLeafPath.concat('meta').join('.'));
+
+       const putLeafPath = ['dependencies', name, 'module', name, path, 'list', name, 'leaf'];
+
+       if (meta) {
+               utils.assignPathValue(yang, putLeafPath.concat(['meta']).join('.'), meta);
+       }
+
+       // module/agument/nsd:nsd-catalog/nsd:nsd/logo
+       const logo = utils.resolvePath(yang, augLeafPath.concat('logo').join('.'));
+       if (logo) {
+               utils.assignPathValue(yang, putLeafPath.concat(['logo']).join('.'), logo);
+       }
+       var data = module.list;
+
+       return {name: name, data: resolveReferences(yang, data)};
+
+}
+
+function reduceModule(result, module) {
+       result[module.name] = buildProperties(module.data, 'list')[0];
+       return result;
+}
+
+var result = yang.map(module).reduce(reduceModule, {});
+
+console.log(JSON.stringify(result, null, 5));
diff --git a/skyquake/plugins/composer/src/schemas/yang/generate-model-meta-json.sh b/skyquake/plugins/composer/src/schemas/yang/generate-model-meta-json.sh
new file mode 100755 (executable)
index 0000000..fbbfcd7
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+./src-remove.sh
+
+./yang2json.sh
+
+./src-append.sh
+
+node confd2model.js >./model-meta.json
diff --git a/skyquake/plugins/composer/src/schemas/yang/ietf-inet-types.yang.json b/skyquake/plugins/composer/src/schemas/yang/ietf-inet-types.yang.json
new file mode 100644 (file)
index 0000000..384efbe
--- /dev/null
@@ -0,0 +1,962 @@
+{
+ "synth": "source",
+ "name": "ietf-inet-types",
+ "description": "This module contains a collection of generally useful derived\nYANG data types for Internet addresses and related things.\n\nCopyright (c) 2013 IETF Trust and the persons identified as\nauthors of the code.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or\nwithout modification, is permitted pursuant to, and subject\nto the license terms contained in, the Simplified BSD License\nset forth in Section 4.c of the IETF Trust's Legal Provisions\nRelating to IETF Documents\n(http://trustee.ietf.org/license-info).\n\nThis version of this YANG module is part of RFC 6991; see\nthe RFC itself for full legal notices.",
+ "schema": {
+  "module": {
+   "ietf-inet-types": {
+    "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types",
+    "prefix": "inet",
+    "organization": "IETF NETMOD (NETCONF Data Modeling Language) Working Group",
+    "contact": "WG Web:   <http://tools.ietf.org/wg/netmod/>\nWG List:  <mailto:netmod@ietf.org>\n\nWG Chair: David Kessens\n          <mailto:david.kessens@nsn.com>\n\nWG Chair: Juergen Schoenwaelder\n          <mailto:j.schoenwaelder@jacobs-university.de>\n\nEditor:   Juergen Schoenwaelder\n          <mailto:j.schoenwaelder@jacobs-university.de>",
+    "description": "This module contains a collection of generally useful derived\nYANG data types for Internet addresses and related things.\n\nCopyright (c) 2013 IETF Trust and the persons identified as\nauthors of the code.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or\nwithout modification, is permitted pursuant to, and subject\nto the license terms contained in, the Simplified BSD License\nset forth in Section 4.c of the IETF Trust's Legal Provisions\nRelating to IETF Documents\n(http://trustee.ietf.org/license-info).\n\nThis version of this YANG module is part of RFC 6991; see\nthe RFC itself for full legal notices.",
+    "revision": {
+     "2013-07-15": {
+      "description": "This revision adds the following new data types:\n- ip-address-no-zone\n- ipv4-address-no-zone\n- ipv6-address-no-zone",
+      "reference": "RFC 6991: Common YANG Data Types"
+     },
+     "2010-09-24": {
+      "description": "Initial revision.",
+      "reference": "RFC 6021: Common YANG Data Types"
+     }
+    },
+    "typedef": {
+     "ip-version": {
+      "type": {
+       "enumeration": {
+        "enum": {
+         "unknown": {
+          "value": 0,
+          "description": "An unknown or unspecified version of the Internet\nprotocol."
+         },
+         "ipv4": {
+          "value": 1,
+          "description": "The IPv4 protocol as defined in RFC 791."
+         },
+         "ipv6": {
+          "value": 2,
+          "description": "The IPv6 protocol as defined in RFC 2460."
+         }
+        }
+       }
+      },
+      "description": "This value represents the version of the IP protocol.\n\nIn the value set and its semantics, this type is equivalent\nto the InetVersion textual convention of the SMIv2.",
+      "reference": "RFC  791: Internet Protocol\nRFC 2460: Internet Protocol, Version 6 (IPv6) Specification\nRFC 4001: Textual Conventions for Internet Network Addresses"
+     },
+     "dscp": {
+      "type": {
+       "uint8": {
+        "range": "0..63"
+       }
+      },
+      "description": "The dscp type represents a Differentiated Services Code Point\nthat may be used for marking packets in a traffic stream.\nIn the value set and its semantics, this type is equivalent\nto the Dscp textual convention of the SMIv2.",
+      "reference": "RFC 3289: Management Information Base for the Differentiated\n          Services Architecture\nRFC 2474: Definition of the Differentiated Services Field\n          (DS Field) in the IPv4 and IPv6 Headers\nRFC 2780: IANA Allocation Guidelines For Values In\n          the Internet Protocol and Related Headers"
+     },
+     "ipv6-flow-label": {
+      "type": {
+       "uint32": {
+        "range": "0..1048575"
+       }
+      },
+      "description": "The ipv6-flow-label type represents the flow identifier or Flow\nLabel in an IPv6 packet header that may be used to\ndiscriminate traffic flows.\n\nIn the value set and its semantics, this type is equivalent\nto the IPv6FlowLabel textual convention of the SMIv2.",
+      "reference": "RFC 3595: Textual Conventions for IPv6 Flow Label\nRFC 2460: Internet Protocol, Version 6 (IPv6) Specification"
+     },
+     "port-number": {
+      "type": {
+       "uint16": {
+        "range": "0..65535"
+       }
+      },
+      "description": "The port-number type represents a 16-bit port number of an\nInternet transport-layer protocol such as UDP, TCP, DCCP, or\nSCTP.  Port numbers are assigned by IANA.  A current list of\nall assignments is available from <http://www.iana.org/>.\n\nNote that the port number value zero is reserved by IANA.  In\nsituations where the value zero does not make sense, it can\nbe excluded by subtyping the port-number type.\nIn the value set and its semantics, this type is equivalent\nto the InetPortNumber textual convention of the SMIv2.",
+      "reference": "RFC  768: User Datagram Protocol\nRFC  793: Transmission Control Protocol\nRFC 4960: Stream Control Transmission Protocol\nRFC 4340: Datagram Congestion Control Protocol (DCCP)\nRFC 4001: Textual Conventions for Internet Network Addresses"
+     },
+     "as-number": {
+      "type": "uint32",
+      "description": "The as-number type represents autonomous system numbers\nwhich identify an Autonomous System (AS).  An AS is a set\nof routers under a single technical administration, using\nan interior gateway protocol and common metrics to route\npackets within the AS, and using an exterior gateway\nprotocol to route packets to other ASes.  IANA maintains\nthe AS number space and has delegated large parts to the\nregional registries.\n\nAutonomous system numbers were originally limited to 16\nbits.  BGP extensions have enlarged the autonomous system\nnumber space to 32 bits.  This type therefore uses an uint32\nbase type without a range restriction in order to support\na larger autonomous system number space.\n\nIn the value set and its semantics, this type is equivalent\nto the InetAutonomousSystemNumber textual convention of\nthe SMIv2.",
+      "reference": "RFC 1930: Guidelines for creation, selection, and registration\n          of an Autonomous System (AS)\nRFC 4271: A Border Gateway Protocol 4 (BGP-4)\nRFC 4001: Textual Conventions for Internet Network Addresses\nRFC 6793: BGP Support for Four-Octet Autonomous System (AS)\n          Number Space"
+     },
+     "ip-address": {
+      "type": {
+       "union": {
+        "type": {
+         "inet:ipv4-address": null,
+         "inet:ipv6-address": null
+        }
+       }
+      },
+      "description": "The ip-address type represents an IP address and is IP\nversion neutral.  The format of the textual representation\nimplies the IP version.  This type supports scoped addresses\nby allowing zone identifiers in the address format.",
+      "reference": "RFC 4007: IPv6 Scoped Address Architecture"
+     },
+     "ipv4-address": {
+      "type": {
+       "string": {
+        "pattern": "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\\p{N}\\p{L}]+)?"
+       }
+      },
+      "description": "The ipv4-address type represents an IPv4 address in\ndotted-quad notation.  The IPv4 address may include a zone\nindex, separated by a % sign.\n\nThe zone index is used to disambiguate identical address\nvalues.  For link-local addresses, the zone index will\ntypically be the interface index number or the name of an\ninterface.  If the zone index is not present, the default\nzone of the device will be used.\n\nThe canonical format for the zone index is the numerical\nformat"
+     },
+     "ipv6-address": {
+      "type": {
+       "string": {
+        "pattern": {
+         "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\\p{N}\\p{L}]+)?": null,
+         "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?": null
+        }
+       }
+      },
+      "description": "The ipv6-address type represents an IPv6 address in full,\nmixed, shortened, and shortened-mixed notation.  The IPv6\naddress may include a zone index, separated by a % sign.\n\nThe zone index is used to disambiguate identical address\nvalues.  For link-local addresses, the zone index will\ntypically be the interface index number or the name of an\ninterface.  If the zone index is not present, the default\nzone of the device will be used.\n\nThe canonical format of IPv6 addresses uses the textual\nrepresentation defined in Section 4 of RFC 5952.  The\ncanonical format for the zone index is the numerical\nformat as described in Section 11.2 of RFC 4007.",
+      "reference": "RFC 4291: IP Version 6 Addressing Architecture\nRFC 4007: IPv6 Scoped Address Architecture\nRFC 5952: A Recommendation for IPv6 Address Text\n          Representation"
+     },
+     "ip-address-no-zone": {
+      "type": {
+       "union": {
+        "type": {
+         "inet:ipv4-address-no-zone": null,
+         "inet:ipv6-address-no-zone": null
+        }
+       }
+      },
+      "description": "The ip-address-no-zone type represents an IP address and is\nIP version neutral.  The format of the textual representation\nimplies the IP version.  This type does not support scoped\naddresses since it does not allow zone identifiers in the\naddress format.",
+      "reference": "RFC 4007: IPv6 Scoped Address Architecture"
+     },
+     "ipv4-address-no-zone": {
+      "type": {
+       "inet:ipv4-address": {
+        "pattern": "[0-9\\.]*"
+       }
+      },
+      "description": "An IPv4 address without a zone index.  This type, derived from\nipv4-address, may be used in situations where the zone is\nknown from the context and hence no zone index is needed."
+     },
+     "ipv6-address-no-zone": {
+      "type": {
+       "inet:ipv6-address": {
+        "pattern": "[0-9a-fA-F:\\.]*"
+       }
+      },
+      "description": "An IPv6 address without a zone index.  This type, derived from\nipv6-address, may be used in situations where the zone is\nknown from the context and hence no zone index is needed.",
+      "reference": "RFC 4291: IP Version 6 Addressing Architecture\nRFC 4007: IPv6 Scoped Address Architecture\nRFC 5952: A Recommendation for IPv6 Address Text\n          Representation"
+     },
+     "ip-prefix": {
+      "type": {
+       "union": {
+        "type": {
+         "inet:ipv4-prefix": null,
+         "inet:ipv6-prefix": null
+        }
+       }
+      },
+      "description": "The ip-prefix type represents an IP prefix and is IP\nversion neutral.  The format of the textual representations\nimplies the IP version."
+     },
+     "ipv4-prefix": {
+      "type": {
+       "string": {
+        "pattern": "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))"
+       }
+      },
+      "description": "The ipv4-prefix type represents an IPv4 address prefix.\nThe prefix length is given by the number following the\nslash character and must be less than or equal to 32.\n\nA prefix length value of n corresponds to an IP address\nmask that has n contiguous 1-bits from the most\nsignificant bit (MSB) and all other bits set to 0.\n\nThe canonical format of an IPv4 prefix has all bits of\nthe IPv4 address set to zero that are not part of the\nIPv4 prefix."
+     },
+     "ipv6-prefix": {
+      "type": {
+       "string": {
+        "pattern": {
+         "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))": null,
+         "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+)": null
+        }
+       }
+      },
+      "description": "The ipv6-prefix type represents an IPv6 address prefix.\nThe prefix length is given by the number following the\nslash character and must be less than or equal to 128.\n\nA prefix length value of n corresponds to an IP address\nmask that has n contiguous 1-bits from the most\nsignificant bit (MSB) and all other bits set to 0.\n\nThe IPv6 address should have all bits that do not belong\nto the prefix set to zero.\n\nThe canonical format of an IPv6 prefix has all bits of\nthe IPv6 address set to zero that are not part of the\nIPv6 prefix.  Furthermore, the IPv6 address is represented\nas defined in Section 4 of RFC 5952.",
+      "reference": "RFC 5952: A Recommendation for IPv6 Address Text\n          Representation"
+     },
+     "domain-name": {
+      "type": {
+       "string": {
+        "length": "1..253",
+        "pattern": "((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)|\\."
+       }
+      },
+      "description": "The domain-name type represents a DNS domain name.  The\nname SHOULD be fully qualified whenever possible.\n\nInternet domain names are only loosely specified.  Section\n3.5 of RFC 1034 recommends a syntax (modified in Section\n2.1 of RFC 1123).  The pattern above is intended to allow\nfor current practice in domain name use, and some possible\nfuture expansion.  It is designed to hold various types of\ndomain names, including names used for A or AAAA records\n(host names) and other records, such as SRV records.  Note\nthat Internet host names have a stricter syntax (described\nin RFC 952) than the DNS recommendations in RFCs 1034 and\n1123, and that systems that want to store host names in\nschema nodes using the domain-name type are recommended to\nadhere to this stricter standard to ensure interoperability.\n\nThe encoding of DNS names in the DNS protocol is limited\nto 255 characters.  Since the encoding consists of labels\nprefixed by a length bytes and there is a trailing NULL\nbyte, only 253 characters can appear in the textual dotted\nnotation.\n\nThe description clause of schema nodes using the domain-name\ntype MUST describe when and how these names are resolved to\nIP addresses.  Note that the resolution of a domain-name value\nmay require to query multiple DNS records (e.g., A for IPv4\nand AAAA for IPv6).  The order of the resolution process and\nwhich DNS record takes precedence can either be defined\nexplicitly or may depend on the configuration of the\nresolver.\n\nDomain-name values use the US-ASCII encoding.  Their canonical\nformat uses lowercase US-ASCII characters.  Internationalized\ndomain names MUST be A-labels as per RFC 5890.",
+      "reference": "RFC  952: DoD Internet Host Table Specification\nRFC 1034: Domain Names - Concepts and Facilities\nRFC 1123: Requirements for Internet Hosts -- Application\n          and Support\nRFC 2782: A DNS RR for specifying the location of services\n          (DNS SRV)\nRFC 5890: Internationalized Domain Names in Applications\n          (IDNA): Definitions and Document Framework"
+     },
+     "host": {
+      "type": {
+       "union": {
+        "type": {
+         "inet:ip-address": null,
+         "inet:domain-name": null
+        }
+       }
+      },
+      "description": "The host type represents either an IP address or a DNS\ndomain name."
+     },
+     "uri": {
+      "type": "string",
+      "description": "The uri type represents a Uniform Resource Identifier\n(URI) as defined by STD 66.\n\nObjects using the uri type MUST be in US-ASCII encoding,\nand MUST be normalized as described by RFC 3986 Sections\n6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary\npercent-encoding is removed, and all case-insensitive\ncharacters are set to lowercase except for hexadecimal\ndigits, which are normalized to uppercase as described in\nSection 6.2.2.1.\n\nThe purpose of this normalization is to help provide\nunique URIs.  Note that this normalization is not\nsufficient to provide uniqueness.  Two URIs that are\ntextually distinct after this normalization may still be\nequivalent.\n\nObjects using the uri type may restrict the schemes that\nthey permit.  For example, 'data:' and 'urn:' schemes\nmight not be appropriate.\n\nA zero-length URI is not a valid URI.  This can be used to\nexpress 'URI absent' where required.\n\nIn the value set and its semantics, this type is equivalent\nto the Uri SMIv2 textual convention defined in RFC 5017.",
+      "reference": "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax\nRFC 3305: Report from the Joint W3C/IETF URI Planning Interest\n          Group: Uniform Resource Identifiers (URIs), URLs,\n          and Uniform Resource Names (URNs): Clarifications\n          and Recommendations\nRFC 5017: MIB Textual Conventions for Uniform Resource\n          Identifiers (URIs)"
+     }
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "typedef": {
+  "ip-version": {
+   "type": {
+    "enumeration": {
+     "enum": {
+      "unknown": {
+       "value": 0,
+       "description": "An unknown or unspecified version of the Internet\nprotocol."
+      },
+      "ipv4": {
+       "value": 1,
+       "description": "The IPv4 protocol as defined in RFC 791."
+      },
+      "ipv6": {
+       "value": 2,
+       "description": "The IPv6 protocol as defined in RFC 2460."
+      }
+     }
+    }
+   },
+   "description": "This value represents the version of the IP protocol.\n\nIn the value set and its semantics, this type is equivalent\nto the InetVersion textual convention of the SMIv2.",
+   "reference": "RFC  791: Internet Protocol\nRFC 2460: Internet Protocol, Version 6 (IPv6) Specification\nRFC 4001: Textual Conventions for Internet Network Addresses"
+  },
+  "dscp": {
+   "type": {
+    "uint8": {
+     "range": "0..63"
+    }
+   },
+   "description": "The dscp type represents a Differentiated Services Code Point\nthat may be used for marking packets in a traffic stream.\nIn the value set and its semantics, this type is equivalent\nto the Dscp textual convention of the SMIv2.",
+   "reference": "RFC 3289: Management Information Base for the Differentiated\n          Services Architecture\nRFC 2474: Definition of the Differentiated Services Field\n          (DS Field) in the IPv4 and IPv6 Headers\nRFC 2780: IANA Allocation Guidelines For Values In\n          the Internet Protocol and Related Headers"
+  },
+  "ipv6-flow-label": {
+   "type": {
+    "uint32": {
+     "range": "0..1048575"
+    }
+   },
+   "description": "The ipv6-flow-label type represents the flow identifier or Flow\nLabel in an IPv6 packet header that may be used to\ndiscriminate traffic flows.\n\nIn the value set and its semantics, this type is equivalent\nto the IPv6FlowLabel textual convention of the SMIv2.",
+   "reference": "RFC 3595: Textual Conventions for IPv6 Flow Label\nRFC 2460: Internet Protocol, Version 6 (IPv6) Specification"
+  },
+  "port-number": {
+   "type": {
+    "uint16": {
+     "range": "0..65535"
+    }
+   },
+   "description": "The port-number type represents a 16-bit port number of an\nInternet transport-layer protocol such as UDP, TCP, DCCP, or\nSCTP.  Port numbers are assigned by IANA.  A current list of\nall assignments is available from <http://www.iana.org/>.\n\nNote that the port number value zero is reserved by IANA.  In\nsituations where the value zero does not make sense, it can\nbe excluded by subtyping the port-number type.\nIn the value set and its semantics, this type is equivalent\nto the InetPortNumber textual convention of the SMIv2.",
+   "reference": "RFC  768: User Datagram Protocol\nRFC  793: Transmission Control Protocol\nRFC 4960: Stream Control Transmission Protocol\nRFC 4340: Datagram Congestion Control Protocol (DCCP)\nRFC 4001: Textual Conventions for Internet Network Addresses"
+  },
+  "as-number": {
+   "type": "uint32",
+   "description": "The as-number type represents autonomous system numbers\nwhich identify an Autonomous System (AS).  An AS is a set\nof routers under a single technical administration, using\nan interior gateway protocol and common metrics to route\npackets within the AS, and using an exterior gateway\nprotocol to route packets to other ASes.  IANA maintains\nthe AS number space and has delegated large parts to the\nregional registries.\n\nAutonomous system numbers were originally limited to 16\nbits.  BGP extensions have enlarged the autonomous system\nnumber space to 32 bits.  This type therefore uses an uint32\nbase type without a range restriction in order to support\na larger autonomous system number space.\n\nIn the value set and its semantics, this type is equivalent\nto the InetAutonomousSystemNumber textual convention of\nthe SMIv2.",
+   "reference": "RFC 1930: Guidelines for creation, selection, and registration\n          of an Autonomous System (AS)\nRFC 4271: A Border Gateway Protocol 4 (BGP-4)\nRFC 4001: Textual Conventions for Internet Network Addresses\nRFC 6793: BGP Support for Four-Octet Autonomous System (AS)\n          Number Space"
+  },
+  "ip-address": {
+   "type": {
+    "union": {
+     "type": {
+      "inet:ipv4-address": null,
+      "inet:ipv6-address": null
+     }
+    }
+   },
+   "description": "The ip-address type represents an IP address and is IP\nversion neutral.  The format of the textual representation\nimplies the IP version.  This type supports scoped addresses\nby allowing zone identifiers in the address format.",
+   "reference": "RFC 4007: IPv6 Scoped Address Architecture"
+  },
+  "ipv4-address": {
+   "type": {
+    "string": {
+     "pattern": "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\\p{N}\\p{L}]+)?"
+    }
+   },
+   "description": "The ipv4-address type represents an IPv4 address in\ndotted-quad notation.  The IPv4 address may include a zone\nindex, separated by a % sign.\n\nThe zone index is used to disambiguate identical address\nvalues.  For link-local addresses, the zone index will\ntypically be the interface index number or the name of an\ninterface.  If the zone index is not present, the default\nzone of the device will be used.\n\nThe canonical format for the zone index is the numerical\nformat"
+  },
+  "ipv6-address": {
+   "type": {
+    "string": {
+     "pattern": {
+      "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\\p{N}\\p{L}]+)?": null,
+      "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?": null
+     }
+    }
+   },
+   "description": "The ipv6-address type represents an IPv6 address in full,\nmixed, shortened, and shortened-mixed notation.  The IPv6\naddress may include a zone index, separated by a % sign.\n\nThe zone index is used to disambiguate identical address\nvalues.  For link-local addresses, the zone index will\ntypically be the interface index number or the name of an\ninterface.  If the zone index is not present, the default\nzone of the device will be used.\n\nThe canonical format of IPv6 addresses uses the textual\nrepresentation defined in Section 4 of RFC 5952.  The\ncanonical format for the zone index is the numerical\nformat as described in Section 11.2 of RFC 4007.",
+   "reference": "RFC 4291: IP Version 6 Addressing Architecture\nRFC 4007: IPv6 Scoped Address Architecture\nRFC 5952: A Recommendation for IPv6 Address Text\n          Representation"
+  },
+  "ip-address-no-zone": {
+   "type": {
+    "union": {
+     "type": {
+      "inet:ipv4-address-no-zone": null,
+      "inet:ipv6-address-no-zone": null
+     }
+    }
+   },
+   "description": "The ip-address-no-zone type represents an IP address and is\nIP version neutral.  The format of the textual representation\nimplies the IP version.  This type does not support scoped\naddresses since it does not allow zone identifiers in the\naddress format.",
+   "reference": "RFC 4007: IPv6 Scoped Address Architecture"
+  },
+  "ipv4-address-no-zone": {
+   "type": {
+    "inet:ipv4-address": {
+     "pattern": "[0-9\\.]*"
+    }
+   },
+   "description": "An IPv4 address without a zone index.  This type, derived from\nipv4-address, may be used in situations where the zone is\nknown from the context and hence no zone index is needed."
+  },
+  "ipv6-address-no-zone": {
+   "type": {
+    "inet:ipv6-address": {
+     "pattern": "[0-9a-fA-F:\\.]*"
+    }
+   },
+   "description": "An IPv6 address without a zone index.  This type, derived from\nipv6-address, may be used in situations where the zone is\nknown from the context and hence no zone index is needed.",
+   "reference": "RFC 4291: IP Version 6 Addressing Architecture\nRFC 4007: IPv6 Scoped Address Architecture\nRFC 5952: A Recommendation for IPv6 Address Text\n          Representation"
+  },
+  "ip-prefix": {
+   "type": {
+    "union": {
+     "type": {
+      "inet:ipv4-prefix": null,
+      "inet:ipv6-prefix": null
+     }
+    }
+   },
+   "description": "The ip-prefix type represents an IP prefix and is IP\nversion neutral.  The format of the textual representations\nimplies the IP version."
+  },
+  "ipv4-prefix": {
+   "type": {
+    "string": {
+     "pattern": "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))"
+    }
+   },
+   "description": "The ipv4-prefix type represents an IPv4 address prefix.\nThe prefix length is given by the number following the\nslash character and must be less than or equal to 32.\n\nA prefix length value of n corresponds to an IP address\nmask that has n contiguous 1-bits from the most\nsignificant bit (MSB) and all other bits set to 0.\n\nThe canonical format of an IPv4 prefix has all bits of\nthe IPv4 address set to zero that are not part of the\nIPv4 prefix."
+  },
+  "ipv6-prefix": {
+   "type": {
+    "string": {
+     "pattern": {
+      "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))": null,
+      "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+)": null
+     }
+    }
+   },
+   "description": "The ipv6-prefix type represents an IPv6 address prefix.\nThe prefix length is given by the number following the\nslash character and must be less than or equal to 128.\n\nA prefix length value of n corresponds to an IP address\nmask that has n contiguous 1-bits from the most\nsignificant bit (MSB) and all other bits set to 0.\n\nThe IPv6 address should have all bits that do not belong\nto the prefix set to zero.\n\nThe canonical format of an IPv6 prefix has all bits of\nthe IPv6 address set to zero that are not part of the\nIPv6 prefix.  Furthermore, the IPv6 address is represented\nas defined in Section 4 of RFC 5952.",
+   "reference": "RFC 5952: A Recommendation for IPv6 Address Text\n          Representation"
+  },
+  "domain-name": {
+   "type": {
+    "string": {
+     "length": "1..253",
+     "pattern": "((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)|\\."
+    }
+   },
+   "description": "The domain-name type represents a DNS domain name.  The\nname SHOULD be fully qualified whenever possible.\n\nInternet domain names are only loosely specified.  Section\n3.5 of RFC 1034 recommends a syntax (modified in Section\n2.1 of RFC 1123).  The pattern above is intended to allow\nfor current practice in domain name use, and some possible\nfuture expansion.  It is designed to hold various types of\ndomain names, including names used for A or AAAA records\n(host names) and other records, such as SRV records.  Note\nthat Internet host names have a stricter syntax (described\nin RFC 952) than the DNS recommendations in RFCs 1034 and\n1123, and that systems that want to store host names in\nschema nodes using the domain-name type are recommended to\nadhere to this stricter standard to ensure interoperability.\n\nThe encoding of DNS names in the DNS protocol is limited\nto 255 characters.  Since the encoding consists of labels\nprefixed by a length bytes and there is a trailing NULL\nbyte, only 253 characters can appear in the textual dotted\nnotation.\n\nThe description clause of schema nodes using the domain-name\ntype MUST describe when and how these names are resolved to\nIP addresses.  Note that the resolution of a domain-name value\nmay require to query multiple DNS records (e.g., A for IPv4\nand AAAA for IPv6).  The order of the resolution process and\nwhich DNS record takes precedence can either be defined\nexplicitly or may depend on the configuration of the\nresolver.\n\nDomain-name values use the US-ASCII encoding.  Their canonical\nformat uses lowercase US-ASCII characters.  Internationalized\ndomain names MUST be A-labels as per RFC 5890.",
+   "reference": "RFC  952: DoD Internet Host Table Specification\nRFC 1034: Domain Names - Concepts and Facilities\nRFC 1123: Requirements for Internet Hosts -- Application\n          and Support\nRFC 2782: A DNS RR for specifying the location of services\n          (DNS SRV)\nRFC 5890: Internationalized Domain Names in Applications\n          (IDNA): Definitions and Document Framework"
+  },
+  "host": {
+   "type": {
+    "union": {
+     "type": {
+      "inet:ip-address": null,
+      "inet:domain-name": null
+     }
+    }
+   },
+   "description": "The host type represents either an IP address or a DNS\ndomain name."
+  },
+  "uri": {
+   "type": "string",
+   "description": "The uri type represents a Uniform Resource Identifier\n(URI) as defined by STD 66.\n\nObjects using the uri type MUST be in US-ASCII encoding,\nand MUST be normalized as described by RFC 3986 Sections\n6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary\npercent-encoding is removed, and all case-insensitive\ncharacters are set to lowercase except for hexadecimal\ndigits, which are normalized to uppercase as described in\nSection 6.2.2.1.\n\nThe purpose of this normalization is to help provide\nunique URIs.  Note that this normalization is not\nsufficient to provide uniqueness.  Two URIs that are\ntextually distinct after this normalization may still be\nequivalent.\n\nObjects using the uri type may restrict the schemes that\nthey permit.  For example, 'data:' and 'urn:' schemes\nmight not be appropriate.\n\nA zero-length URI is not a valid URI.  This can be used to\nexpress 'URI absent' where required.\n\nIn the value set and its semantics, this type is equivalent\nto the Uri SMIv2 textual convention defined in RFC 5017.",
+   "reference": "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax\nRFC 3305: Report from the Joint W3C/IETF URI Planning Interest\n          Group: Uniform Resource Identifiers (URIs), URLs,\n          and Uniform Resource Names (URNs): Clarifications\n          and Recommendations\nRFC 5017: MIB Textual Conventions for Uniform Resource\n          Identifiers (URIs)"
+  }
+ },
+ "pkgdir": "/Users/onvelocity/rift-composer/webapp/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/ietf-inet-types.yang.src b/skyquake/plugins/composer/src/schemas/yang/ietf-inet-types.yang.src
new file mode 100755 (executable)
index 0000000..4ed2c13
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * NO RW COPYRIGHT
+ *
+ */
+
+module ietf-inet-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+  prefix "inet";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    WG Chair: Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types for Internet addresses and related things.
+
+    Copyright (c) 2013 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Simplified BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC 6991; see
+    the RFC itself for full legal notices.";
+
+  revision 2013-07-15 {
+    description
+     "This revision adds the following new data types:
+      - ip-address-no-zone
+      - ipv4-address-no-zone
+      - ipv6-address-no-zone";
+    reference
+     "RFC 6991: Common YANG Data Types";
+  }
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of types related to protocol fields ***/
+
+  typedef ip-version {
+    type enumeration {
+      enum unknown {
+        value "0";
+        description
+         "An unknown or unspecified version of the Internet
+          protocol.";
+      }
+      enum ipv4 {
+        value "1";
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum ipv6 {
+        value "2";
+        description
+         "The IPv6 protocol as defined in RFC 2460.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetVersion textual convention of the SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+     "The dscp type represents a Differentiated Services Code Point
+      that may be used for marking packets in a traffic stream.
+      In the value set and its semantics, this type is equivalent
+      to the Dscp textual convention of the SMIv2.";
+    reference
+     "RFC 3289: Management Information Base for the Differentiated
+                Services Architecture
+      RFC 2474: Definition of the Differentiated Services Field
+                (DS Field) in the IPv4 and IPv6 Headers
+      RFC 2780: IANA Allocation Guidelines For Values In
+                the Internet Protocol and Related Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+     "The ipv6-flow-label type represents the flow identifier or Flow
+      Label in an IPv6 packet header that may be used to
+      discriminate traffic flows.
+
+      In the value set and its semantics, this type is equivalent
+      to the IPv6FlowLabel textual convention of the SMIv2.";
+    reference
+     "RFC 3595: Textual Conventions for IPv6 Flow Label
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16 {
+      range "0..65535";
+    }
+    description
+     "The port-number type represents a 16-bit port number of an
+      Internet transport-layer protocol such as UDP, TCP, DCCP, or
+      SCTP.  Port numbers are assigned by IANA.  A current list of
+      all assignments is available from <http://www.iana.org/>.
+
+      Note that the port number value zero is reserved by IANA.  In
+      situations where the value zero does not make sense, it can
+      be excluded by subtyping the port-number type.
+      In the value set and its semantics, this type is equivalent
+      to the InetPortNumber textual convention of the SMIv2.";
+    reference
+     "RFC  768: User Datagram Protocol
+      RFC  793: Transmission Control Protocol
+      RFC 4960: Stream Control Transmission Protocol
+      RFC 4340: Datagram Congestion Control Protocol (DCCP)
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of types related to autonomous systems ***/
+
+  typedef as-number {
+    type uint32;
+    description
+     "The as-number type represents autonomous system numbers
+      which identify an Autonomous System (AS).  An AS is a set
+      of routers under a single technical administration, using
+      an interior gateway protocol and common metrics to route
+      packets within the AS, and using an exterior gateway
+      protocol to route packets to other ASes.  IANA maintains
+      the AS number space and has delegated large parts to the
+      regional registries.
+
+      Autonomous system numbers were originally limited to 16
+      bits.  BGP extensions have enlarged the autonomous system
+      number space to 32 bits.  This type therefore uses an uint32
+      base type without a range restriction in order to support
+      a larger autonomous system number space.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetAutonomousSystemNumber textual convention of
+      the SMIv2.";
+    reference
+     "RFC 1930: Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+      RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+      RFC 4001: Textual Conventions for Internet Network Addresses
+      RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
+                Number Space";
+  }
+
+  /*** collection of types related to IP addresses and hostnames ***/
+
+  typedef ip-address {
+    type union {
+      type inet:ipv4-address;
+      type inet:ipv6-address;
+    }
+    description
+     "The ip-address type represents an IP address and is IP
+      version neutral.  The format of the textual representation
+      implies the IP version.  This type supports scoped addresses
+      by allowing zone identifiers in the address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+      + '(%[\p{N}\p{L}]+)?';
+    }
+    description
+      "The ipv4-address type represents an IPv4 address in
+       dotted-quad notation.  The IPv4 address may include a zone
+       index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format for the zone index is the numerical
+       format";
+  }
+
+  typedef ipv6-address {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(%[\p{N}\p{L}]+)?';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(%.+)?';
+    }
+    description
+     "The ipv6-address type represents an IPv6 address in full,
+      mixed, shortened, and shortened-mixed notation.  The IPv6
+      address may include a zone index, separated by a % sign.
+
+      The zone index is used to disambiguate identical address
+      values.  For link-local addresses, the zone index will
+      typically be the interface index number or the name of an
+      interface.  If the zone index is not present, the default
+      zone of the device will be used.
+
+      The canonical format of IPv6 addresses uses the textual
+      representation defined in Section 4 of RFC 5952.  The
+      canonical format for the zone index is the numerical
+      format as described in Section 11.2 of RFC 4007.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-address-no-zone {
+    type union {
+      type inet:ipv4-address-no-zone;
+      type inet:ipv6-address-no-zone;
+    }
+    description
+     "The ip-address-no-zone type represents an IP address and is
+      IP version neutral.  The format of the textual representation
+      implies the IP version.  This type does not support scoped
+      addresses since it does not allow zone identifiers in the
+      address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address-no-zone {
+    type inet:ipv4-address {
+      pattern '[0-9\.]*';
+    }
+    description
+      "An IPv4 address without a zone index.  This type, derived from
+       ipv4-address, may be used in situations where the zone is
+       known from the context and hence no zone index is needed.";
+  }
+
+  typedef ipv6-address-no-zone {
+    type inet:ipv6-address {
+      pattern '[0-9a-fA-F:\.]*';
+    }
+    description
+      "An IPv6 address without a zone index.  This type, derived from
+       ipv6-address, may be used in situations where the zone is
+       known from the context and hence no zone index is needed.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type inet:ipv4-prefix;
+      type inet:ipv6-prefix;
+    }
+    description
+     "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv4 prefix has all bits of
+      the IPv4 address set to zero that are not part of the
+      IPv4 prefix.";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-prefix type represents an IPv6 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 128.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The IPv6 address should have all bits that do not belong
+      to the prefix set to zero.
+
+      The canonical format of an IPv6 prefix has all bits of
+      the IPv6 address set to zero that are not part of the
+      IPv6 prefix.  Furthermore, the IPv6 address is represented
+      as defined in Section 4 of RFC 5952.";
+    reference
+     "RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  /*** collection of domain name and URI types ***/
+
+  typedef domain-name {
+    type string {
+      length "1..253";
+      pattern
+        '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+      + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+      + '|\.';
+    }
+    description
+     "The domain-name type represents a DNS domain name.  The
+      name SHOULD be fully qualified whenever possible.
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  It is designed to hold various types of
+      domain names, including names used for A or AAAA records
+      (host names) and other records, such as SRV records.  Note
+      that Internet host names have a stricter syntax (described
+      in RFC 952) than the DNS recommendations in RFCs 1034 and
+      1123, and that systems that want to store host names in
+      schema nodes using the domain-name type are recommended to
+      adhere to this stricter standard to ensure interoperability.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      The description clause of schema nodes using the domain-name
+      type MUST describe when and how these names are resolved to
+      IP addresses.  Note that the resolution of a domain-name value
+      may require to query multiple DNS records (e.g., A for IPv4
+      and AAAA for IPv6).  The order of the resolution process and
+      which DNS record takes precedence can either be defined
+      explicitly or may depend on the configuration of the
+      resolver.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be A-labels as per RFC 5890.";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1034: Domain Names - Concepts and Facilities
+      RFC 1123: Requirements for Internet Hosts -- Application
+                and Support
+      RFC 2782: A DNS RR for specifying the location of services
+                (DNS SRV)
+      RFC 5890: Internationalized Domain Names in Applications
+                (IDNA): Definitions and Document Framework";
+  }
+
+  typedef host {
+    type union {
+      type inet:ip-address;
+      type inet:domain-name;
+    }
+    description
+     "The host type represents either an IP address or a DNS
+      domain name.";
+  }
+
+  typedef uri {
+    type string;
+    description
+     "The uri type represents a Uniform Resource Identifier
+      (URI) as defined by STD 66.
+
+      Objects using the uri type MUST be in US-ASCII encoding,
+      and MUST be normalized as described by RFC 3986 Sections
+      6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+      percent-encoding is removed, and all case-insensitive
+      characters are set to lowercase except for hexadecimal
+      digits, which are normalized to uppercase as described in
+      Section 6.2.2.1.
+
+      The purpose of this normalization is to help provide
+      unique URIs.  Note that this normalization is not
+      sufficient to provide uniqueness.  Two URIs that are
+      textually distinct after this normalization may still be
+      equivalent.
+
+      Objects using the uri type may restrict the schemes that
+      they permit.  For example, 'data:' and 'urn:' schemes
+      might not be appropriate.
+
+      A zero-length URI is not a valid URI.  This can be used to
+      express 'URI absent' where required.
+
+      In the value set and its semantics, this type is equivalent
+      to the Uri SMIv2 textual convention defined in RFC 5017.";
+    reference
+     "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+      RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                Group: Uniform Resource Identifiers (URIs), URLs,
+                and Uniform Resource Names (URNs): Clarifications
+                and Recommendations
+      RFC 5017: MIB Textual Conventions for Uniform Resource
+                Identifiers (URIs)";
+  }
+
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/json-nsd.json b/skyquake/plugins/composer/src/schemas/yang/json-nsd.json
new file mode 100644 (file)
index 0000000..1e7b753
--- /dev/null
@@ -0,0 +1,5144 @@
+{
+ "synth": "source",
+ "name": "rw-nsd",
+ "schema": {
+  "module": {
+   "rw-nsd": {
+    "namespace": "http://riftio.com/ns/riftware-1.0/rw-nsd",
+    "prefix": "rw-nsd",
+    "import": {
+     "nsd": {
+      "prefix": "nsd"
+     },
+     "ietf-yang-types": {
+      "prefix": "yang"
+     },
+     "mano-types": {
+      "prefix": "manotypes"
+     }
+    },
+    "revision": {
+     "2015-09-10": {
+      "description": "Initial revision. This YANG file augments\nthe base MANO NSD",
+      "reference": "Derived from earlier versions of base YANG files"
+     }
+    },
+    "augment": {
+     "/nsd:nsd-catalog/nsd:nsd": {
+      "uses": {},
+      "leaf": {
+       "meta": {
+        "description": "Any meta-data needed by the UI",
+        "type": "string"
+       }
+      },
+      "list": {
+       "control-param": {
+        "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group control parameters",
+          "type": "string"
+         },
+         "min-value": {
+          "description": "Minimum value for the parameter",
+          "type": "uint64"
+         },
+         "max-value": {
+          "description": "Maxium value for the parameter",
+          "type": "uint64"
+         },
+         "current-value": {
+          "description": "Current value for the parameter",
+          "type": "uint64"
+         },
+         "step-value": {
+          "description": "Step value for the parameter",
+          "type": "uint64"
+         },
+         "units": {
+          "type": "string"
+         },
+         "widget-type": {
+          "type": "manotypes:widget-type"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+          "type": "string"
+         }
+        }
+       },
+       "action-param": {
+        "description": "List of action parameters to\ncontrol VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group monitoring parameter",
+          "type": "string"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+          "type": "string"
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "dependencies": {
+  "nsd": {
+   "module": {
+    "nsd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:nsd",
+     "prefix": "nsd",
+     "import": {
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "vld": {
+       "prefix": "vld"
+      },
+      "vnfd": {
+       "prefix": "vnfd"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "mano-types": {
+       "prefix": "manotypes"
+      }
+     },
+     "revision": {
+      "2014-10-27": {
+       "description": "Initial revision. This YANG file defines\nthe Network Service Descriptor (NSD)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "scaling-trigger": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "pre-scale-in": {
+           "value": "1"
+          },
+          "post-scale-in": {
+           "value": "2"
+          },
+          "pre-scale-out": {
+           "value": "3"
+          },
+          "post-scale-out": {
+           "value": "4"
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "nsd-catalog": {
+       "list": {
+        "nsd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the NSD.",
+           "type": "string"
+          },
+          "name": {
+           "description": "NSD name.",
+           "mandatory": "true",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "NSD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the NSD.",
+           "type": "string"
+          },
+          "logo": {
+           "description": "File path for  the vendor specific logo. For example icons/mylogo.png.\nThe logo  should be part of the network service",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the NSD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the NSD",
+           "type": "string"
+          }
+         },
+         "list": {
+          "connection-point": {
+           "description": "List for external connection points.\nEach NS has one or more external connection\npoints. As the name implies that external\nconnection points are used for connecting\nthe NS to other NS or to external networks.\nEach NS exposes these connection points to\nthe orchestrator. The orchestrator can\nconstruct network service chains by\nconnecting the connection points between\ndifferent NS.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the NS connection point.",
+             "type": "string"
+            },
+            "type": {
+             "description": "Type of the connection point.",
+             "type": "manotypes:connection-point-type"
+            }
+           }
+          },
+          "vld": {
+           "description": "List of Virtual Link Descriptors.",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD.",
+             "type": "string"
+            },
+            "name": {
+             "description": "Virtual Link Descriptor (VLD) name.",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name for VLD for UI",
+             "type": "string"
+            },
+            "vendor": {
+             "description": "Provider of the VLD.",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VLD.",
+             "type": "string"
+            },
+            "version": {
+             "description": "Version of the VLD",
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "list": {
+            "vnfd-connection-point-ref": {
+             "description": "A list of references to connection points.",
+             "key": "member-vnf-index-ref",
+             "leaf": {
+              "member-vnf-index-ref": {
+               "description": "Reference to member-vnf within constituent-vnfds",
+               "type": {
+                "leafref": {
+                 "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                }
+               }
+              },
+              "vnfd-id-ref": {
+               "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "A reference to a connection point name\nin a vnfd. This is a leafref to path:\n    /vnfd:vnfd-catalog/vnfd:vnfd\n    + [vnfd:id = current()/../nsd:vnfd-id-ref]\n    + /vnfd:connection-point/vnfd:name\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+               "type": "string"
+              }
+             }
+            }
+           },
+           "uses": "manotypes:provider-network"
+          },
+          "constituent-vnfd": {
+           "description": "List of VNFDs that are part of this\nnetwork service.",
+           "key": "member-vnf-index",
+           "leaf": {
+            "member-vnf-index": {
+             "description": "Identifier/index for the VNFD. This separate id\nis required to ensure that multiple VNFs can be\npart of single NS",
+             "type": "uint64"
+            },
+            "vnfd-id-ref": {
+             "description": "Identifier for the VNFD.",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            },
+            "start-by-default": {
+             "description": "VNFD is started as part of the NS instantiation",
+             "type": "boolean",
+             "default": "true"
+            }
+           }
+          },
+          "scaling-group-descriptor": {
+           "description": "scaling group descriptor within this network service.\nThe scaling group defines a group of VNFs,\nand the ratio of VNFs in the network service\nthat is used as target for scaling action",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of this scaling group.",
+             "type": "string"
+            },
+            "min-instance-count": {
+             "description": "Minimum instances of the scaling group which are allowed.\nThese instances are created by default when the network service\nis instantiated.",
+             "type": "uint32",
+             "default": "0"
+            },
+            "max-instance-count": {
+             "description": "Maximum instances of this scaling group that are allowed\nin a single network service. The network service scaling\nwill fail, when the number of service group instances\nexceed the max-instance-count specified.",
+             "type": "uint32",
+             "default": "10"
+            }
+           },
+           "list": {
+            "vnfd-member": {
+             "description": "List of VNFs in this scaling group",
+             "key": "member-vnf-index-ref",
+             "leaf": {
+              "member-vnf-index-ref": {
+               "description": "member VNF index of this member VNF",
+               "type": {
+                "leafref": {
+                 "path": "../../../constituent-vnfd/member-vnf-index"
+                }
+               }
+              },
+              "count": {
+               "description": "count of this member VNF  within this scaling group.\nThe count allows to define  the number of instances\nwhen a scaling action targets this scaling group",
+               "type": "uint32",
+               "default": "1"
+              }
+             }
+            },
+            "scaling-config-action": {
+             "description": "List of scaling config actions",
+             "key": "trigger",
+             "leaf": {
+              "trigger": {
+               "description": "scaling trigger",
+               "type": "scaling-trigger"
+              },
+              "ns-config-primitive-name-ref": {
+               "description": "Reference to the NS config name primitive",
+               "type": {
+                "leafref": {
+                 "path": "../../../config-primitive/name"
+                }
+               }
+              }
+             }
+            }
+           }
+          },
+          "placement-groups": {
+           "description": "List of placement groups at NS level",
+           "key": "name",
+           "uses": "manotypes:placement-group-info",
+           "list": {
+            "member-vnfd": {
+             "description": "List of VNFDs that are part of this placement group",
+             "key": "member-vnf-index-ref",
+             "leaf": {
+              "member-vnf-index-ref": {
+               "description": "member VNF index of this member VNF",
+               "type": {
+                "leafref": {
+                 "path": "../../../constituent-vnfd/member-vnf-index"
+                }
+               }
+              },
+              "vnfd-id-ref": {
+               "description": "Identifier for the VNFD.",
+               "type": {
+                "leafref": {
+                 "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                }
+               }
+              }
+             }
+            }
+           }
+          },
+          "vnf-dependency": {
+           "description": "List of VNF dependencies.",
+           "key": "vnf-source-ref",
+           "leaf": {
+            "vnf-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            },
+            "vnf-depends-on-ref": {
+             "description": "Reference to VNF that sorce VNF depends.",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            }
+           }
+          },
+          "vnffgd": {
+           "description": "List of VNF Forwarding Graph Descriptors (VNFFGD).",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VNFFGD.",
+             "type": "string"
+            },
+            "name": {
+             "description": "VNFFGD name.",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name for VNFFGD for UI",
+             "type": "string"
+            },
+            "vendor": {
+             "description": "Provider of the VNFFGD.",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VNFFGD.",
+             "type": "string"
+            },
+            "version": {
+             "description": "Version of the VNFFGD",
+             "type": "string"
+            }
+           },
+           "list": {
+            "rsp": {
+             "description": "List of Rendered Service Paths (RSP).",
+             "key": "id",
+             "leaf": {
+              "id": {
+               "description": "Identifier for the RSP.",
+               "type": "string"
+              },
+              "name": {
+               "description": "RSP name.",
+               "type": "string"
+              }
+             },
+             "list": {
+              "vnfd-connection-point-ref": {
+               "description": "A list of references to connection points.",
+               "key": "member-vnf-index-ref",
+               "leaf": {
+                "member-vnf-index-ref": {
+                 "description": "Reference to member-vnf within constituent-vnfds",
+                 "type": {
+                  "leafref": {
+                   "path": "../../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                  }
+                 }
+                },
+                "order": {
+                 "type": "uint8",
+                 "description": "A number that denotes the order of a VNF in a chain"
+                },
+                "vnfd-id-ref": {
+                 "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+                 "type": "string"
+                },
+                "vnfd-connection-point-ref": {
+                 "description": "A reference to a connection point name\nin a vnfd. This is a leafref to path:\n    /vnfd:vnfd-catalog/vnfd:vnfd\n    + [vnfd:id = current()/../nsd:vnfd-id-ref]\n    + /vnfd:connection-point/vnfd:name\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+                 "type": "string"
+                }
+               }
+              }
+             }
+            },
+            "classifier": {
+             "description": "List of classifier rules.",
+             "key": "id",
+             "leaf": {
+              "id": {
+               "description": "Identifier for the classifier rule.",
+               "type": "string"
+              },
+              "name": {
+               "description": "Name of the classifier.",
+               "type": "string"
+              },
+              "rsp-id-ref": {
+               "description": "A reference to the RSP.",
+               "type": {
+                "leafref": {
+                 "path": "../../nsd:rsp/nsd:id"
+                }
+               }
+              },
+              "member-vnf-index-ref": {
+               "description": "Reference to member-vnf within constituent-vnfds",
+               "type": {
+                "leafref": {
+                 "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                }
+               }
+              },
+              "vnfd-id-ref": {
+               "description": "A reference to a vnfd. This is a\n   leafref to path:\n       ../../../nsd:constituent-vnfd\n       + [nsd:id = current()/../nsd:id-ref]\n       + /nsd:vnfd-id-ref\n   NOTE: An issue with confd is preventing the\n   use of xpath. Seems to be an issue with leafref\n   to leafref, whose target is in a different module.\n   Once that is resovled this will switched to use\n   leafref",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "A reference to a connection point name\n   in a vnfd. This is a leafref to path:\n       /vnfd:vnfd-catalog/vnfd:vnfd\n       + [vnfd:id = current()/../nsd:vnfd-id-ref]\n       + /vnfd:connection-point/vnfd:name\n   NOTE: An issue with confd is preventing the\n   use of xpath. Seems to be an issue with leafref\n   to leafref, whose target is in a different module.\n   Once that is resovled this will switched to use\n   leafref",
+               "type": "string"
+              }
+             },
+             "list": {
+              "match-attributes": {
+               "description": "List of match attributes.",
+               "key": "id",
+               "leaf": {
+                "id": {
+                 "description": "Identifier for the classifier match attribute rule.",
+                 "type": "string"
+                },
+                "ip-proto": {
+                 "description": "IP Protocol.",
+                 "type": "uint8"
+                },
+                "source-ip-address": {
+                 "description": "Source IP address.",
+                 "type": "inet:ip-address"
+                },
+                "destination-ip-address": {
+                 "description": "Destination IP address.",
+                 "type": "inet:ip-address"
+                },
+                "source-port": {
+                 "description": "Source port number.",
+                 "type": "inet:port-number"
+                },
+                "destination-port": {
+                 "description": "Destination port number.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            }
+           }
+          },
+          "parameter-pool": {
+           "description": "Pool of parameter values which must be\npulled from during configuration",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the configuration value pool",
+             "type": "string"
+            }
+           },
+           "container": {
+            "range": {
+             "description": "Create a range of values to populate the pool with",
+             "leaf": {
+              "start-value": {
+               "description": "Generated pool values start at this value",
+               "type": "uint32",
+               "mandatory": "true"
+              },
+              "end-value": {
+               "description": "Generated pool values stop at this value",
+               "type": "uint32",
+               "mandatory": "true"
+              }
+             }
+            }
+           }
+          }
+         },
+         "uses": {
+          "manotypes:monitoring-param": null,
+          "manotypes:input-parameter-xpath": null,
+          "manotypes:config-primitive": null
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "rw-pb-ext": {
+   "module": {
+    "rw-pb-ext": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-pb-ext",
+     "prefix": "rwpb",
+     "revision": {
+      "2014-03-28": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang extensions for converting yang files to Google\nProtocol Buffers (protobuf) using rift protoc-c extensions."
+      }
+     }
+    }
+   }
+  },
+  "vld": {
+   "module": {
+    "vld": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vld",
+     "prefix": "vld",
+     "import": {
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "vnfd": {
+       "prefix": "vnfd"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "mano-types": {
+       "prefix": "manotypes"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Link Descriptor (VLD)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "container": {
+      "vld-catalog": {
+       "list": {
+        "vld": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VLD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "Virtual Link Descriptor (VLD) name.",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "Short name for VLD for UI",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Provider of the VLD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VLD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VLD",
+           "type": "string"
+          },
+          "type": {
+           "type": "manotypes:virtual-link-type"
+          },
+          "root-bandwidth": {
+           "description": "For ELAN this is the aggregate bandwidth.",
+           "type": "uint64"
+          },
+          "leaf-bandwidth": {
+           "description": "For ELAN this is the bandwidth of branches.",
+           "type": "uint64"
+          }
+         },
+         "list": {
+          "vnfd-connection-point-ref": {
+           "description": "A list of references to connection points.",
+           "key": "vnfd-ref member-vnf-index-ref",
+           "leaf": {
+            "vnfd-ref": {
+             "description": "A reference to a vnfd",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            },
+            "member-vnf-index-ref": {
+             "description": "A reference to the consituent-vnfd id in nsd.\nShould have been a leafref to:\n '/nsd:nsd-catalog:/nsd:nsd/constituent-vnfd/member-vnf-index-ref'.\nInstead using direct leaf to avoid circular reference.",
+             "type": "uint64"
+            },
+            "vnfd-connection-point-ref": {
+             "description": "A reference to a connection point name in a vnfd",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id = current()/../vld:vnfd-ref]/vnfd:connection-point/vnfd:name"
+              }
+             }
+            }
+           }
+          }
+         },
+         "container": {
+          "provider-network": {
+           "description": "Container for the provider network.",
+           "leaf": {
+            "physical-network": {
+             "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+             "type": "string"
+            },
+            "overlay-type": {
+             "description": "Type of the overlay network.",
+             "type": {
+              "enumeration": {
+               "enum": {
+                "LOCAL": {
+                 "value": 0
+                },
+                "FLAT": {
+                 "value": 1
+                },
+                "VLAN": {
+                 "value": 2
+                },
+                "VXLAN": {
+                 "value": 3
+                },
+                "GRE": {
+                 "value": 4
+                }
+               }
+              }
+             }
+            },
+            "segmentation_id": {
+             "description": "Segmentation ID",
+             "type": "uint32"
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "vnfd": {
+   "module": {
+    "vnfd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vnfd",
+     "prefix": "vnfd",
+     "import": {
+      "mano-types": {
+       "prefix": "manotypes"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Network Function (VNF)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "grouping": {
+      "common-connection-point": {
+       "leaf": {
+        "name": {
+         "description": "Name of the connection point",
+         "type": "string"
+        },
+        "id": {
+         "description": "Identifier for the internal connection points",
+         "type": "string"
+        },
+        "short-name": {
+         "description": "Short name of the connection point",
+         "type": "string"
+        },
+        "type": {
+         "description": "Type of the connection point.",
+         "type": "manotypes:connection-point-type"
+        }
+       }
+      },
+      "virtual-interface": {
+       "container": {
+        "virtual-interface": {
+         "description": "Container for the virtual interface properties",
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "OM-MGMT": {
+               "value": 0
+              },
+              "PCI-PASSTHROUGH": {
+               "value": 1
+              },
+              "SR-IOV": {
+               "value": 2
+              },
+              "VIRTIO": {
+               "value": 3
+              }
+             }
+            }
+           },
+           "default": "VIRTIO"
+          },
+          "vpci": {
+           "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+           "type": "string"
+          },
+          "bandwidth": {
+           "description": "Aggregate bandwidth of the NIC.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "vnfd-catalog": {
+       "description": "Virtual Network Function Descriptor (VNFD).",
+       "list": {
+        "vnfd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VNFD.",
+           "type": "string"
+          },
+          "name": {
+           "description": "VNFD name.",
+           "mandatory": true,
+           "type": "string"
+          },
+          "short-name": {
+           "description": "VNFD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the VNFD.",
+           "type": "string"
+          },
+          "logo": {
+           "description": "Vendor logo for the Virtual Network Function",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VNFD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VNFD",
+           "type": "string"
+          },
+          "service-function-chain": {
+           "description": "Type of node in Service Function Chaining Architecture",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "UNAWARE": {
+               "value": 0
+              },
+              "CLASSIFIER": {
+               "value": 1
+              },
+              "SF": {
+               "value": 2
+              },
+              "SFF": {
+               "value": 3
+              }
+             }
+            }
+           },
+           "default": "UNAWARE"
+          },
+          "service-function-type": {
+           "description": "Type of Service Function.\nNOTE: This needs to map with Service Function Type in ODL to\nsupport VNFFG. Service Function Type is manadatory param in ODL\nSFC. This is temporarily set to string for ease of use",
+           "type": "string"
+          }
+         },
+         "container": {
+          "mgmt-interface": {
+           "description": "Interface over which the VNF is managed.",
+           "choice": {
+            "endpoint-type": {
+             "description": "Indicates the type of management endpoint.",
+             "case": {
+              "ip": {
+               "description": "Specifies the static IP address for managing the VNF.",
+               "leaf": {
+                "ip-address": {
+                 "type": "inet:ip-address"
+                }
+               }
+              },
+              "vdu-id": {
+               "description": "Use the default management interface on this VDU.",
+               "leaf": {
+                "vdu-id": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                  }
+                 }
+                }
+               }
+              },
+              "cp": {
+               "description": "Use the ip address associated with this connection point.",
+               "leaf": {
+                "cp": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           },
+           "leaf": {
+            "port": {
+             "description": "Port for the management interface.",
+             "type": "inet:port-number"
+            }
+           },
+           "container": {
+            "dashboard-params": {
+             "description": "Parameters for the VNF dashboard",
+             "leaf": {
+              "path": {
+               "description": "The HTTP path for the dashboard",
+               "type": "string"
+              },
+              "https": {
+               "description": "Pick HTTPS instead of HTTP , Default is false",
+               "type": "boolean"
+              },
+              "port": {
+               "description": "The HTTP port for the dashboard",
+               "type": "inet:port-number"
+              }
+             }
+            },
+            "vnf-configuration": {
+             "description": "Information regarding the VNF configuration\nis captured here. ",
+             "choice": {
+              "config-method": {
+               "description": "Defines the configuration method for the VNF.",
+               "case": {
+                "netconf": {
+                 "description": "Use NETCONF for configuring the VNF.",
+                 "container": {
+                  "netconf": {
+                   "leaf": {
+                    "target": {
+                     "description": "Netconf configuration target",
+                     "type": {
+                      "enumeration": {
+                       "enum": {
+                        "running": {
+                         "value": 0
+                        },
+                        "candidate": {
+                         "value": 1
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "protocol": {
+                     "description": "Protocol to use for netconf (e.g. ssh)",
+                     "type": {
+                      "enumeration": {
+                       "enum": {
+                        "None": {
+                         "value": 0
+                        },
+                        "ssh": {
+                         "value": 1
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "port": {
+                     "description": "Port for the netconf server.",
+                     "type": "inet:port-number"
+                    }
+                   }
+                  }
+                 }
+                },
+                "rest": {
+                 "description": "Use REST for configuring the VNF.",
+                 "container": {
+                  "rest": {
+                   "leaf": {
+                    "port": {
+                     "description": "Port for the REST server.",
+                     "type": "inet:port-number"
+                    }
+                   }
+                  }
+                 }
+                },
+                "script": {
+                 "description": "Use custom script for configuring the VNF.\nThis script is executed in the context of\nOrchestrator.",
+                 "container": {
+                  "script": {
+                   "leaf": {
+                    "script-type": {
+                     "description": "Script type - currently supported : bash, expect",
+                     "type": {
+                      "enumeration": {
+                       "enum": {
+                        "bash": {
+                         "value": 0
+                        },
+                        "expect": {
+                         "value": 1
+                        }
+                       }
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                },
+                "juju": {
+                 "description": "Configure the VNF through Juju.",
+                 "container": {
+                  "juju": {
+                   "leaf": {
+                    "charm": {
+                     "description": "Juju charm to use with the VNF.",
+                     "type": "string"
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             },
+             "container": {
+              "config-access": {
+               "leaf": {
+                "mgmt-ip-address": {
+                 "description": "IP address to be used to configure this VNF,\noptional if it is possible to resolve dynamically.",
+                 "type": "inet:ip-address"
+                },
+                "username": {
+                 "description": "username for configuration.",
+                 "type": "string"
+                },
+                "password": {
+                 "description": "Password for configuration access authentication.",
+                 "type": "string"
+                }
+               }
+              },
+              "config-attributes": {
+               "description": "Miscelaneous input parameters to be considered\nwhile processing the NSD to apply configuration",
+               "leaf": {
+                "config-priority": {
+                 "description": "Configuration priority - order of confgiration\nto be applied to each VNF in this NS,\nlow number gets precedence over high number",
+                 "type": "uint64"
+                },
+                "config-delay": {
+                 "description": "Wait (seconds) before applying the configuration to VNF",
+                 "type": "uint64"
+                }
+               }
+              }
+             },
+             "list": {
+              "config-primitive": {
+               "description": "List of configuration primitives supported by the\nconfiguration agent for this VNF.",
+               "key": "name",
+               "leaf": {
+                "name": {
+                 "description": "Name of the configuration primitive.",
+                 "type": "string"
+                }
+               },
+               "list": {
+                "parameter": {
+                 "description": "List of parameters to the configuration primitive.",
+                 "key": "name",
+                 "leaf": {
+                  "name": {
+                   "description": "Name of the parameter.",
+                   "type": "string"
+                  },
+                  "data-type": {
+                   "description": "Data type associated with the name.",
+                   "type": "manotypes:parameter-data-type"
+                  },
+                  "mandatory": {
+                   "description": "Is this field mandatory",
+                   "type": "boolean",
+                   "default": "false"
+                  },
+                  "default-value": {
+                   "description": "The default value for this field",
+                   "type": "string"
+                  },
+                  "parameter-pool": {
+                   "description": "NSD Parameter pool name to use for this paramter",
+                   "type": "string"
+                  },
+                  "read-only": {
+                   "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+                   "type": "boolean"
+                  },
+                  "hidden": {
+                   "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+                   "type": "boolean"
+                  }
+                 }
+                }
+               }
+              },
+              "initial-config-primitive": {
+               "description": "Initial set of configuration primitives.",
+               "key": "seq",
+               "leaf": {
+                "seq": {
+                 "description": "Sequence number for the configuration primitive.",
+                 "type": "uint64"
+                },
+                "name": {
+                 "description": "Name of the configuration primitive.",
+                 "type": "string"
+                }
+               },
+               "list": {
+                "parameter": {
+                 "key": "name",
+                 "leaf": {
+                  "name": {
+                   "type": "string"
+                  },
+                  "value": {
+                   "type": "string"
+                  }
+                 }
+                }
+               }
+              }
+             },
+             "leaf": {
+              "config-template": {
+               "description": "Configuration template for each VNF",
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "internal-vld": {
+           "key": "id",
+           "description": "List of Internal Virtual Link Descriptors (VLD).\nThe internal VLD describes the basic topology of\nthe connectivity (e.g. E-LAN, E-Line, E-Tree)\nbetween internal VNF components of the system.",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD",
+             "type": "string"
+            },
+            "name": {
+             "description": "Name of the internal VLD",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the internal VLD",
+             "type": "string"
+            },
+            "description": {
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "leaf-list": {
+            "internal-connection-point-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/internal-connection-point/id"
+              }
+             }
+            }
+           },
+           "container": {
+            "provider-network": {
+             "description": "Container for the provider network.",
+             "leaf": {
+              "physical-network": {
+               "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+               "type": "string"
+              },
+              "overlay-type": {
+               "description": "Type of the overlay network.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "LOCAL": {
+                   "value": 0
+                  },
+                  "FLAT": {
+                   "value": 1
+                  },
+                  "VLAN": {
+                   "value": 2
+                  },
+                  "VXLAN": {
+                   "value": 3
+                  },
+                  "GRE": {
+                   "value": 4
+                  }
+                 }
+                }
+               }
+              },
+              "segmentation_id": {
+               "description": "Segmentation ID",
+               "type": "uint32"
+              }
+             }
+            }
+           }
+          },
+          "connection-point": {
+           "key": "name",
+           "description": "List for external connection points. Each VNF has one\nor more external connection points. As the name\nimplies that external connection points are used for\nconnecting the VNF to other VNFs or to external networks.\nEach VNF exposes these connection points to the\norchestrator. The orchestrator can construct network\nservices by connecting the connection points between\ndifferent VNFs. The NFVO will use VLDs and VNFFGs at\nthe network service level to construct network services.",
+           "leaf": {
+            "name": {
+             "description": "Name of the connection point",
+             "type": "string"
+            },
+            "id": {
+             "description": "Identifier for the internal connection points",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the connection point",
+             "type": "string"
+            },
+            "type": {
+             "description": "Type of the connection point.",
+             "type": "manotypes:connection-point-type"
+            }
+           }
+          },
+          "vdu": {
+           "description": "List of Virtual Deployment Units",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Unique id for the VDU",
+             "type": "string"
+            },
+            "name": {
+             "description": "Unique name for the VDU",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VDU.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of instances of VDU",
+             "type": "uint64"
+            },
+            "mgmt-vpci": {
+             "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+             "type": "string"
+            },
+            "image": {
+             "description": "Image name for the software image.\nIf the image name is found within the VNF packaage it will\nbe uploaded to all cloud accounts during onboarding process.\nOtherwise, the image must be added to the cloud account with\nthe same name as entered here.\n",
+             "mandatory": true,
+             "type": "string"
+            },
+            "image-checksum": {
+             "description": "Image md5sum for the software image.\nThe md5sum, if provided, along with the image name uniquely\nidentifies an image uploaded to the CAL.\n",
+             "type": "string"
+            },
+            "cloud-init": {
+             "description": "Content of cloud-init script",
+             "type": "string"
+            }
+           },
+           "uses": {},
+           "list": {
+            "alarm": {
+             "key": "alarm-id",
+             "leaf": {
+              "alarm-id": {
+               "description": "This field is reserved for the identifier assigned by the cloud\nprovider",
+               "type": "string"
+              },
+              "name": {
+               "description": "A human readable string to identify the alarm",
+               "type": "string"
+              },
+              "description": {
+               "description": "A string containing a description of this alarm",
+               "type": "string"
+              },
+              "vdur-id": {
+               "description": "The identifier of the VDUR that the alarm is associated with",
+               "type": "string"
+              },
+              "repeat": {
+               "description": "This flag indicates whether the alarm should be repeatedly emitted\nwhile the associated threshold has been crossed.",
+               "type": "boolean",
+               "default": "true"
+              },
+              "enabled": {
+               "description": "This flag indicates whether the alarm has been enabled or\ndisabled.",
+               "type": "boolean",
+               "default": "true"
+              },
+              "severity": {
+               "description": "A measure of the important or urgency of the alarm",
+               "type": "manotypes:alarm-severity-type"
+              },
+              "metric": {
+               "description": "The metric to be tracked by this alarm.",
+               "type": "manotypes:alarm-metric-type"
+              },
+              "statistic": {
+               "description": "The type of metric statistic that is tracked by this alarm",
+               "type": "manotypes:alarm-statistic-type"
+              },
+              "operation": {
+               "description": "The relational operator that defines whether the alarm should be\ntriggered when the metric statistic is, say, above or below the\nspecified threshold value.",
+               "type": "manotypes:alarm-operation-type"
+              },
+              "value": {
+               "description": "This value defines the threshold that, if crossed, will trigger\nthe alarm.",
+               "type": {
+                "decimal64": {
+                 "fraction-digits": "4"
+                }
+               }
+              },
+              "period": {
+               "description": "The period defines the length of time (seconds) that the metric\ndata are collected over in oreder to evaluate the chosen\nstatistic.",
+               "type": "uint32"
+              },
+              "evaluations": {
+               "description": "This is the number of samples of the metric statistic used to\nevaluate threshold crossing. Each sample or evaluation is equal to\nthe metric statistic obtained for a given period. This can be used\nto mitigate spikes in the metric that may skew the statistic of\ninterest.",
+               "type": "uint32"
+              }
+             },
+             "container": {
+              "actions": {
+               "list": {
+                "ok": {
+                 "key": "url",
+                 "leaf": {
+                  "url": {
+                   "type": "string"
+                  }
+                 }
+                },
+                "insufficient-data": {
+                 "key": "url",
+                 "leaf": {
+                  "url": {
+                   "type": "string"
+                  }
+                 }
+                },
+                "alarm": {
+                 "key": "url",
+                 "leaf": {
+                  "url": {
+                   "type": "string"
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "internal-connection-point": {
+             "key": "id",
+             "description": "List for internal connection points. Each VNFC\nhas zero or more internal connection points.\nInternal connection points are used for connecting\nthe VNF components internal to the VNF. If a VNF\nhas only one VNFC, it may not have any internal\nconnection points.",
+             "leaf": {
+              "internal-vld-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../internal-vld/id"
+                }
+               }
+              },
+              "name": {
+               "description": "Name of the connection point",
+               "type": "string"
+              },
+              "id": {
+               "description": "Identifier for the internal connection points",
+               "type": "string"
+              },
+              "short-name": {
+               "description": "Short name of the connection point",
+               "type": "string"
+              },
+              "type": {
+               "description": "Type of the connection point.",
+               "type": "manotypes:connection-point-type"
+              }
+             }
+            },
+            "internal-interface": {
+             "description": "List of internal interfaces for the VNF",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of internal interface. Note that this\nname has only local significance to the VDU.",
+               "type": "string"
+              },
+              "vdu-internal-connection-point-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../internal-connection-point/id"
+                }
+               }
+              }
+             },
+             "container": {
+              "virtual-interface": {
+               "description": "Container for the virtual interface properties",
+               "leaf": {
+                "type": {
+                 "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "OM-MGMT": {
+                     "value": 0
+                    },
+                    "PCI-PASSTHROUGH": {
+                     "value": 1
+                    },
+                    "SR-IOV": {
+                     "value": 2
+                    },
+                    "VIRTIO": {
+                     "value": 3
+                    }
+                   }
+                  }
+                 },
+                 "default": "VIRTIO"
+                },
+                "vpci": {
+                 "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+                 "type": "string"
+                },
+                "bandwidth": {
+                 "description": "Aggregate bandwidth of the NIC.",
+                 "type": "uint64"
+                }
+               }
+              }
+             }
+            },
+            "external-interface": {
+             "description": "List of external interfaces for the VNF.\nThe external interfaces enable sending\ntraffic to and from VNF.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the external interface. Note that\nthis name has only local significance.",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "Name of the external connection point.",
+               "type": {
+                "leafref": {
+                 "path": "../../../connection-point/name"
+                }
+               }
+              }
+             },
+             "container": {
+              "virtual-interface": {
+               "description": "Container for the virtual interface properties",
+               "leaf": {
+                "type": {
+                 "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "OM-MGMT": {
+                     "value": 0
+                    },
+                    "PCI-PASSTHROUGH": {
+                     "value": 1
+                    },
+                    "SR-IOV": {
+                     "value": 2
+                    },
+                    "VIRTIO": {
+                     "value": 3
+                    }
+                   }
+                  }
+                 },
+                 "default": "VIRTIO"
+                },
+                "vpci": {
+                 "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+                 "type": "string"
+                },
+                "bandwidth": {
+                 "description": "Aggregate bandwidth of the NIC.",
+                 "type": "uint64"
+                }
+               }
+              }
+             }
+            }
+           },
+           "container": {
+            "vm-flavor": {
+             "leaf": {
+              "vcpu-count": {
+               "description": "Number of vcpus for the VM.",
+               "type": "uint16"
+              },
+              "memory-mb": {
+               "description": "Amount of memory in MB.",
+               "type": "uint64"
+              },
+              "storage-gb": {
+               "description": "Amount of disk space in GB.",
+               "type": "uint64"
+              }
+             }
+            },
+            "guest-epa": {
+             "leaf": {
+              "trusted-execution": {
+               "description": "This VM should be allocated from trusted pool",
+               "type": "boolean"
+              },
+              "mempage-size": {
+               "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "LARGE": {
+                   "value": 0
+                  },
+                  "SMALL": {
+                   "value": 1
+                  },
+                  "SIZE_2MB": {
+                   "value": 2
+                  },
+                  "SIZE_1GB": {
+                   "value": 3
+                  },
+                  "PREFER_LARGE": {
+                   "value": 4
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-pinning-policy": {
+               "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "DEDICATED": {
+                   "value": 0
+                  },
+                  "SHARED": {
+                   "value": 1
+                  },
+                  "ANY": {
+                   "value": 2
+                  }
+                 }
+                }
+               },
+               "default": "ANY"
+              },
+              "cpu-thread-pinning-policy": {
+               "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "AVOID": {
+                   "value": 0
+                  },
+                  "SEPARATE": {
+                   "value": 1
+                  },
+                  "ISOLATE": {
+                   "value": 2
+                  },
+                  "PREFER": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              }
+             },
+             "list": {
+              "pcie-device": {
+               "description": "List of pcie passthrough devices.",
+               "key": "device-id",
+               "leaf": {
+                "device-id": {
+                 "description": "Device identifier.",
+                 "type": "string"
+                },
+                "count": {
+                 "description": "Number of devices to attach to the VM.",
+                 "type": "uint64"
+                }
+               }
+              }
+             },
+             "choice": {
+              "numa-policy": {
+               "case": {
+                "numa-unware": {
+                 "leaf": {
+                  "numa-unware": {
+                   "type": "empty"
+                  }
+                 }
+                },
+                "numa-aware": {
+                 "container": {
+                  "numa-node-policy": {
+                   "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+                   "leaf": {
+                    "node-cnt": {
+                     "description": "The number of numa nodes to expose to the VM.",
+                     "type": "uint16"
+                    },
+                    "mem-policy": {
+                     "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                     "type": {
+                      "enumeration": {
+                       "enum": {
+                        "STRICT": {
+                         "value": 0
+                        },
+                        "PREFERRED": {
+                         "value": 1
+                        }
+                       }
+                      }
+                     }
+                    }
+                   },
+                   "list": {
+                    "node": {
+                     "key": "id",
+                     "leaf": {
+                      "id": {
+                       "description": "NUMA node identification. Typically\nit's 0 or 1",
+                       "type": "uint64"
+                      },
+                      "memory-mb": {
+                       "description": "Memory size expressed in MB\nfor this NUMA node.",
+                       "type": "uint64"
+                      }
+                     },
+                     "leaf-list": {
+                      "vcpu": {
+                       "description": "List of vcpus to allocate on\nthis numa node.",
+                       "type": "uint64"
+                      }
+                     },
+                     "choice": {
+                      "om-numa-type": {
+                       "description": "Openmano Numa type selection",
+                       "case": {
+                        "cores": {
+                         "leaf": {
+                          "num-cores": {
+                           "type": "uint8"
+                          }
+                         }
+                        },
+                        "paired-threads": {
+                         "container": {
+                          "paired-threads": {
+                           "leaf": {
+                            "num-paired-threads": {
+                             "type": "uint8"
+                            }
+                           },
+                           "list": {
+                            "paired-thread-ids": {
+                             "description": "List of thread pairs to use in case of paired-thread numa",
+                             "max-elements": 16,
+                             "key": "thread-a",
+                             "leaf": {
+                              "thread-a": {
+                               "type": "uint8"
+                              },
+                              "thread-b": {
+                               "type": "uint8"
+                              }
+                             }
+                            }
+                           }
+                          }
+                         }
+                        },
+                        "threads": {
+                         "leaf": {
+                          "num-threads": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "vswitch-epa": {
+             "leaf": {
+              "ovs-acceleration": {
+               "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "MANDATORY": {
+                   "value": 0
+                  },
+                  "PREFERRED": {
+                   "value": 1
+                  },
+                  "DISABLED": {
+                   "value": 2
+                  }
+                 }
+                }
+               }
+              },
+              "ovs-offload": {
+               "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "MANDATORY": {
+                   "value": 0
+                  },
+                  "PREFERRED": {
+                   "value": 1
+                  },
+                  "DISABLED": {
+                   "value": 2
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "hypervisor-epa": {
+             "leaf": {
+              "type": {
+               "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_KVM": {
+                   "value": 0
+                  },
+                  "REQUIRE_KVM": {
+                   "value": 1
+                  }
+                 }
+                }
+               }
+              },
+              "version": {
+               "type": "string"
+              }
+             }
+            },
+            "host-epa": {
+             "description": "Specifies the host level EPA attributes.",
+             "leaf": {
+              "cpu-model": {
+               "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_WESTMERE": {
+                   "value": 0
+                  },
+                  "REQUIRE_WESTMERE": {
+                   "value": 1
+                  },
+                  "PREFER_SANDYBRIDGE": {
+                   "value": 2
+                  },
+                  "REQUIRE_SANDYBRIDGE": {
+                   "value": 3
+                  },
+                  "PREFER_IVYBRIDGE": {
+                   "value": 4
+                  },
+                  "REQUIRE_IVYBRIDGE": {
+                   "value": 5
+                  },
+                  "PREFER_HASWELL": {
+                   "value": 6
+                  },
+                  "REQUIRE_HASWELL": {
+                   "value": 7
+                  },
+                  "PREFER_BROADWELL": {
+                   "value": 8
+                  },
+                  "REQUIRE_BROADWELL": {
+                   "value": 9
+                  },
+                  "PREFER_NEHALEM": {
+                   "value": 10
+                  },
+                  "REQUIRE_NEHALEM": {
+                   "value": 11
+                  },
+                  "PREFER_PENRYN": {
+                   "value": 12
+                  },
+                  "REQUIRE_PENRYN": {
+                   "value": 13
+                  },
+                  "PREFER_CONROE": {
+                   "value": 14
+                  },
+                  "REQUIRE_CONROE": {
+                   "value": 15
+                  },
+                  "PREFER_CORE2DUO": {
+                   "value": 16
+                  },
+                  "REQUIRE_CORE2DUO": {
+                   "value": 17
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-arch": {
+               "description": "Host CPU architecture.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_X86": {
+                   "value": 0
+                  },
+                  "REQUIRE_X86": {
+                   "value": 1
+                  },
+                  "PREFER_X86_64": {
+                   "value": 2
+                  },
+                  "REQUIRE_X86_64": {
+                   "value": 3
+                  },
+                  "PREFER_I686": {
+                   "value": 4
+                  },
+                  "REQUIRE_I686": {
+                   "value": 5
+                  },
+                  "PREFER_IA64": {
+                   "value": 6
+                  },
+                  "REQUIRE_IA64": {
+                   "value": 7
+                  },
+                  "PREFER_ARMV7": {
+                   "value": 8
+                  },
+                  "REQUIRE_ARMV7": {
+                   "value": 9
+                  },
+                  "PREFER_ARMV8": {
+                   "value": 10
+                  },
+                  "REQUIRE_ARMV8": {
+                   "value": 11
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-vendor": {
+               "description": "Host CPU Vendor.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_INTEL": {
+                   "value": 0
+                  },
+                  "REQUIRE_INTEL": {
+                   "value": 1
+                  },
+                  "PREFER_AMD": {
+                   "value": 2
+                  },
+                  "REQUIRE_AMD": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-socket-count": {
+               "description": "Number of sockets on the host.",
+               "type": "uint64"
+              },
+              "cpu-core-count": {
+               "description": "Number of cores on the host.",
+               "type": "uint64"
+              },
+              "cpu-core-thread-count": {
+               "description": "Number of threads per cores on the host.",
+               "type": "uint64"
+              },
+              "om-cpu-model-string": {
+               "description": "Openmano CPU model string",
+               "type": "string"
+              }
+             },
+             "leaf-list": {
+              "cpu-feature": {
+               "description": "List of CPU features.",
+               "type": "manotypes:cpu-feature-type"
+              },
+              "om-cpu-feature": {
+               "description": "Openmano CPU features",
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "vdu-dependency": {
+           "description": "List of VDU dependencies.",
+           "key": "vdu-source-ref",
+           "leaf": {
+            "vdu-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            },
+            "vdu-depends-on-ref": {
+             "description": "Reference to the VDU that\nsource VDU depends.",
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            }
+           }
+          },
+          "placement-groups": {
+           "description": "List of placement groups at VNF level",
+           "key": "name",
+           "list": {
+            "member-vdus": {
+             "description": "List of VDUs that are part of this placement group",
+             "key": "member-vdu-ref",
+             "leaf": {
+              "member-vdu-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../vdu/id"
+                }
+               }
+              }
+             }
+            }
+           },
+           "leaf": {
+            "name": {
+             "description": "Place group construct to define the compute resource placement strategy\nin cloud environment",
+             "type": "string"
+            },
+            "requirement": {
+             "description": "This is free text space used to describe the intent/rationale\nbehind this placement group. This is for human consumption only",
+             "type": "string"
+            },
+            "strategy": {
+             "description": "Strategy associated with this placement group\n  Following values are possible\n    - COLOCATION: Colocation strategy imply intent to share the physical\n                  infrastructure (hypervisor/network) among all members\n                  of this group.\n    - ISOLATION: Isolation strategy imply intent to not share the physical\n                 infrastructure (hypervisor/network) among the members\n                 of this group.\n  ",
+             "type": {
+              "enumeration": {
+               "enum": {
+                "COLOCATION": {
+                 "value": 0
+                },
+                "ISOLATION": {
+                 "value": 1
+                }
+               }
+              }
+             },
+             "default": "COLOCATION"
+            }
+           }
+          },
+          "http-endpoint": {
+           "description": "List of http endpoints to be used by monitoring params",
+           "key": "path",
+           "leaf": {
+            "path": {
+             "description": "The HTTP path on the management server",
+             "type": "string"
+            },
+            "https": {
+             "description": "Pick HTTPS instead of HTTP , Default is false",
+             "type": "boolean",
+             "default": "false"
+            },
+            "port": {
+             "description": "The HTTP port to connect to",
+             "type": "inet:port-number"
+            },
+            "username": {
+             "description": "The HTTP basic auth username",
+             "type": "string"
+            },
+            "password": {
+             "description": "The HTTP basic auth password",
+             "type": "string"
+            },
+            "polling_interval_secs": {
+             "description": "The HTTP polling interval in seconds",
+             "type": "uint8",
+             "default": "2"
+            },
+            "method": {
+             "description": "This is the method to be performed at the uri.\nGET by default for action",
+             "type": "manotypes:http-method",
+             "default": "GET"
+            }
+           },
+           "list": {
+            "headers": {
+             "description": "Custom HTTP headers to put on HTTP request",
+             "key": "key",
+             "leaf": {
+              "key": {
+               "description": "HTTP header key",
+               "type": "string"
+              },
+              "value": {
+               "description": "HTTP header value",
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "monitoring-param": {
+           "description": "List of monitoring parameters at the NS level",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "type": "string"
+            },
+            "name": {
+             "type": "string"
+            },
+            "http-endpoint-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../http-endpoint/path"
+              }
+             }
+            },
+            "json-query-method": {
+             "type": "manotypes:json-query-method",
+             "default": "NAMEKEY"
+            },
+            "description": {
+             "type": "string"
+            },
+            "group-tag": {
+             "description": "A simple tag to group monitoring parameters",
+             "type": "string"
+            },
+            "value-type": {
+             "type": "manotypes:param-value-type",
+             "default": "INT"
+            },
+            "value-integer": {
+             "description": "Current value for an integer parameter",
+             "type": "int64"
+            },
+            "value-decimal": {
+             "description": "Current value for a decimal parameter",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "4"
+              }
+             }
+            },
+            "value-string": {
+             "description": "Current value for a string parameter",
+             "type": "string"
+            },
+            "widget-type": {
+             "type": "manotypes:widget-type"
+            },
+            "units": {
+             "type": "string"
+            }
+           },
+           "container": {
+            "json-query-params": {
+             "leaf": {
+              "json-path": {
+               "description": "The jsonpath to use to extract value from JSON structure",
+               "type": "string"
+              },
+              "object-path": {
+               "description": "The objectpath to use to extract value from JSON structure",
+               "type": "string"
+              }
+             }
+            },
+            "numeric-constraints": {
+             "leaf": {
+              "min-value": {
+               "description": "Minimum value for the parameter",
+               "type": "uint64"
+              },
+              "max-value": {
+               "description": "Maxium value for the parameter",
+               "type": "uint64"
+              }
+             }
+            },
+            "text-constraints": {
+             "leaf": {
+              "min-length": {
+               "description": "Minimum string length for the parameter",
+               "type": "uint8"
+              },
+              "max-length": {
+               "description": "Maximum string length for the parameter",
+               "type": "uint8"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "mano-types": {
+   "module": {
+    "mano-types": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:mano-types",
+     "prefix": "manotypes",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      }
+     },
+     "revision": {
+      "2015-04-23": {
+       "description": "Initial revision. This YANG file defines\nthe reusable base types for VNF Management\nand Orchestration (MANO).",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "parameter-data-type": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "STRING": {
+           "value": 0
+          },
+          "INTEGER": {
+           "value": 1
+          },
+          "BOOLEAN": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "virtual-link-type": {
+       "description": "Type of virtual link\nELAN: A multipoint service connecting a set of VNFs\n// ELINE: For a simple point to point connection\n//        between a VNF and the existing network.\n// ETREE: A multipoint service connecting one or\n//        more roots and a set of leaves, but\n//        preventing inter-leaf communication.",
+       "type": {
+        "enumeration": {
+         "enum": "ELAN"
+        }
+       }
+      },
+      "http-method": {
+       "description": "Type of HTTP operation",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "POST": {
+           "value": 0
+          },
+          "PUT": {
+           "value": 1
+          },
+          "GET": {
+           "value": 2
+          },
+          "DELETE": {
+           "value": 3
+          },
+          "OPTIONS": {
+           "value": 4
+          },
+          "PATCH": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "api-type": {
+       "description": "Type of API to fetch monitoring params",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HTTP": {
+           "value": 0
+          },
+          "NETCONF": {
+           "value": 1
+          },
+          "SOAP": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "json-query-method": {
+       "description": "The method to extract a value from a JSON response\n\nNAMEKEY - Use the name as the key for a non-nested value.\nJSONPATH - Use jsonpath-rw implemenation to extract a value.\nOBJECTPATH - Use objectpath implemenation to extract a value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NAMEKEY": {
+           "value": 0
+          },
+          "JSONPATH": {
+           "value": 1
+          },
+          "OBJECTPATH": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "param-value-type": {
+       "description": "The type of the parameter value",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "INT": {
+           "value": 0
+          },
+          "DECIMAL": {
+           "value": 1
+          },
+          "STRING": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "connection-point-type": {
+       "description": "Type of connection point\nVPORT: Virtual Port\n// VNIC_ADDR: Virtual NIC Address\n// PNIC_ADDR: Physical NIC Address\n// PPORT: Phsical Port.",
+       "type": {
+        "enumeration": {
+         "enum": "VPORT"
+        }
+       }
+      },
+      "widget-type": {
+       "description": "Type of the widget, typically used by the UI.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HISTOGRAM": {
+           "value": 0
+          },
+          "BAR": {
+           "value": 1
+          },
+          "GAUGE": {
+           "value": 2
+          },
+          "SLIDER": {
+           "value": 3
+          },
+          "COUNTER": {
+           "value": 4
+          },
+          "TEXTBOX": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "cpu-feature-type": {
+       "description": "Enumeration for CPU features.\n\nAES: CPU supports advanced instruction set for\nAES (Advanced Encryption Standard).\n\nCAT: Cache Allocation Technology (CAT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to specify the amount\nof L3 cache (currently the last-level cache\nin most server and client platforms) space an\napplication can fill (as a hint to hardware\nfunctionality, certain features such as power\nmanagement may override CAT settings).\n\nCMT: Cache Monitoring Technology (CMT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to determine the\nusage of cache based on applications running\non the platform. The implementation is\ndirected at L3 cache monitoring (currently\nthe last-level cache in most server and\nclient platforms).\n\nDDIO: Intel Data Direct I/O (DDIO) enables\nEthernet server NICs and controllers talk\ndirectly to the processor cache without a\ndetour via system memory. This enumeration\nspecifies if the VM requires a DDIO\ncapable host.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "PREFER_AES": {
+           "value": 0
+          },
+          "REQUIRE_AES": {
+           "value": 1
+          },
+          "PREFER_CAT": {
+           "value": 2
+          },
+          "REQUIRE_CAT": {
+           "value": 3
+          },
+          "PREFER_CMT": {
+           "value": 4
+          },
+          "REQUIRE_CMT": {
+           "value": 5
+          },
+          "PREFER_DDIO": {
+           "value": 6
+          },
+          "REQUIRE_DDIO": {
+           "value": 7
+          },
+          "REQUIRE_VME": {
+           "value": 8
+          },
+          "PREFER_VME": {
+           "value": 9
+          },
+          "REQUIRE_DE": {
+           "value": 10
+          },
+          "PREFER_DE": {
+           "value": 11
+          },
+          "REQUIRE_PSE": {
+           "value": 12
+          },
+          "PREFER_PSE": {
+           "value": 13
+          },
+          "REQUIRE_TSC": {
+           "value": 14
+          },
+          "PREFER_TSC": {
+           "value": 15
+          },
+          "REQUIRE_MSR": {
+           "value": 16
+          },
+          "PREFER_MSR": {
+           "value": 17
+          },
+          "REQUIRE_PAE": {
+           "value": 18
+          },
+          "PREFER_PAE": {
+           "value": 19
+          },
+          "REQUIRE_MCE": {
+           "value": 20
+          },
+          "PREFER_MCE": {
+           "value": 21
+          },
+          "REQUIRE_CX8": {
+           "value": 22
+          },
+          "PREFER_CX8": {
+           "value": 23
+          },
+          "REQUIRE_APIC": {
+           "value": 24
+          },
+          "PREFER_APIC": {
+           "value": 25
+          },
+          "REQUIRE_SEP": {
+           "value": 26
+          },
+          "PREFER_SEP": {
+           "value": 27
+          },
+          "REQUIRE_MTRR": {
+           "value": 28
+          },
+          "PREFER_MTRR": {
+           "value": 29
+          },
+          "REQUIRE_PGE": {
+           "value": 30
+          },
+          "PREFER_PGE": {
+           "value": 31
+          },
+          "REQUIRE_MCA": {
+           "value": 32
+          },
+          "PREFER_MCA": {
+           "value": 33
+          },
+          "REQUIRE_CMOV": {
+           "value": 34
+          },
+          "PREFER_CMOV": {
+           "value": 35
+          },
+          "REQUIRE_PAT": {
+           "value": 36
+          },
+          "PREFER_PAT": {
+           "value": 37
+          },
+          "REQUIRE_PSE36": {
+           "value": 38
+          },
+          "PREFER_PSE36": {
+           "value": 39
+          },
+          "REQUIRE_CLFLUSH": {
+           "value": 40
+          },
+          "PREFER_CLFLUSH": {
+           "value": 41
+          },
+          "REQUIRE_DTS": {
+           "value": 42
+          },
+          "PREFER_DTS": {
+           "value": 43
+          },
+          "REQUIRE_ACPI": {
+           "value": 44
+          },
+          "PREFER_ACPI": {
+           "value": 45
+          },
+          "REQUIRE_MMX": {
+           "value": 46
+          },
+          "PREFER_MMX": {
+           "value": 47
+          },
+          "REQUIRE_FXSR": {
+           "value": 48
+          },
+          "PREFER_FXSR": {
+           "value": 49
+          },
+          "REQUIRE_SSE": {
+           "value": 50
+          },
+          "PREFER_SSE": {
+           "value": 51
+          },
+          "REQUIRE_SSE2": {
+           "value": 52
+          },
+          "PREFER_SSE2": {
+           "value": 53
+          },
+          "REQUIRE_SS": {
+           "value": 54
+          },
+          "PREFER_SS": {
+           "value": 55
+          },
+          "REQUIRE_HT": {
+           "value": 56
+          },
+          "PREFER_HT": {
+           "value": 57
+          },
+          "REQUIRE_TM": {
+           "value": 58
+          },
+          "PREFER_TM": {
+           "value": 59
+          },
+          "REQUIRE_IA64": {
+           "value": 60
+          },
+          "PREFER_IA64": {
+           "value": 61
+          },
+          "REQUIRE_PBE": {
+           "value": 62
+          },
+          "PREFER_PBE": {
+           "value": 63
+          },
+          "REQUIRE_RDTSCP": {
+           "value": 64
+          },
+          "PREFER_RDTSCP": {
+           "value": 65
+          },
+          "REQUIRE_PNI": {
+           "value": 66
+          },
+          "PREFER_PNI": {
+           "value": 67
+          },
+          "REQUIRE_PCLMULQDQ": {
+           "value": 68
+          },
+          "PREFER_PCLMULQDQ": {
+           "value": 69
+          },
+          "REQUIRE_DTES64": {
+           "value": 70
+          },
+          "PREFER_DTES64": {
+           "value": 71
+          },
+          "REQUIRE_MONITOR": {
+           "value": 72
+          },
+          "PREFER_MONITOR": {
+           "value": 73
+          },
+          "REQUIRE_DS_CPL": {
+           "value": 74
+          },
+          "PREFER_DS_CPL": {
+           "value": 75
+          },
+          "REQUIRE_VMX": {
+           "value": 76
+          },
+          "PREFER_VMX": {
+           "value": 77
+          },
+          "REQUIRE_SMX": {
+           "value": 78
+          },
+          "PREFER_SMX": {
+           "value": 79
+          },
+          "REQUIRE_EST": {
+           "value": 80
+          },
+          "PREFER_EST": {
+           "value": 81
+          },
+          "REQUIRE_TM2": {
+           "value": 82
+          },
+          "PREFER_TM2": {
+           "value": 83
+          },
+          "REQUIRE_SSSE3": {
+           "value": 84
+          },
+          "PREFER_SSSE3": {
+           "value": 85
+          },
+          "REQUIRE_CID": {
+           "value": 86
+          },
+          "PREFER_CID": {
+           "value": 87
+          },
+          "REQUIRE_FMA": {
+           "value": 88
+          },
+          "PREFER_FMA": {
+           "value": 89
+          },
+          "REQUIRE_CX16": {
+           "value": 90
+          },
+          "PREFER_CX16": {
+           "value": 91
+          },
+          "REQUIRE_XTPR": {
+           "value": 92
+          },
+          "PREFER_XTPR": {
+           "value": 93
+          },
+          "REQUIRE_PDCM": {
+           "value": 94
+          },
+          "PREFER_PDCM": {
+           "value": 95
+          },
+          "REQUIRE_PCID": {
+           "value": 96
+          },
+          "PREFER_PCID": {
+           "value": 97
+          },
+          "REQUIRE_DCA": {
+           "value": 98
+          },
+          "PREFER_DCA": {
+           "value": 99
+          },
+          "REQUIRE_SSE4_1": {
+           "value": 100
+          },
+          "PREFER_SSE4_1": {
+           "value": 101
+          },
+          "REQUIRE_SSE4_2": {
+           "value": 102
+          },
+          "PREFER_SSE4_2": {
+           "value": 103
+          },
+          "REQUIRE_X2APIC": {
+           "value": 104
+          },
+          "PREFER_X2APIC": {
+           "value": 105
+          },
+          "REQUIRE_MOVBE": {
+           "value": 106
+          },
+          "PREFER_MOVBE": {
+           "value": 107
+          },
+          "REQUIRE_POPCNT": {
+           "value": 108
+          },
+          "PREFER_POPCNT": {
+           "value": 109
+          },
+          "REQUIRE_TSC_DEADLINE_TIMER": {
+           "value": 110
+          },
+          "PREFER_TSC_DEADLINE_TIMER": {
+           "value": 111
+          },
+          "REQUIRE_XSAVE": {
+           "value": 112
+          },
+          "PREFER_XSAVE": {
+           "value": 113
+          },
+          "REQUIRE_AVX": {
+           "value": 114
+          },
+          "PREFER_AVX": {
+           "value": 115
+          },
+          "REQUIRE_F16C": {
+           "value": 116
+          },
+          "PREFER_F16C": {
+           "value": 117
+          },
+          "REQUIRE_RDRAND": {
+           "value": 118
+          },
+          "PREFER_RDRAND": {
+           "value": 119
+          },
+          "REQUIRE_FSGSBASE": {
+           "value": 120
+          },
+          "PREFER_FSGSBASE": {
+           "value": 121
+          },
+          "REQUIRE_BMI1": {
+           "value": 122
+          },
+          "PREFER_BMI1": {
+           "value": 123
+          },
+          "REQUIRE_HLE": {
+           "value": 124
+          },
+          "PREFER_HLE": {
+           "value": 125
+          },
+          "REQUIRE_AVX2": {
+           "value": 126
+          },
+          "PREFER_AVX2": {
+           "value": 127
+          },
+          "REQUIRE_SMEP": {
+           "value": 128
+          },
+          "PREFER_SMEP": {
+           "value": 129
+          },
+          "REQUIRE_BMI2": {
+           "value": 130
+          },
+          "PREFER_BMI2": {
+           "value": 131
+          },
+          "REQUIRE_ERMS": {
+           "value": 132
+          },
+          "PREFER_ERMS": {
+           "value": 133
+          },
+          "REQUIRE_INVPCID": {
+           "value": 134
+          },
+          "PREFER_INVPCID": {
+           "value": 135
+          },
+          "REQUIRE_RTM": {
+           "value": 136
+          },
+          "PREFER_RTM": {
+           "value": 137
+          },
+          "REQUIRE_MPX": {
+           "value": 138
+          },
+          "PREFER_MPX": {
+           "value": 139
+          },
+          "REQUIRE_RDSEED": {
+           "value": 140
+          },
+          "PREFER_RDSEED": {
+           "value": 141
+          },
+          "REQUIRE_ADX": {
+           "value": 142
+          },
+          "PREFER_ADX": {
+           "value": 143
+          },
+          "REQUIRE_SMAP": {
+           "value": 144
+          },
+          "PREFER_SMAP": {
+           "value": 145
+          }
+         }
+        }
+       }
+      },
+      "alarm-severity-type": {
+       "description": "An indication of the importance or ugency of the alarm",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "LOW": {
+           "value": 0
+          },
+          "MODERATE": {
+           "value": 1
+          },
+          "CRITICAL": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "alarm-metric-type": {
+       "description": "The type of metrics to register the alarm for",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "CPU_UTILIZATION": {
+           "value": 0
+          },
+          "MEMORY_UTILIZATION": {
+           "value": 1
+          },
+          "STORAGE_UTILIZATION": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "alarm-statistic-type": {
+       "description": "The type of statistic to used to measure a metric to determine\nthreshold crossing for an alarm.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "AVERAGE": {
+           "value": 0
+          },
+          "MINIMUM": {
+           "value": 1
+          },
+          "MAXIMUM": {
+           "value": 2
+          },
+          "COUNT": {
+           "value": 3
+          },
+          "SUM": {
+           "value": 4
+          }
+         }
+        }
+       }
+      },
+      "alarm-operation-type": {
+       "description": "The relational operator used to define whether an alarm should be\ntriggered when, say, the metric statistic goes above or below a\nspecified value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "GE": {
+           "value": 0
+          },
+          "LE": {
+           "value": 1
+          },
+          "GT": {
+           "value": 2
+          },
+          "LT": {
+           "value": 3
+          },
+          "EQ": {
+           "value": 4
+          }
+         }
+        }
+       }
+      },
+      "cloud-account-type": {
+       "description": "cloud account type",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "aws": {
+           "value": 0
+          },
+          "cloudsim": {
+           "value": 1
+          },
+          "cloudsim_proxy": {
+           "value": 2
+          },
+          "mock": {
+           "value": 3
+          },
+          "openmano": {
+           "value": 4
+          },
+          "openstack": {
+           "value": 5
+          },
+          "vsphere": {
+           "value": 6
+          }
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "primitive-parameter": {
+       "leaf": {
+        "name": {
+         "description": "Name of the parameter.",
+         "type": "string"
+        },
+        "data-type": {
+         "description": "Data type associated with the name.",
+         "type": "manotypes:parameter-data-type"
+        },
+        "mandatory": {
+         "description": "Is this field mandatory",
+         "type": "boolean",
+         "default": "false"
+        },
+        "default-value": {
+         "description": "The default value for this field",
+         "type": "string"
+        },
+        "parameter-pool": {
+         "description": "NSD Parameter pool name to use for this paramter",
+         "type": "string"
+        },
+        "read-only": {
+         "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+         "type": "boolean"
+        },
+        "hidden": {
+         "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+         "type": "boolean"
+        }
+       }
+      },
+      "vnf-configuration": {
+       "container": {
+        "vnf-configuration": {
+         "description": "Information regarding the VNF configuration\nis captured here. ",
+         "choice": {
+          "config-method": {
+           "description": "Defines the configuration method for the VNF.",
+           "case": {
+            "netconf": {
+             "description": "Use NETCONF for configuring the VNF.",
+             "container": {
+              "netconf": {
+               "leaf": {
+                "target": {
+                 "description": "Netconf configuration target",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "running": {
+                     "value": 0
+                    },
+                    "candidate": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                },
+                "protocol": {
+                 "description": "Protocol to use for netconf (e.g. ssh)",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "None": {
+                     "value": 0
+                    },
+                    "ssh": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                },
+                "port": {
+                 "description": "Port for the netconf server.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            },
+            "rest": {
+             "description": "Use REST for configuring the VNF.",
+             "container": {
+              "rest": {
+               "leaf": {
+                "port": {
+                 "description": "Port for the REST server.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            },
+            "script": {
+             "description": "Use custom script for configuring the VNF.\nThis script is executed in the context of\nOrchestrator.",
+             "container": {
+              "script": {
+               "leaf": {
+                "script-type": {
+                 "description": "Script type - currently supported : bash, expect",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "bash": {
+                     "value": 0
+                    },
+                    "expect": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "juju": {
+             "description": "Configure the VNF through Juju.",
+             "container": {
+              "juju": {
+               "leaf": {
+                "charm": {
+                 "description": "Juju charm to use with the VNF.",
+                 "type": "string"
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         },
+         "container": {
+          "config-access": {
+           "leaf": {
+            "mgmt-ip-address": {
+             "description": "IP address to be used to configure this VNF,\noptional if it is possible to resolve dynamically.",
+             "type": "inet:ip-address"
+            },
+            "username": {
+             "description": "username for configuration.",
+             "type": "string"
+            },
+            "password": {
+             "description": "Password for configuration access authentication.",
+             "type": "string"
+            }
+           }
+          },
+          "config-attributes": {
+           "description": "Miscelaneous input parameters to be considered\nwhile processing the NSD to apply configuration",
+           "leaf": {
+            "config-priority": {
+             "description": "Configuration priority - order of confgiration\nto be applied to each VNF in this NS,\nlow number gets precedence over high number",
+             "type": "uint64"
+            },
+            "config-delay": {
+             "description": "Wait (seconds) before applying the configuration to VNF",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "list": {
+          "config-primitive": {
+           "description": "List of configuration primitives supported by the\nconfiguration agent for this VNF.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "description": "List of parameters to the configuration primitive.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the parameter.",
+               "type": "string"
+              },
+              "data-type": {
+               "description": "Data type associated with the name.",
+               "type": "manotypes:parameter-data-type"
+              },
+              "mandatory": {
+               "description": "Is this field mandatory",
+               "type": "boolean",
+               "default": "false"
+              },
+              "default-value": {
+               "description": "The default value for this field",
+               "type": "string"
+              },
+              "parameter-pool": {
+               "description": "NSD Parameter pool name to use for this paramter",
+               "type": "string"
+              },
+              "read-only": {
+               "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              },
+              "hidden": {
+               "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              }
+             }
+            }
+           }
+          },
+          "initial-config-primitive": {
+           "description": "Initial set of configuration primitives.",
+           "key": "seq",
+           "leaf": {
+            "seq": {
+             "description": "Sequence number for the configuration primitive.",
+             "type": "uint64"
+            },
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "key": "name",
+             "leaf": {
+              "name": {
+               "type": "string"
+              },
+              "value": {
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         },
+         "leaf": {
+          "config-template": {
+           "description": "Configuration template for each VNF",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "named-value": {
+       "leaf": {
+        "name": {
+         "type": "string"
+        },
+        "value": {
+         "type": "string"
+        }
+       }
+      },
+      "vm-flavor": {
+       "container": {
+        "vm-flavor": {
+         "leaf": {
+          "vcpu-count": {
+           "description": "Number of vcpus for the VM.",
+           "type": "uint16"
+          },
+          "memory-mb": {
+           "description": "Amount of memory in MB.",
+           "type": "uint64"
+          },
+          "storage-gb": {
+           "description": "Amount of disk space in GB.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      },
+      "vswitch-epa": {
+       "container": {
+        "vswitch-epa": {
+         "leaf": {
+          "ovs-acceleration": {
+           "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          },
+          "ovs-offload": {
+           "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "hypervisor-epa": {
+       "container": {
+        "hypervisor-epa": {
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_KVM": {
+               "value": 0
+              },
+              "REQUIRE_KVM": {
+               "value": 1
+              }
+             }
+            }
+           }
+          },
+          "version": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "host-epa": {
+       "container": {
+        "host-epa": {
+         "description": "Specifies the host level EPA attributes.",
+         "leaf": {
+          "cpu-model": {
+           "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_WESTMERE": {
+               "value": 0
+              },
+              "REQUIRE_WESTMERE": {
+               "value": 1
+              },
+              "PREFER_SANDYBRIDGE": {
+               "value": 2
+              },
+              "REQUIRE_SANDYBRIDGE": {
+               "value": 3
+              },
+              "PREFER_IVYBRIDGE": {
+               "value": 4
+              },
+              "REQUIRE_IVYBRIDGE": {
+               "value": 5
+              },
+              "PREFER_HASWELL": {
+               "value": 6
+              },
+              "REQUIRE_HASWELL": {
+               "value": 7
+              },
+              "PREFER_BROADWELL": {
+               "value": 8
+              },
+              "REQUIRE_BROADWELL": {
+               "value": 9
+              },
+              "PREFER_NEHALEM": {
+               "value": 10
+              },
+              "REQUIRE_NEHALEM": {
+               "value": 11
+              },
+              "PREFER_PENRYN": {
+               "value": 12
+              },
+              "REQUIRE_PENRYN": {
+               "value": 13
+              },
+              "PREFER_CONROE": {
+               "value": 14
+              },
+              "REQUIRE_CONROE": {
+               "value": 15
+              },
+              "PREFER_CORE2DUO": {
+               "value": 16
+              },
+              "REQUIRE_CORE2DUO": {
+               "value": 17
+              }
+             }
+            }
+           }
+          },
+          "cpu-arch": {
+           "description": "Host CPU architecture.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_X86": {
+               "value": 0
+              },
+              "REQUIRE_X86": {
+               "value": 1
+              },
+              "PREFER_X86_64": {
+               "value": 2
+              },
+              "REQUIRE_X86_64": {
+               "value": 3
+              },
+              "PREFER_I686": {
+               "value": 4
+              },
+              "REQUIRE_I686": {
+               "value": 5
+              },
+              "PREFER_IA64": {
+               "value": 6
+              },
+              "REQUIRE_IA64": {
+               "value": 7
+              },
+              "PREFER_ARMV7": {
+               "value": 8
+              },
+              "REQUIRE_ARMV7": {
+               "value": 9
+              },
+              "PREFER_ARMV8": {
+               "value": 10
+              },
+              "REQUIRE_ARMV8": {
+               "value": 11
+              }
+             }
+            }
+           }
+          },
+          "cpu-vendor": {
+           "description": "Host CPU Vendor.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_INTEL": {
+               "value": 0
+              },
+              "REQUIRE_INTEL": {
+               "value": 1
+              },
+              "PREFER_AMD": {
+               "value": 2
+              },
+              "REQUIRE_AMD": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-socket-count": {
+           "description": "Number of sockets on the host.",
+           "type": "uint64"
+          },
+          "cpu-core-count": {
+           "description": "Number of cores on the host.",
+           "type": "uint64"
+          },
+          "cpu-core-thread-count": {
+           "description": "Number of threads per cores on the host.",
+           "type": "uint64"
+          },
+          "om-cpu-model-string": {
+           "description": "Openmano CPU model string",
+           "type": "string"
+          }
+         },
+         "leaf-list": {
+          "cpu-feature": {
+           "description": "List of CPU features.",
+           "type": "manotypes:cpu-feature-type"
+          },
+          "om-cpu-feature": {
+           "description": "Openmano CPU features",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "guest-epa": {
+       "description": "EPA attributes for the guest",
+       "container": {
+        "guest-epa": {
+         "leaf": {
+          "trusted-execution": {
+           "description": "This VM should be allocated from trusted pool",
+           "type": "boolean"
+          },
+          "mempage-size": {
+           "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LARGE": {
+               "value": 0
+              },
+              "SMALL": {
+               "value": 1
+              },
+              "SIZE_2MB": {
+               "value": 2
+              },
+              "SIZE_1GB": {
+               "value": 3
+              },
+              "PREFER_LARGE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "cpu-pinning-policy": {
+           "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "DEDICATED": {
+               "value": 0
+              },
+              "SHARED": {
+               "value": 1
+              },
+              "ANY": {
+               "value": 2
+              }
+             }
+            }
+           },
+           "default": "ANY"
+          },
+          "cpu-thread-pinning-policy": {
+           "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "AVOID": {
+               "value": 0
+              },
+              "SEPARATE": {
+               "value": 1
+              },
+              "ISOLATE": {
+               "value": 2
+              },
+              "PREFER": {
+               "value": 3
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "pcie-device": {
+           "description": "List of pcie passthrough devices.",
+           "key": "device-id",
+           "leaf": {
+            "device-id": {
+             "description": "Device identifier.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of devices to attach to the VM.",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "choice": {
+          "numa-policy": {
+           "case": {
+            "numa-unware": {
+             "leaf": {
+              "numa-unware": {
+               "type": "empty"
+              }
+             }
+            },
+            "numa-aware": {
+             "container": {
+              "numa-node-policy": {
+               "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+               "leaf": {
+                "node-cnt": {
+                 "description": "The number of numa nodes to expose to the VM.",
+                 "type": "uint16"
+                },
+                "mem-policy": {
+                 "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "STRICT": {
+                     "value": 0
+                    },
+                    "PREFERRED": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               },
+               "list": {
+                "node": {
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "NUMA node identification. Typically\nit's 0 or 1",
+                   "type": "uint64"
+                  },
+                  "memory-mb": {
+                   "description": "Memory size expressed in MB\nfor this NUMA node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "leaf-list": {
+                  "vcpu": {
+                   "description": "List of vcpus to allocate on\nthis numa node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "choice": {
+                  "om-numa-type": {
+                   "description": "Openmano Numa type selection",
+                   "case": {
+                    "cores": {
+                     "leaf": {
+                      "num-cores": {
+                       "type": "uint8"
+                      }
+                     }
+                    },
+                    "paired-threads": {
+                     "container": {
+                      "paired-threads": {
+                       "leaf": {
+                        "num-paired-threads": {
+                         "type": "uint8"
+                        }
+                       },
+                       "list": {
+                        "paired-thread-ids": {
+                         "description": "List of thread pairs to use in case of paired-thread numa",
+                         "max-elements": 16,
+                         "key": "thread-a",
+                         "leaf": {
+                          "thread-a": {
+                           "type": "uint8"
+                          },
+                          "thread-b": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "threads": {
+                     "leaf": {
+                      "num-threads": {
+                       "type": "uint8"
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "provider-network": {
+       "container": {
+        "provider-network": {
+         "description": "Container for the provider network.",
+         "leaf": {
+          "physical-network": {
+           "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+           "type": "string"
+          },
+          "overlay-type": {
+           "description": "Type of the overlay network.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LOCAL": {
+               "value": 0
+              },
+              "FLAT": {
+               "value": 1
+              },
+              "VLAN": {
+               "value": 2
+              },
+              "VXLAN": {
+               "value": 3
+              },
+              "GRE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "segmentation_id": {
+           "description": "Segmentation ID",
+           "type": "uint32"
+          }
+         }
+        }
+       }
+      },
+      "config-primitive": {
+       "list": {
+        "config-primitive": {
+         "description": "Network service level configuration primitives.",
+         "key": "name",
+         "leaf": {
+          "name": {
+           "description": "Name of the configuration primitive.",
+           "type": "string"
+          },
+          "user-defined-script": {
+           "description": "A user defined script.",
+           "type": "string"
+          }
+         },
+         "list": {
+          "parameter": {
+           "description": "List of parameters to the configuration primitive.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the parameter.",
+             "type": "string"
+            },
+            "data-type": {
+             "description": "Data type associated with the name.",
+             "type": "manotypes:parameter-data-type"
+            },
+            "mandatory": {
+             "description": "Is this field mandatory",
+             "type": "boolean",
+             "default": "false"
+            },
+            "default-value": {
+             "description": "The default value for this field",
+             "type": "string"
+            },
+            "parameter-pool": {
+             "description": "NSD Parameter pool name to use for this paramter",
+             "type": "string"
+            },
+            "read-only": {
+             "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+             "type": "boolean"
+            },
+            "hidden": {
+             "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+             "type": "boolean"
+            }
+           }
+          },
+          "parameter-group": {
+           "description": "Grouping of parameters which are logically grouped in UI",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the parameter group",
+             "type": "string"
+            },
+            "mandatory": {
+             "description": "Is this parameter group mandatory",
+             "type": "boolean",
+             "default": "true"
+            }
+           },
+           "list": {
+            "parameter": {
+             "description": "List of parameters to the configuration primitive.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the parameter.",
+               "type": "string"
+              },
+              "data-type": {
+               "description": "Data type associated with the name.",
+               "type": "manotypes:parameter-data-type"
+              },
+              "mandatory": {
+               "description": "Is this field mandatory",
+               "type": "boolean",
+               "default": "false"
+              },
+              "default-value": {
+               "description": "The default value for this field",
+               "type": "string"
+              },
+              "parameter-pool": {
+               "description": "NSD Parameter pool name to use for this paramter",
+               "type": "string"
+              },
+              "read-only": {
+               "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              },
+              "hidden": {
+               "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              }
+             }
+            }
+           }
+          },
+          "vnf-primitive-group": {
+           "description": "List of configuration primitives grouped by VNF.",
+           "key": "member-vnf-index-ref",
+           "leaf": {
+            "member-vnf-index-ref": {
+             "description": "Reference to member-vnf within constituent-vnfds",
+             "type": "uint64"
+            },
+            "vnfd-id-ref": {
+             "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+             "type": "string"
+            },
+            "vnfd-name": {
+             "description": "Name of the VNFD",
+             "type": "string"
+            }
+           },
+           "list": {
+            "primitive": {
+             "key": "index",
+             "leaf": {
+              "index": {
+               "description": "Index of this primitive",
+               "type": "uint32"
+              },
+              "name": {
+               "description": "Name of the primitive in the VNF primitive ",
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "monitoring-param": {
+       "list": {
+        "http-endpoint": {
+         "description": "List of http endpoints to be used by monitoring params",
+         "key": "path",
+         "leaf": {
+          "path": {
+           "description": "The HTTP path on the management server",
+           "type": "string"
+          },
+          "https": {
+           "description": "Pick HTTPS instead of HTTP , Default is false",
+           "type": "boolean",
+           "default": "false"
+          },
+          "port": {
+           "description": "The HTTP port to connect to",
+           "type": "inet:port-number"
+          },
+          "username": {
+           "description": "The HTTP basic auth username",
+           "type": "string"
+          },
+          "password": {
+           "description": "The HTTP basic auth password",
+           "type": "string"
+          },
+          "polling_interval_secs": {
+           "description": "The HTTP polling interval in seconds",
+           "type": "uint8",
+           "default": "2"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nGET by default for action",
+           "type": "manotypes:http-method",
+           "default": "GET"
+          }
+         },
+         "list": {
+          "headers": {
+           "description": "Custom HTTP headers to put on HTTP request",
+           "key": "key",
+           "leaf": {
+            "key": {
+             "description": "HTTP header key",
+             "type": "string"
+            },
+            "value": {
+             "description": "HTTP header value",
+             "type": "string"
+            }
+           }
+          }
+         }
+        },
+        "monitoring-param": {
+         "description": "List of monitoring parameters at the NS level",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "http-endpoint-ref": {
+           "type": {
+            "leafref": {
+             "path": "../../http-endpoint/path"
+            }
+           }
+          },
+          "json-query-method": {
+           "type": "manotypes:json-query-method",
+           "default": "NAMEKEY"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameters",
+           "type": "string"
+          },
+          "value-type": {
+           "type": "manotypes:param-value-type",
+           "default": "INT"
+          },
+          "value-integer": {
+           "description": "Current value for an integer parameter",
+           "type": "int64"
+          },
+          "value-decimal": {
+           "description": "Current value for a decimal parameter",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "4"
+            }
+           }
+          },
+          "value-string": {
+           "description": "Current value for a string parameter",
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "units": {
+           "type": "string"
+          }
+         },
+         "container": {
+          "json-query-params": {
+           "leaf": {
+            "json-path": {
+             "description": "The jsonpath to use to extract value from JSON structure",
+             "type": "string"
+            },
+            "object-path": {
+             "description": "The objectpath to use to extract value from JSON structure",
+             "type": "string"
+            }
+           }
+          },
+          "numeric-constraints": {
+           "leaf": {
+            "min-value": {
+             "description": "Minimum value for the parameter",
+             "type": "uint64"
+            },
+            "max-value": {
+             "description": "Maxium value for the parameter",
+             "type": "uint64"
+            }
+           }
+          },
+          "text-constraints": {
+           "leaf": {
+            "min-length": {
+             "description": "Minimum string length for the parameter",
+             "type": "uint8"
+            },
+            "max-length": {
+             "description": "Maximum string length for the parameter",
+             "type": "uint8"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "control-param": {
+       "list": {
+        "control-param": {
+         "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group control parameters",
+           "type": "string"
+          },
+          "min-value": {
+           "description": "Minimum value for the parameter",
+           "type": "uint64"
+          },
+          "max-value": {
+           "description": "Maxium value for the parameter",
+           "type": "uint64"
+          },
+          "current-value": {
+           "description": "Current value for the parameter",
+           "type": "uint64"
+          },
+          "step-value": {
+           "description": "Step value for the parameter",
+           "type": "uint64"
+          },
+          "units": {
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-param": {
+       "list": {
+        "action-param": {
+         "description": "List of action parameters to\ncontrol VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameter",
+           "type": "string"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter": {
+       "description": "",
+       "list": {
+        "input-parameter": {
+         "description": "List of input parameters",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          },
+          "value": {
+           "description": "The value that the element specified by the xpath should take when a\nrecord is created.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter-xpath": {
+       "list": {
+        "input-parameter-xpath": {
+         "description": "List of xpaths to parameters inside the NSD\nthe can be customized during the instantiation.",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "An xpath that specifies the element in a descriptor.",
+           "type": "string"
+          },
+          "label": {
+           "description": "A descriptive string",
+           "type": "string"
+          },
+          "default-value": {
+           "description": " A default value for this input parameter",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "nfvi-metrics": {
+       "container": {
+        "vcpu": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "VCPU"
+          },
+          "total": {
+           "description": "The total number of VCPUs available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The VCPU utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "memory": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "MEMORY"
+          },
+          "used": {
+           "description": "The amount of memory (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of memory (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The memory utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "storage": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "STORAGE"
+          },
+          "used": {
+           "description": "The amount of storage (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of storage (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The storage utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "external-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "EXTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of external ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "internal-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "INTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of internal ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "network": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "NETWORK TRAFFIC"
+          }
+         },
+         "container": {
+          "incoming": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "INCOMING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of incoming bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of incoming packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current incoming byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current incoming packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          },
+          "outgoing": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "OUTGOING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of outgoing bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of outgoing packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current outgoing byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current outgoing packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "alarm": {
+       "leaf": {
+        "alarm-id": {
+         "description": "This field is reserved for the identifier assigned by the cloud\nprovider",
+         "type": "string"
+        },
+        "name": {
+         "description": "A human readable string to identify the alarm",
+         "type": "string"
+        },
+        "description": {
+         "description": "A string containing a description of this alarm",
+         "type": "string"
+        },
+        "vdur-id": {
+         "description": "The identifier of the VDUR that the alarm is associated with",
+         "type": "string"
+        },
+        "repeat": {
+         "description": "This flag indicates whether the alarm should be repeatedly emitted\nwhile the associated threshold has been crossed.",
+         "type": "boolean",
+         "default": "true"
+        },
+        "enabled": {
+         "description": "This flag indicates whether the alarm has been enabled or\ndisabled.",
+         "type": "boolean",
+         "default": "true"
+        },
+        "severity": {
+         "description": "A measure of the important or urgency of the alarm",
+         "type": "manotypes:alarm-severity-type"
+        },
+        "metric": {
+         "description": "The metric to be tracked by this alarm.",
+         "type": "manotypes:alarm-metric-type"
+        },
+        "statistic": {
+         "description": "The type of metric statistic that is tracked by this alarm",
+         "type": "manotypes:alarm-statistic-type"
+        },
+        "operation": {
+         "description": "The relational operator that defines whether the alarm should be\ntriggered when the metric statistic is, say, above or below the\nspecified threshold value.",
+         "type": "manotypes:alarm-operation-type"
+        },
+        "value": {
+         "description": "This value defines the threshold that, if crossed, will trigger\nthe alarm.",
+         "type": {
+          "decimal64": {
+           "fraction-digits": "4"
+          }
+         }
+        },
+        "period": {
+         "description": "The period defines the length of time (seconds) that the metric\ndata are collected over in oreder to evaluate the chosen\nstatistic.",
+         "type": "uint32"
+        },
+        "evaluations": {
+         "description": "This is the number of samples of the metric statistic used to\nevaluate threshold crossing. Each sample or evaluation is equal to\nthe metric statistic obtained for a given period. This can be used\nto mitigate spikes in the metric that may skew the statistic of\ninterest.",
+         "type": "uint32"
+        }
+       },
+       "container": {
+        "actions": {
+         "list": {
+          "ok": {
+           "key": "url",
+           "leaf": {
+            "url": {
+             "type": "string"
+            }
+           }
+          },
+          "insufficient-data": {
+           "key": "url",
+           "leaf": {
+            "url": {
+             "type": "string"
+            }
+           }
+          },
+          "alarm": {
+           "key": "url",
+           "leaf": {
+            "url": {
+             "type": "string"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "host-aggregate": {
+       "list": {
+        "host-aggregate": {
+         "description": "Name of the Host Aggregate",
+         "key": "metadata-key",
+         "leaf": {
+          "metadata-key": {
+           "type": "string"
+          },
+          "metadata-value": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "placement-group-input": {
+       "leaf": {
+        "cloud-type": {
+         "type": "manotypes:cloud-account-type"
+        }
+       },
+       "choice": {
+        "cloud-provider": {
+         "case": {
+          "openstack": {
+           "container": {
+            "availability-zone": {
+             "description": "Name of the Availability Zone",
+             "leaf": {
+              "name": {
+               "type": "string"
+              }
+             }
+            },
+            "server-group": {
+             "description": "Name of the Affinity/Anti-Affinity Server Group",
+             "leaf": {
+              "name": {
+               "type": "string"
+              }
+             }
+            }
+           },
+           "list": {
+            "host-aggregate": {
+             "description": "Name of the Host Aggregate",
+             "key": "metadata-key",
+             "leaf": {
+              "metadata-key": {
+               "type": "string"
+              },
+              "metadata-value": {
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "aws": {
+           "leaf": {
+            "aws-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "openmano": {
+           "leaf": {
+            "openmano-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "vsphere": {
+           "leaf": {
+            "vsphere-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "mock": {
+           "leaf": {
+            "mock-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "cloudsim": {
+           "leaf": {
+            "cloudsim-construct": {
+             "type": "empty"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "placement-group-info": {
+       "description": "",
+       "leaf": {
+        "name": {
+         "description": "Place group construct to define the compute resource placement strategy\nin cloud environment",
+         "type": "string"
+        },
+        "requirement": {
+         "description": "This is free text space used to describe the intent/rationale\nbehind this placement group. This is for human consumption only",
+         "type": "string"
+        },
+        "strategy": {
+         "description": "Strategy associated with this placement group\n  Following values are possible\n    - COLOCATION: Colocation strategy imply intent to share the physical\n                  infrastructure (hypervisor/network) among all members\n                  of this group.\n    - ISOLATION: Isolation strategy imply intent to not share the physical\n                 infrastructure (hypervisor/network) among the members\n                 of this group.\n  ",
+         "type": {
+          "enumeration": {
+           "enum": {
+            "COLOCATION": {
+             "value": 0
+            },
+            "ISOLATION": {
+             "value": 1
+            }
+           }
+          }
+         },
+         "default": "COLOCATION"
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "pkgdir": "/Users/larsmaultsby/Documents/ATG_Branch/rift/modules/ui/rw.ui/skyquake/plugins/composer/src/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/json-vnfd.json b/skyquake/plugins/composer/src/schemas/yang/json-vnfd.json
new file mode 100644 (file)
index 0000000..299e3aa
--- /dev/null
@@ -0,0 +1,4508 @@
+{
+ "synth": "source",
+ "name": "rw-vnfd",
+ "schema": {
+  "module": {
+   "rw-vnfd": {
+    "namespace": "http://riftio.com/ns/riftware-1.0/rw-vnfd",
+    "prefix": "rw-vnfd",
+    "import": {
+     "vnfd": {
+      "prefix": "vnfd"
+     },
+     "rwvcs-types": {
+      "prefix": "rwvcstypes"
+     },
+     "rw-pb-ext": {
+      "prefix": "rwpb"
+     },
+     "ietf-yang-types": {
+      "prefix": "yang"
+     },
+     "mano-types": {
+      "prefix": "manotypes"
+     }
+    },
+    "revision": {
+     "2015-09-10": {
+      "description": "Initial revision. This YANG file augments\nthe base MANO VNFD",
+      "reference": "Derived from earlier versions of base YANG files"
+     }
+    },
+    "augment": {
+     "/vnfd:vnfd-catalog/vnfd:vnfd": {
+      "uses": {},
+      "leaf": {
+       "meta": {
+        "description": "Any meta-data needed by the UI",
+        "type": "string"
+       }
+      },
+      "list": {
+       "component": {
+        "description": "This section defines the RIFT.ware\nvirtual components",
+        "key": "component-name",
+        "leaf": {
+         "component-name": {
+          "description": "",
+          "type": "string"
+         },
+         "component-type": {
+          "description": "",
+          "type": "rwvcstypes:component_type",
+          "mandatory": true
+         }
+        },
+        "choice": {
+         "component": {
+          "case": {
+           "rwvcs-rwcollection": {
+            "container": {
+             "rwcollection": {
+              "description": "This section defines a RW.VCS\nrwollection component",
+              "leaf": {
+               "collection-type": {
+                "description": "Collection type",
+                "type": "string"
+               }
+              },
+              "container": {
+               "event-list": {
+                "description": "",
+                "list": {
+                 "event": {
+                  "description": "This section contains a list\nof RW.VCS events",
+                  "key": "name",
+                  "leaf": {
+                   "name": {
+                    "description": "Name of the event",
+                    "type": "string"
+                   }
+                  },
+                  "list": {
+                   "action": {
+                    "description": "This section contains a sequence\nof RW.VCS actions",
+                    "key": "name",
+                    "leaf": {
+                     "name": {
+                      "description": "Name of the action within the sequence",
+                      "type": "string"
+                     },
+                     "python-loop-expression": {
+                      "description": "Python expression",
+                      "type": "string"
+                     },
+                     "python-loop-iterate": {
+                      "description": "Python iteration",
+                      "type": "string"
+                     }
+                    },
+                    "grouping": {
+                     "rwvcs-python-loop": {
+                      "leaf": {
+                       "python-loop-expression": {
+                        "description": "Python expression",
+                        "type": "string"
+                       },
+                       "python-loop-iterate": {
+                        "description": "Python iteration",
+                        "type": "string"
+                       }
+                      }
+                     }
+                    },
+                    "choice": {
+                     "action": {
+                      "case": {
+                       "annex": {
+                        "container": {
+                         "annex": {
+                          "leaf": {
+                           "component-name": {
+                            "description": "Name of the component type\nin the inventory",
+                            "type": {
+                             "leafref": {
+                              "path": "../../../../../../../component/component-name"
+                             }
+                            }
+                           },
+                           "instance-id": {
+                            "description": "ID of the component instance\nin the inventory",
+                            "type": "string"
+                           }
+                          }
+                         }
+                        }
+                       },
+                       "start": {
+                        "container": {
+                         "start": {
+                          "leaf": {
+                           "component-name": {
+                            "description": "Name of the component type in\nthe inventory",
+                            "type": {
+                             "leafref": {
+                              "path": "../../../../../../../component/component-name"
+                             }
+                            }
+                           },
+                           "instance-id": {
+                            "description": "ID of the component instance\nin the inventory",
+                            "type": "string"
+                           },
+                           "config-ready": {
+                            "description": "Config readiness check enable",
+                            "type": "boolean",
+                            "default": "true"
+                           },
+                           "recovery-action": {
+                            "description": "Define recovery action if this component fail",
+                            "type": "recovery-type"
+                           }
+                          },
+                          "leaf-list": {
+                           "python-variable": {
+                            "description": "List of Python variable assignments",
+                            "type": "string"
+                           }
+                          }
+                         }
+                        }
+                       },
+                       "sleep": {
+                        "container": {
+                         "sleep": {
+                          "leaf": {
+                           "wait-time-usec": {
+                            "description": "Time to wait while sleeping",
+                            "type": "uint32"
+                           }
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           },
+           "rwvcs-rwvm": {
+            "container": {
+             "rwvm": {
+              "description": "This section defines a RW.VCS\nrwvm component",
+              "leaf": {
+               "pool-name": {
+                "description": "Name of the pool from which to\nallocate the VM",
+                "type": "string"
+               },
+               "leader": {
+                "description": "True if this VM is designated as a leader for\nthe parent collection.",
+                "type": "boolean"
+               }
+              },
+              "uses": {},
+              "container": {
+               "event-list": {
+                "description": "",
+                "list": {
+                 "event": {
+                  "description": "This section contains a list\nof RW.VCS events",
+                  "key": "name",
+                  "leaf": {
+                   "name": {
+                    "description": "Name of the event",
+                    "type": "string"
+                   }
+                  },
+                  "list": {
+                   "action": {
+                    "description": "This section contains a sequence\nof RW.VCS actions",
+                    "key": "name",
+                    "leaf": {
+                     "name": {
+                      "description": "Name of the action within the sequence",
+                      "type": "string"
+                     },
+                     "python-loop-expression": {
+                      "description": "Python expression",
+                      "type": "string"
+                     },
+                     "python-loop-iterate": {
+                      "description": "Python iteration",
+                      "type": "string"
+                     }
+                    },
+                    "grouping": {
+                     "rwvcs-python-loop": {
+                      "leaf": {
+                       "python-loop-expression": {
+                        "description": "Python expression",
+                        "type": "string"
+                       },
+                       "python-loop-iterate": {
+                        "description": "Python iteration",
+                        "type": "string"
+                       }
+                      }
+                     }
+                    },
+                    "choice": {
+                     "action": {
+                      "case": {
+                       "annex": {
+                        "container": {
+                         "annex": {
+                          "leaf": {
+                           "component-name": {
+                            "description": "Name of the component type\nin the inventory",
+                            "type": {
+                             "leafref": {
+                              "path": "../../../../../../../component/component-name"
+                             }
+                            }
+                           },
+                           "instance-id": {
+                            "description": "ID of the component instance\nin the inventory",
+                            "type": "string"
+                           }
+                          }
+                         }
+                        }
+                       },
+                       "start": {
+                        "container": {
+                         "start": {
+                          "leaf": {
+                           "component-name": {
+                            "description": "Name of the component type in\nthe inventory",
+                            "type": {
+                             "leafref": {
+                              "path": "../../../../../../../component/component-name"
+                             }
+                            }
+                           },
+                           "instance-id": {
+                            "description": "ID of the component instance\nin the inventory",
+                            "type": "string"
+                           },
+                           "config-ready": {
+                            "description": "Config readiness check enable",
+                            "type": "boolean",
+                            "default": "true"
+                           },
+                           "recovery-action": {
+                            "description": "Define recovery action if this component fail",
+                            "type": "recovery-type"
+                           }
+                          },
+                          "leaf-list": {
+                           "python-variable": {
+                            "description": "List of Python variable assignments",
+                            "type": "string"
+                           }
+                          }
+                         }
+                        }
+                       },
+                       "sleep": {
+                        "container": {
+                         "sleep": {
+                          "leaf": {
+                           "wait-time-usec": {
+                            "description": "Time to wait while sleeping",
+                            "type": "uint32"
+                           }
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               },
+               "valgrind": {
+                "leaf": {
+                 "enable": {
+                  "description": "Run the component under valgrind",
+                  "type": "boolean"
+                 }
+                },
+                "leaf-list": {
+                 "opts": {
+                  "description": "Command line options to pass to valgrind",
+                  "type": "string"
+                 }
+                }
+               }
+              }
+             }
+            }
+           },
+           "rwvcs-rwproc": {
+            "container": {
+             "rwproc": {
+              "description": "This section defines a RW.VCS\nrwproc component",
+              "leaf": {
+               "run-as": {
+                "description": "Host OS user that should run this\nprocess, requires sudo -E access\nand non-collapsed processes",
+                "type": "string"
+               }
+              },
+              "list": {
+               "tasklet": {
+                "description": "List of tasklets to be run within\nthis process",
+                "key": "name",
+                "leaf": {
+                 "name": {
+                  "description": "Local description of the tasklet",
+                  "type": "string"
+                 },
+                 "component-name": {
+                  "description": "Component name of the tasklet",
+                  "mandatory": true,
+                  "type": "string"
+                 },
+                 "instance-id": {
+                  "description": "If specified, the desired instance-id of\ntasklet component instance",
+                  "type": "uint32"
+                 },
+                 "config-ready": {
+                  "description": "Config readiness check enable",
+                  "type": "boolean",
+                  "default": "true"
+                 },
+                 "recovery-action": {
+                  "description": "Define recovery action if this component fail",
+                  "type": "recovery-type"
+                 }
+                },
+                "leaf-list": {
+                 "python-variable": {
+                  "description": "List of Python variable assignments",
+                  "type": "string"
+                 }
+                }
+               }
+              },
+              "container": {
+               "valgrind": {
+                "leaf": {
+                 "enable": {
+                  "description": "Run the component under valgrind",
+                  "type": "boolean"
+                 }
+                },
+                "leaf-list": {
+                 "opts": {
+                  "description": "Command line options to pass to valgrind",
+                  "type": "string"
+                 }
+                }
+               }
+              }
+             }
+            }
+           },
+           "native-proc": {
+            "container": {
+             "native-proc": {
+              "leaf": {
+               "run-as": {
+                "description": "Host OS user that should run this\nprocess, requires sudo -E access",
+                "type": "string"
+               },
+               "environment": {
+                "description": "Runtime environment for native process",
+                "type": "string"
+               },
+               "exe-path": {
+                "description": "Path to native process executable",
+                "type": "string"
+               },
+               "args": {
+                "description": "Arguments to pass to native process",
+                "type": "string"
+               },
+               "network-namespace": {
+                "description": "Namespace to start process in",
+                "type": "string"
+               },
+               "stdout": {
+                "description": "Redirect stdout to the file at the\nspecified path",
+                "type": "string"
+               },
+               "stderr": {
+                "description": "Redirect stderr to the file at the\nspecified path. Optionally, 'stdout'\nmay be used to redirect to the same\nfile as stdout",
+                "type": "string"
+               },
+               "interactive": {
+                "description": "Native process is interactive and needs\nterminal control",
+                "type": "empty"
+               }
+              },
+              "container": {
+               "valgrind": {
+                "leaf": {
+                 "enable": {
+                  "description": "Run the component under valgrind",
+                  "type": "boolean"
+                 }
+                },
+                "leaf-list": {
+                 "opts": {
+                  "description": "Command line options to pass to valgrind",
+                  "type": "string"
+                 }
+                }
+               }
+              }
+             }
+            }
+           },
+           "rwvcs-rwtasklet": {
+            "container": {
+             "rwtasklet": {
+              "description": "This section defines a RW.VCS\nrwtasklet component",
+              "leaf": {
+               "plugin-directory": {
+                "description": "",
+                "type": "string"
+               },
+               "plugin-name": {
+                "description": "",
+                "type": "string"
+               },
+               "plugin-version": {
+                "description": "",
+                "type": "string"
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       },
+       "control-param": {
+        "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group control parameters",
+          "type": "string"
+         },
+         "min-value": {
+          "description": "Minimum value for the parameter",
+          "type": "uint64"
+         },
+         "max-value": {
+          "description": "Maxium value for the parameter",
+          "type": "uint64"
+         },
+         "current-value": {
+          "description": "Current value for the parameter",
+          "type": "uint64"
+         },
+         "step-value": {
+          "description": "Step value for the parameter",
+          "type": "uint64"
+         },
+         "units": {
+          "type": "string"
+         },
+         "widget-type": {
+          "type": "manotypes:widget-type"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+          "type": "string"
+         }
+        }
+       },
+       "action-param": {
+        "description": "List of action parameters to\ncontrol VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group monitoring parameter",
+          "type": "string"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+          "type": "string"
+         }
+        }
+       }
+      }
+     },
+     "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu": {
+      "leaf": {
+       "vcs-component-ref": {
+        "description": "This defines the software components using the\nRIFT.ware Virtual Component System (VCS). This\nalso allows specifying a state machine during\nthe VM startup.\nNOTE: This is an significant addition to MANO,\nsince MANO doesn't clearly specify a method to\nidentify various software components in a VM.\nAlso using a state machine is not something that\nis well described in MANO.",
+        "type": {
+         "leafref": {
+          "path": "/vnfd:vnfd-catalog/vnfd:vnfd/rw-vnfd:component/rw-vnfd:component-name"
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "dependencies": {
+  "vnfd": {
+   "module": {
+    "vnfd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vnfd",
+     "prefix": "vnfd",
+     "import": {
+      "mano-types": {
+       "prefix": "manotypes"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Network Function (VNF)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "grouping": {
+      "common-connection-point": {
+       "leaf": {
+        "name": {
+         "description": "Name of the connection point",
+         "type": "string"
+        },
+        "id": {
+         "description": "Identifier for the internal connection points",
+         "type": "string"
+        },
+        "short-name": {
+         "description": "Short name of the connection point",
+         "type": "string"
+        },
+        "type": {
+         "description": "Type of the connection point.",
+         "type": "manotypes:connection-point-type"
+        }
+       }
+      },
+      "virtual-interface": {
+       "container": {
+        "virtual-interface": {
+         "description": "Container for the virtual interface properties",
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "OM-MGMT": null,
+              "PCI-PASSTHROUGH": null,
+              "SR-IOV": null,
+              "VIRTIO": null
+             }
+            }
+           },
+           "default": "VIRTIO"
+          },
+          "vpci": {
+           "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+           "type": "string"
+          },
+          "bandwidth": {
+           "description": "Aggregate bandwidth of the NIC.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "vnfd-catalog": {
+       "description": "Virtual Network Function Descriptor (VNFD).",
+       "list": {
+        "vnfd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VNFD.",
+           "type": "string"
+          },
+          "name": {
+           "description": "VNFD name.",
+           "mandatory": "true",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "VNFD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the VNFD.",
+           "type": "string"
+          },
+          "logo": {
+           "description": "Vendor logo for the Virtual Network Function",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VNFD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VNFD",
+           "type": "string"
+          },
+          "service-function-chain": {
+           "description": "Type of node in Service Function Chaining Architecture",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "UNAWARE": null,
+              "CLASSIFIER": null,
+              "SF": null,
+              "SFF": null
+             }
+            }
+           },
+           "default": "UNAWARE"
+          },
+          "service-function-type": {
+           "description": "Type of Service Function.\nNOTE: This needs to map with Service Function Type in ODL to\nsupport VNFFG. Service Function Type is manadatory param in ODL\nSFC. This is temporarily set to string for ease of use",
+           "type": "string"
+          }
+         },
+         "container": {
+          "mgmt-interface": {
+           "description": "Interface over which the VNF is managed.",
+           "uses": "manotypes:vnf-configuration",
+           "choice": {
+            "endpoint-type": {
+             "description": "Indicates the type of management endpoint.",
+             "case": {
+              "ip": {
+               "description": "Specifies the static IP address for managing the VNF.",
+               "leaf": {
+                "ip-address": {
+                 "type": "inet:ip-address"
+                }
+               }
+              },
+              "vdu-id": {
+               "description": "Use the default management interface on this VDU.",
+               "leaf": {
+                "vdu-id": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                  }
+                 }
+                }
+               }
+              },
+              "cp": {
+               "description": "Use the ip address associated with this connection point.",
+               "leaf": {
+                "cp": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           },
+           "leaf": {
+            "port": {
+             "description": "Port for the management interface.",
+             "type": "inet:port-number"
+            }
+           },
+           "container": {
+            "dashboard-params": {
+             "description": "Parameters for the VNF dashboard",
+             "leaf": {
+              "path": {
+               "description": "The HTTP path for the dashboard",
+               "type": "string"
+              },
+              "https": {
+               "description": "Pick HTTPS instead of HTTP , Default is false",
+               "type": "boolean"
+              },
+              "port": {
+               "description": "The HTTP port for the dashboard",
+               "type": "inet:port-number"
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "internal-vld": {
+           "key": "id",
+           "description": "List of Internal Virtual Link Descriptors (VLD).\nThe internal VLD describes the basic topology of\nthe connectivity (e.g. E-LAN, E-Line, E-Tree)\nbetween internal VNF components of the system.",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD",
+             "type": "string"
+            },
+            "name": {
+             "description": "Name of the internal VLD",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the internal VLD",
+             "type": "string"
+            },
+            "description": {
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "leaf-list": {
+            "internal-connection-point-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/internal-connection-point/id"
+              }
+             }
+            }
+           },
+           "uses": "manotypes:provider-network"
+          },
+          "connection-point": {
+           "key": "name",
+           "description": "List for external connection points. Each VNF has one\nor more external connection points. As the name\nimplies that external connection points are used for\nconnecting the VNF to other VNFs or to external networks.\nEach VNF exposes these connection points to the\norchestrator. The orchestrator can construct network\nservices by connecting the connection points between\ndifferent VNFs. The NFVO will use VLDs and VNFFGs at\nthe network service level to construct network services.",
+           "uses": "common-connection-point"
+          },
+          "vdu": {
+           "description": "List of Virtual Deployment Units",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Unique id for the VDU",
+             "type": "string"
+            },
+            "name": {
+             "description": "Unique name for the VDU",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VDU.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of instances of VDU",
+             "type": "uint64"
+            },
+            "mgmt-vpci": {
+             "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+             "type": "string"
+            },
+            "image": {
+             "description": "Image name for the software image.\nIf the image name is found within the VNF packaage it will\nbe uploaded to all cloud accounts during onboarding process.\nOtherwise, the image must be added to the cloud account with\nthe same name as entered here.\n",
+             "mandatory": "true",
+             "type": "string"
+            },
+            "image-checksum": {
+             "description": "Image md5sum for the software image.\nThe md5sum, if provided, along with the image name uniquely\nidentifies an image uploaded to the CAL.\n",
+             "type": "string"
+            },
+            "cloud-init": {
+             "description": "Content of cloud-init script",
+             "type": "string"
+            }
+           },
+           "uses": {
+            "manotypes:vm-flavor": null,
+            "manotypes:guest-epa": null,
+            "manotypes:vswitch-epa": null,
+            "manotypes:hypervisor-epa": null,
+            "manotypes:host-epa": null
+           },
+           "list": {
+            "alarm": {
+             "key": "alarm-id",
+             "uses": "manotypes:alarm"
+            },
+            "internal-connection-point": {
+             "key": "id",
+             "description": "List for internal connection points. Each VNFC\nhas zero or more internal connection points.\nInternal connection points are used for connecting\nthe VNF components internal to the VNF. If a VNF\nhas only one VNFC, it may not have any internal\nconnection points.",
+             "uses": "common-connection-point",
+             "leaf": {
+              "internal-vld-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../internal-vld/id"
+                }
+               }
+              }
+             }
+            },
+            "internal-interface": {
+             "description": "List of internal interfaces for the VNF",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of internal interface. Note that this\nname has only local significance to the VDU.",
+               "type": "string"
+              },
+              "vdu-internal-connection-point-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../internal-connection-point/id"
+                }
+               }
+              }
+             },
+             "uses": "virtual-interface"
+            },
+            "external-interface": {
+             "description": "List of external interfaces for the VNF.\nThe external interfaces enable sending\ntraffic to and from VNF.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the external interface. Note that\nthis name has only local significance.",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "Name of the external connection point.",
+               "type": {
+                "leafref": {
+                 "path": "../../../connection-point/name"
+                }
+               }
+              }
+             },
+             "uses": "virtual-interface"
+            }
+           }
+          },
+          "vdu-dependency": {
+           "description": "List of VDU dependencies.",
+           "key": "vdu-source-ref",
+           "leaf": {
+            "vdu-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            },
+            "vdu-depends-on-ref": {
+             "description": "Reference to the VDU that\nsource VDU depends.",
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            }
+           }
+          },
+          "placement-groups": {
+           "description": "List of placement groups at VNF level",
+           "key": "name",
+           "uses": "manotypes:placement-group-info",
+           "list": {
+            "member-vdus": {
+             "description": "List of VDUs that are part of this placement group",
+             "key": "member-vdu-ref",
+             "leaf": {
+              "member-vdu-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../vdu/id"
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         },
+         "uses": "manotypes:monitoring-param"
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "mano-types": {
+   "module": {
+    "mano-types": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:mano-types",
+     "prefix": "manotypes",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      }
+     },
+     "revision": {
+      "2015-04-23": {
+       "description": "Initial revision. This YANG file defines\nthe reusable base types for VNF Management\nand Orchestration (MANO).",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "parameter-data-type": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "STRING": {
+           "value": 0
+          },
+          "INTEGER": {
+           "value": 1
+          },
+          "BOOLEAN": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "virtual-link-type": {
+       "description": "Type of virtual link\nELAN: A multipoint service connecting a set of VNFs\n// ELINE: For a simple point to point connection\n//        between a VNF and the existing network.\n// ETREE: A multipoint service connecting one or\n//        more roots and a set of leaves, but\n//        preventing inter-leaf communication.",
+       "type": {
+        "enumeration": {
+         "enum": "ELAN"
+        }
+       }
+      },
+      "http-method": {
+       "description": "Type of HTTP operation",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "POST": {
+           "value": 0
+          },
+          "PUT": {
+           "value": 1
+          },
+          "GET": {
+           "value": 2
+          },
+          "DELETE": {
+           "value": 3
+          },
+          "OPTIONS": {
+           "value": 4
+          },
+          "PATCH": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "api-type": {
+       "description": "Type of API to fetch monitoring params",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HTTP": {
+           "value": 0
+          },
+          "NETCONF": {
+           "value": 1
+          },
+          "SOAP": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "json-query-method": {
+       "description": "The method to extract a value from a JSON response\n\nNAMEKEY - Use the name as the key for a non-nested value.\nJSONPATH - Use jsonpath-rw implemenation to extract a value.\nOBJECTPATH - Use objectpath implemenation to extract a value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NAMEKEY": {
+           "value": 0
+          },
+          "JSONPATH": {
+           "value": 1
+          },
+          "OBJECTPATH": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "param-value-type": {
+       "description": "The type of the parameter value",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "INT": {
+           "value": 0
+          },
+          "DECIMAL": {
+           "value": 1
+          },
+          "STRING": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "connection-point-type": {
+       "description": "Type of connection point\nVPORT: Virtual Port\n// VNIC_ADDR: Virtual NIC Address\n// PNIC_ADDR: Physical NIC Address\n// PPORT: Phsical Port.",
+       "type": {
+        "enumeration": {
+         "enum": "VPORT"
+        }
+       }
+      },
+      "widget-type": {
+       "description": "Type of the widget, typically used by the UI.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HISTOGRAM": {
+           "value": 0
+          },
+          "BAR": {
+           "value": 1
+          },
+          "GAUGE": {
+           "value": 2
+          },
+          "SLIDER": {
+           "value": 3
+          },
+          "COUNTER": {
+           "value": 4
+          },
+          "TEXTBOX": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "cpu-feature-type": {
+       "description": "Enumeration for CPU features.\n\nAES: CPU supports advanced instruction set for\nAES (Advanced Encryption Standard).\n\nCAT: Cache Allocation Technology (CAT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to specify the amount\nof L3 cache (currently the last-level cache\nin most server and client platforms) space an\napplication can fill (as a hint to hardware\nfunctionality, certain features such as power\nmanagement may override CAT settings).\n\nCMT: Cache Monitoring Technology (CMT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to determine the\nusage of cache based on applications running\non the platform. The implementation is\ndirected at L3 cache monitoring (currently\nthe last-level cache in most server and\nclient platforms).\n\nDDIO: Intel Data Direct I/O (DDIO) enables\nEthernet server NICs and controllers talk\ndirectly to the processor cache without a\ndetour via system memory. This enumeration\nspecifies if the VM requires a DDIO\ncapable host.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "PREFER_AES": {
+           "value": 0
+          },
+          "REQUIRE_AES": {
+           "value": 1
+          },
+          "PREFER_CAT": {
+           "value": 2
+          },
+          "REQUIRE_CAT": {
+           "value": 3
+          },
+          "PREFER_CMT": {
+           "value": 4
+          },
+          "REQUIRE_CMT": {
+           "value": 5
+          },
+          "PREFER_DDIO": {
+           "value": 6
+          },
+          "REQUIRE_DDIO": {
+           "value": 7
+          },
+          "REQUIRE_VME": {
+           "value": 8
+          },
+          "PREFER_VME": {
+           "value": 9
+          },
+          "REQUIRE_DE": {
+           "value": 10
+          },
+          "PREFER_DE": {
+           "value": 11
+          },
+          "REQUIRE_PSE": {
+           "value": 12
+          },
+          "PREFER_PSE": {
+           "value": 13
+          },
+          "REQUIRE_TSC": {
+           "value": 14
+          },
+          "PREFER_TSC": {
+           "value": 15
+          },
+          "REQUIRE_MSR": {
+           "value": 16
+          },
+          "PREFER_MSR": {
+           "value": 17
+          },
+          "REQUIRE_PAE": {
+           "value": 18
+          },
+          "PREFER_PAE": {
+           "value": 19
+          },
+          "REQUIRE_MCE": {
+           "value": 20
+          },
+          "PREFER_MCE": {
+           "value": 21
+          },
+          "REQUIRE_CX8": {
+           "value": 22
+          },
+          "PREFER_CX8": {
+           "value": 23
+          },
+          "REQUIRE_APIC": {
+           "value": 24
+          },
+          "PREFER_APIC": {
+           "value": 25
+          },
+          "REQUIRE_SEP": {
+           "value": 26
+          },
+          "PREFER_SEP": {
+           "value": 27
+          },
+          "REQUIRE_MTRR": {
+           "value": 28
+          },
+          "PREFER_MTRR": {
+           "value": 29
+          },
+          "REQUIRE_PGE": {
+           "value": 30
+          },
+          "PREFER_PGE": {
+           "value": 31
+          },
+          "REQUIRE_MCA": {
+           "value": 32
+          },
+          "PREFER_MCA": {
+           "value": 33
+          },
+          "REQUIRE_CMOV": {
+           "value": 34
+          },
+          "PREFER_CMOV": {
+           "value": 35
+          },
+          "REQUIRE_PAT": {
+           "value": 36
+          },
+          "PREFER_PAT": {
+           "value": 37
+          },
+          "REQUIRE_PSE36": {
+           "value": 38
+          },
+          "PREFER_PSE36": {
+           "value": 39
+          },
+          "REQUIRE_CLFLUSH": {
+           "value": 40
+          },
+          "PREFER_CLFLUSH": {
+           "value": 41
+          },
+          "REQUIRE_DTS": {
+           "value": 42
+          },
+          "PREFER_DTS": {
+           "value": 43
+          },
+          "REQUIRE_ACPI": {
+           "value": 44
+          },
+          "PREFER_ACPI": {
+           "value": 45
+          },
+          "REQUIRE_MMX": {
+           "value": 46
+          },
+          "PREFER_MMX": {
+           "value": 47
+          },
+          "REQUIRE_FXSR": {
+           "value": 48
+          },
+          "PREFER_FXSR": {
+           "value": 49
+          },
+          "REQUIRE_SSE": {
+           "value": 50
+          },
+          "PREFER_SSE": {
+           "value": 51
+          },
+          "REQUIRE_SSE2": {
+           "value": 52
+          },
+          "PREFER_SSE2": {
+           "value": 53
+          },
+          "REQUIRE_SS": {
+           "value": 54
+          },
+          "PREFER_SS": {
+           "value": 55
+          },
+          "REQUIRE_HT": {
+           "value": 56
+          },
+          "PREFER_HT": {
+           "value": 57
+          },
+          "REQUIRE_TM": {
+           "value": 58
+          },
+          "PREFER_TM": {
+           "value": 59
+          },
+          "REQUIRE_IA64": {
+           "value": 60
+          },
+          "PREFER_IA64": {
+           "value": 61
+          },
+          "REQUIRE_PBE": {
+           "value": 62
+          },
+          "PREFER_PBE": {
+           "value": 63
+          },
+          "REQUIRE_RDTSCP": {
+           "value": 64
+          },
+          "PREFER_RDTSCP": {
+           "value": 65
+          },
+          "REQUIRE_PNI": {
+           "value": 66
+          },
+          "PREFER_PNI": {
+           "value": 67
+          },
+          "REQUIRE_PCLMULQDQ": {
+           "value": 68
+          },
+          "PREFER_PCLMULQDQ": {
+           "value": 69
+          },
+          "REQUIRE_DTES64": {
+           "value": 70
+          },
+          "PREFER_DTES64": {
+           "value": 71
+          },
+          "REQUIRE_MONITOR": {
+           "value": 72
+          },
+          "PREFER_MONITOR": {
+           "value": 73
+          },
+          "REQUIRE_DS_CPL": {
+           "value": 74
+          },
+          "PREFER_DS_CPL": {
+           "value": 75
+          },
+          "REQUIRE_VMX": {
+           "value": 76
+          },
+          "PREFER_VMX": {
+           "value": 77
+          },
+          "REQUIRE_SMX": {
+           "value": 78
+          },
+          "PREFER_SMX": {
+           "value": 79
+          },
+          "REQUIRE_EST": {
+           "value": 80
+          },
+          "PREFER_EST": {
+           "value": 81
+          },
+          "REQUIRE_TM2": {
+           "value": 82
+          },
+          "PREFER_TM2": {
+           "value": 83
+          },
+          "REQUIRE_SSSE3": {
+           "value": 84
+          },
+          "PREFER_SSSE3": {
+           "value": 85
+          },
+          "REQUIRE_CID": {
+           "value": 86
+          },
+          "PREFER_CID": {
+           "value": 87
+          },
+          "REQUIRE_FMA": {
+           "value": 88
+          },
+          "PREFER_FMA": {
+           "value": 89
+          },
+          "REQUIRE_CX16": {
+           "value": 90
+          },
+          "PREFER_CX16": {
+           "value": 91
+          },
+          "REQUIRE_XTPR": {
+           "value": 92
+          },
+          "PREFER_XTPR": {
+           "value": 93
+          },
+          "REQUIRE_PDCM": {
+           "value": 94
+          },
+          "PREFER_PDCM": {
+           "value": 95
+          },
+          "REQUIRE_PCID": {
+           "value": 96
+          },
+          "PREFER_PCID": {
+           "value": 97
+          },
+          "REQUIRE_DCA": {
+           "value": 98
+          },
+          "PREFER_DCA": {
+           "value": 99
+          },
+          "REQUIRE_SSE4_1": {
+           "value": 100
+          },
+          "PREFER_SSE4_1": {
+           "value": 101
+          },
+          "REQUIRE_SSE4_2": {
+           "value": 102
+          },
+          "PREFER_SSE4_2": {
+           "value": 103
+          },
+          "REQUIRE_X2APIC": {
+           "value": 104
+          },
+          "PREFER_X2APIC": {
+           "value": 105
+          },
+          "REQUIRE_MOVBE": {
+           "value": 106
+          },
+          "PREFER_MOVBE": {
+           "value": 107
+          },
+          "REQUIRE_POPCNT": {
+           "value": 108
+          },
+          "PREFER_POPCNT": {
+           "value": 109
+          },
+          "REQUIRE_TSC_DEADLINE_TIMER": {
+           "value": 110
+          },
+          "PREFER_TSC_DEADLINE_TIMER": {
+           "value": 111
+          },
+          "REQUIRE_XSAVE": {
+           "value": 112
+          },
+          "PREFER_XSAVE": {
+           "value": 113
+          },
+          "REQUIRE_AVX": {
+           "value": 114
+          },
+          "PREFER_AVX": {
+           "value": 115
+          },
+          "REQUIRE_F16C": {
+           "value": 116
+          },
+          "PREFER_F16C": {
+           "value": 117
+          },
+          "REQUIRE_RDRAND": {
+           "value": 118
+          },
+          "PREFER_RDRAND": {
+           "value": 119
+          },
+          "REQUIRE_FSGSBASE": {
+           "value": 120
+          },
+          "PREFER_FSGSBASE": {
+           "value": 121
+          },
+          "REQUIRE_BMI1": {
+           "value": 122
+          },
+          "PREFER_BMI1": {
+           "value": 123
+          },
+          "REQUIRE_HLE": {
+           "value": 124
+          },
+          "PREFER_HLE": {
+           "value": 125
+          },
+          "REQUIRE_AVX2": {
+           "value": 126
+          },
+          "PREFER_AVX2": {
+           "value": 127
+          },
+          "REQUIRE_SMEP": {
+           "value": 128
+          },
+          "PREFER_SMEP": {
+           "value": 129
+          },
+          "REQUIRE_BMI2": {
+           "value": 130
+          },
+          "PREFER_BMI2": {
+           "value": 131
+          },
+          "REQUIRE_ERMS": {
+           "value": 132
+          },
+          "PREFER_ERMS": {
+           "value": 133
+          },
+          "REQUIRE_INVPCID": {
+           "value": 134
+          },
+          "PREFER_INVPCID": {
+           "value": 135
+          },
+          "REQUIRE_RTM": {
+           "value": 136
+          },
+          "PREFER_RTM": {
+           "value": 137
+          },
+          "REQUIRE_MPX": {
+           "value": 138
+          },
+          "PREFER_MPX": {
+           "value": 139
+          },
+          "REQUIRE_RDSEED": {
+           "value": 140
+          },
+          "PREFER_RDSEED": {
+           "value": 141
+          },
+          "REQUIRE_ADX": {
+           "value": 142
+          },
+          "PREFER_ADX": {
+           "value": 143
+          },
+          "REQUIRE_SMAP": {
+           "value": 144
+          },
+          "PREFER_SMAP": {
+           "value": 145
+          }
+         }
+        }
+       }
+      },
+      "alarm-severity-type": {
+       "description": "An indication of the importance or ugency of the alarm",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "LOW": {
+           "value": 0
+          },
+          "MODERATE": {
+           "value": 1
+          },
+          "CRITICAL": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "alarm-metric-type": {
+       "description": "The type of metrics to register the alarm for",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "CPU_UTILIZATION": {
+           "value": 0
+          },
+          "MEMORY_UTILIZATION": {
+           "value": 1
+          },
+          "STORAGE_UTILIZATION": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "alarm-statistic-type": {
+       "description": "The type of statistic to used to measure a metric to determine\nthreshold crossing for an alarm.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "AVERAGE": {
+           "value": 0
+          },
+          "MINIMUM": {
+           "value": 1
+          },
+          "MAXIMUM": {
+           "value": 2
+          },
+          "COUNT": {
+           "value": 3
+          },
+          "SUM": {
+           "value": 4
+          }
+         }
+        }
+       }
+      },
+      "alarm-operation-type": {
+       "description": "The relational operator used to define whether an alarm should be\ntriggered when, say, the metric statistic goes above or below a\nspecified value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "GE": {
+           "value": 0
+          },
+          "LE": {
+           "value": 1
+          },
+          "GT": {
+           "value": 2
+          },
+          "LT": {
+           "value": 3
+          },
+          "EQ": {
+           "value": 4
+          }
+         }
+        }
+       }
+      },
+      "cloud-account-type": {
+       "description": "cloud account type",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "aws": {
+           "value": 0
+          },
+          "cloudsim": {
+           "value": 1
+          },
+          "cloudsim_proxy": {
+           "value": 2
+          },
+          "mock": {
+           "value": 3
+          },
+          "openmano": {
+           "value": 4
+          },
+          "openstack": {
+           "value": 5
+          },
+          "vsphere": {
+           "value": 6
+          }
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "primitive-parameter": {
+       "leaf": {
+        "name": {
+         "description": "Name of the parameter.",
+         "type": "string"
+        },
+        "data-type": {
+         "description": "Data type associated with the name.",
+         "type": "manotypes:parameter-data-type"
+        },
+        "mandatory": {
+         "description": "Is this field mandatory",
+         "type": "boolean",
+         "default": "false"
+        },
+        "default-value": {
+         "description": "The default value for this field",
+         "type": "string"
+        },
+        "parameter-pool": {
+         "description": "NSD Parameter pool name to use for this paramter",
+         "type": "string"
+        },
+        "read-only": {
+         "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+         "type": "boolean"
+        },
+        "hidden": {
+         "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+         "type": "boolean"
+        }
+       }
+      },
+      "vnf-configuration": {
+       "container": {
+        "vnf-configuration": {
+         "description": "Information regarding the VNF configuration\nis captured here. ",
+         "choice": {
+          "config-method": {
+           "description": "Defines the configuration method for the VNF.",
+           "case": {
+            "netconf": {
+             "description": "Use NETCONF for configuring the VNF.",
+             "container": {
+              "netconf": {
+               "leaf": {
+                "target": {
+                 "description": "Netconf configuration target",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "running": {
+                     "value": 0
+                    },
+                    "candidate": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                },
+                "protocol": {
+                 "description": "Protocol to use for netconf (e.g. ssh)",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "None": {
+                     "value": 0
+                    },
+                    "ssh": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                },
+                "port": {
+                 "description": "Port for the netconf server.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            },
+            "rest": {
+             "description": "Use REST for configuring the VNF.",
+             "container": {
+              "rest": {
+               "leaf": {
+                "port": {
+                 "description": "Port for the REST server.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            },
+            "script": {
+             "description": "Use custom script for configuring the VNF.\nThis script is executed in the context of\nOrchestrator.",
+             "container": {
+              "script": {
+               "leaf": {
+                "script-type": {
+                 "description": "Script type - currently supported : bash, expect",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "bash": {
+                     "value": 0
+                    },
+                    "expect": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "juju": {
+             "description": "Configure the VNF through Juju.",
+             "container": {
+              "juju": {
+               "leaf": {
+                "charm": {
+                 "description": "Juju charm to use with the VNF.",
+                 "type": "string"
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         },
+         "container": {
+          "config-access": {
+           "leaf": {
+            "mgmt-ip-address": {
+             "description": "IP address to be used to configure this VNF,\noptional if it is possible to resolve dynamically.",
+             "type": "inet:ip-address"
+            },
+            "username": {
+             "description": "username for configuration.",
+             "type": "string"
+            },
+            "password": {
+             "description": "Password for configuration access authentication.",
+             "type": "string"
+            }
+           }
+          },
+          "config-attributes": {
+           "description": "Miscelaneous input parameters to be considered\nwhile processing the NSD to apply configuration",
+           "leaf": {
+            "config-priority": {
+             "description": "Configuration priority - order of confgiration\nto be applied to each VNF in this NS,\nlow number gets precedence over high number",
+             "type": "uint64"
+            },
+            "config-delay": {
+             "description": "Wait (seconds) before applying the configuration to VNF",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "list": {
+          "config-primitive": {
+           "description": "List of configuration primitives supported by the\nconfiguration agent for this VNF.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "description": "List of parameters to the configuration primitive.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the parameter.",
+               "type": "string"
+              },
+              "data-type": {
+               "description": "Data type associated with the name.",
+               "type": "manotypes:parameter-data-type"
+              },
+              "mandatory": {
+               "description": "Is this field mandatory",
+               "type": "boolean",
+               "default": "false"
+              },
+              "default-value": {
+               "description": "The default value for this field",
+               "type": "string"
+              },
+              "parameter-pool": {
+               "description": "NSD Parameter pool name to use for this paramter",
+               "type": "string"
+              },
+              "read-only": {
+               "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              },
+              "hidden": {
+               "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              }
+             }
+            }
+           }
+          },
+          "initial-config-primitive": {
+           "description": "Initial set of configuration primitives.",
+           "key": "seq",
+           "leaf": {
+            "seq": {
+             "description": "Sequence number for the configuration primitive.",
+             "type": "uint64"
+            },
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "key": "name",
+             "leaf": {
+              "name": {
+               "type": "string"
+              },
+              "value": {
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         },
+         "leaf": {
+          "config-template": {
+           "description": "Configuration template for each VNF",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "named-value": {
+       "leaf": {
+        "name": {
+         "type": "string"
+        },
+        "value": {
+         "type": "string"
+        }
+       }
+      },
+      "vm-flavor": {
+       "container": {
+        "vm-flavor": {
+         "leaf": {
+          "vcpu-count": {
+           "description": "Number of vcpus for the VM.",
+           "type": "uint16"
+          },
+          "memory-mb": {
+           "description": "Amount of memory in MB.",
+           "type": "uint64"
+          },
+          "storage-gb": {
+           "description": "Amount of disk space in GB.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      },
+      "vswitch-epa": {
+       "container": {
+        "vswitch-epa": {
+         "leaf": {
+          "ovs-acceleration": {
+           "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          },
+          "ovs-offload": {
+           "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "hypervisor-epa": {
+       "container": {
+        "hypervisor-epa": {
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_KVM": {
+               "value": 0
+              },
+              "REQUIRE_KVM": {
+               "value": 1
+              }
+             }
+            }
+           }
+          },
+          "version": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "host-epa": {
+       "container": {
+        "host-epa": {
+         "description": "Specifies the host level EPA attributes.",
+         "leaf": {
+          "cpu-model": {
+           "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_WESTMERE": {
+               "value": 0
+              },
+              "REQUIRE_WESTMERE": {
+               "value": 1
+              },
+              "PREFER_SANDYBRIDGE": {
+               "value": 2
+              },
+              "REQUIRE_SANDYBRIDGE": {
+               "value": 3
+              },
+              "PREFER_IVYBRIDGE": {
+               "value": 4
+              },
+              "REQUIRE_IVYBRIDGE": {
+               "value": 5
+              },
+              "PREFER_HASWELL": {
+               "value": 6
+              },
+              "REQUIRE_HASWELL": {
+               "value": 7
+              },
+              "PREFER_BROADWELL": {
+               "value": 8
+              },
+              "REQUIRE_BROADWELL": {
+               "value": 9
+              },
+              "PREFER_NEHALEM": {
+               "value": 10
+              },
+              "REQUIRE_NEHALEM": {
+               "value": 11
+              },
+              "PREFER_PENRYN": {
+               "value": 12
+              },
+              "REQUIRE_PENRYN": {
+               "value": 13
+              },
+              "PREFER_CONROE": {
+               "value": 14
+              },
+              "REQUIRE_CONROE": {
+               "value": 15
+              },
+              "PREFER_CORE2DUO": {
+               "value": 16
+              },
+              "REQUIRE_CORE2DUO": {
+               "value": 17
+              }
+             }
+            }
+           }
+          },
+          "cpu-arch": {
+           "description": "Host CPU architecture.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_X86": {
+               "value": 0
+              },
+              "REQUIRE_X86": {
+               "value": 1
+              },
+              "PREFER_X86_64": {
+               "value": 2
+              },
+              "REQUIRE_X86_64": {
+               "value": 3
+              },
+              "PREFER_I686": {
+               "value": 4
+              },
+              "REQUIRE_I686": {
+               "value": 5
+              },
+              "PREFER_IA64": {
+               "value": 6
+              },
+              "REQUIRE_IA64": {
+               "value": 7
+              },
+              "PREFER_ARMV7": {
+               "value": 8
+              },
+              "REQUIRE_ARMV7": {
+               "value": 9
+              },
+              "PREFER_ARMV8": {
+               "value": 10
+              },
+              "REQUIRE_ARMV8": {
+               "value": 11
+              }
+             }
+            }
+           }
+          },
+          "cpu-vendor": {
+           "description": "Host CPU Vendor.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_INTEL": {
+               "value": 0
+              },
+              "REQUIRE_INTEL": {
+               "value": 1
+              },
+              "PREFER_AMD": {
+               "value": 2
+              },
+              "REQUIRE_AMD": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-socket-count": {
+           "description": "Number of sockets on the host.",
+           "type": "uint64"
+          },
+          "cpu-core-count": {
+           "description": "Number of cores on the host.",
+           "type": "uint64"
+          },
+          "cpu-core-thread-count": {
+           "description": "Number of threads per cores on the host.",
+           "type": "uint64"
+          },
+          "om-cpu-model-string": {
+           "description": "Openmano CPU model string",
+           "type": "string"
+          }
+         },
+         "leaf-list": {
+          "cpu-feature": {
+           "description": "List of CPU features.",
+           "type": "manotypes:cpu-feature-type"
+          },
+          "om-cpu-feature": {
+           "description": "Openmano CPU features",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "guest-epa": {
+       "description": "EPA attributes for the guest",
+       "container": {
+        "guest-epa": {
+         "leaf": {
+          "trusted-execution": {
+           "description": "This VM should be allocated from trusted pool",
+           "type": "boolean"
+          },
+          "mempage-size": {
+           "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LARGE": {
+               "value": 0
+              },
+              "SMALL": {
+               "value": 1
+              },
+              "SIZE_2MB": {
+               "value": 2
+              },
+              "SIZE_1GB": {
+               "value": 3
+              },
+              "PREFER_LARGE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "cpu-pinning-policy": {
+           "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "DEDICATED": {
+               "value": 0
+              },
+              "SHARED": {
+               "value": 1
+              },
+              "ANY": {
+               "value": 2
+              }
+             }
+            }
+           },
+           "default": "ANY"
+          },
+          "cpu-thread-pinning-policy": {
+           "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "AVOID": {
+               "value": 0
+              },
+              "SEPARATE": {
+               "value": 1
+              },
+              "ISOLATE": {
+               "value": 2
+              },
+              "PREFER": {
+               "value": 3
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "pcie-device": {
+           "description": "List of pcie passthrough devices.",
+           "key": "device-id",
+           "leaf": {
+            "device-id": {
+             "description": "Device identifier.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of devices to attach to the VM.",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "choice": {
+          "numa-policy": {
+           "case": {
+            "numa-unware": {
+             "leaf": {
+              "numa-unware": {
+               "type": "empty"
+              }
+             }
+            },
+            "numa-aware": {
+             "container": {
+              "numa-node-policy": {
+               "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+               "leaf": {
+                "node-cnt": {
+                 "description": "The number of numa nodes to expose to the VM.",
+                 "type": "uint16"
+                },
+                "mem-policy": {
+                 "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "STRICT": {
+                     "value": 0
+                    },
+                    "PREFERRED": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               },
+               "list": {
+                "node": {
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "NUMA node identification. Typically\nit's 0 or 1",
+                   "type": "uint64"
+                  },
+                  "memory-mb": {
+                   "description": "Memory size expressed in MB\nfor this NUMA node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "leaf-list": {
+                  "vcpu": {
+                   "description": "List of vcpus to allocate on\nthis numa node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "choice": {
+                  "om-numa-type": {
+                   "description": "Openmano Numa type selection",
+                   "case": {
+                    "cores": {
+                     "leaf": {
+                      "num-cores": {
+                       "type": "uint8"
+                      }
+                     }
+                    },
+                    "paired-threads": {
+                     "container": {
+                      "paired-threads": {
+                       "leaf": {
+                        "num-paired-threads": {
+                         "type": "uint8"
+                        }
+                       },
+                       "list": {
+                        "paired-thread-ids": {
+                         "description": "List of thread pairs to use in case of paired-thread numa",
+                         "max-elements": 16,
+                         "key": "thread-a",
+                         "leaf": {
+                          "thread-a": {
+                           "type": "uint8"
+                          },
+                          "thread-b": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "threads": {
+                     "leaf": {
+                      "num-threads": {
+                       "type": "uint8"
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "provider-network": {
+       "container": {
+        "provider-network": {
+         "description": "Container for the provider network.",
+         "leaf": {
+          "physical-network": {
+           "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+           "type": "string"
+          },
+          "overlay-type": {
+           "description": "Type of the overlay network.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LOCAL": {
+               "value": 0
+              },
+              "FLAT": {
+               "value": 1
+              },
+              "VLAN": {
+               "value": 2
+              },
+              "VXLAN": {
+               "value": 3
+              },
+              "GRE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "segmentation_id": {
+           "description": "Segmentation ID",
+           "type": "uint32"
+          }
+         }
+        }
+       }
+      },
+      "config-primitive": {
+       "list": {
+        "config-primitive": {
+         "description": "Network service level configuration primitives.",
+         "key": "name",
+         "leaf": {
+          "name": {
+           "description": "Name of the configuration primitive.",
+           "type": "string"
+          },
+          "user-defined-script": {
+           "description": "A user defined script.",
+           "type": "string"
+          }
+         },
+         "list": {
+          "parameter": {
+           "description": "List of parameters to the configuration primitive.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the parameter.",
+             "type": "string"
+            },
+            "data-type": {
+             "description": "Data type associated with the name.",
+             "type": "manotypes:parameter-data-type"
+            },
+            "mandatory": {
+             "description": "Is this field mandatory",
+             "type": "boolean",
+             "default": "false"
+            },
+            "default-value": {
+             "description": "The default value for this field",
+             "type": "string"
+            },
+            "parameter-pool": {
+             "description": "NSD Parameter pool name to use for this paramter",
+             "type": "string"
+            },
+            "read-only": {
+             "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+             "type": "boolean"
+            },
+            "hidden": {
+             "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+             "type": "boolean"
+            }
+           }
+          },
+          "parameter-group": {
+           "description": "Grouping of parameters which are logically grouped in UI",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the parameter group",
+             "type": "string"
+            },
+            "mandatory": {
+             "description": "Is this parameter group mandatory",
+             "type": "boolean",
+             "default": "true"
+            }
+           },
+           "list": {
+            "parameter": {
+             "description": "List of parameters to the configuration primitive.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the parameter.",
+               "type": "string"
+              },
+              "data-type": {
+               "description": "Data type associated with the name.",
+               "type": "manotypes:parameter-data-type"
+              },
+              "mandatory": {
+               "description": "Is this field mandatory",
+               "type": "boolean",
+               "default": "false"
+              },
+              "default-value": {
+               "description": "The default value for this field",
+               "type": "string"
+              },
+              "parameter-pool": {
+               "description": "NSD Parameter pool name to use for this paramter",
+               "type": "string"
+              },
+              "read-only": {
+               "description": "The value should be greyed out by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              },
+              "hidden": {
+               "description": "The value should be hidden by the UI.\nOnly applies to parameters with default values.",
+               "type": "boolean"
+              }
+             }
+            }
+           }
+          },
+          "vnf-primitive-group": {
+           "description": "List of configuration primitives grouped by VNF.",
+           "key": "member-vnf-index-ref",
+           "leaf": {
+            "member-vnf-index-ref": {
+             "description": "Reference to member-vnf within constituent-vnfds",
+             "type": "uint64"
+            },
+            "vnfd-id-ref": {
+             "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+             "type": "string"
+            },
+            "vnfd-name": {
+             "description": "Name of the VNFD",
+             "type": "string"
+            }
+           },
+           "list": {
+            "primitive": {
+             "key": "index",
+             "leaf": {
+              "index": {
+               "description": "Index of this primitive",
+               "type": "uint32"
+              },
+              "name": {
+               "description": "Name of the primitive in the VNF primitive ",
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "monitoring-param": {
+       "list": {
+        "http-endpoint": {
+         "description": "List of http endpoints to be used by monitoring params",
+         "key": "path",
+         "leaf": {
+          "path": {
+           "description": "The HTTP path on the management server",
+           "type": "string"
+          },
+          "https": {
+           "description": "Pick HTTPS instead of HTTP , Default is false",
+           "type": "boolean",
+           "default": "false"
+          },
+          "port": {
+           "description": "The HTTP port to connect to",
+           "type": "inet:port-number"
+          },
+          "username": {
+           "description": "The HTTP basic auth username",
+           "type": "string"
+          },
+          "password": {
+           "description": "The HTTP basic auth password",
+           "type": "string"
+          },
+          "polling_interval_secs": {
+           "description": "The HTTP polling interval in seconds",
+           "type": "uint8",
+           "default": "2"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nGET by default for action",
+           "type": "manotypes:http-method",
+           "default": "GET"
+          }
+         },
+         "list": {
+          "headers": {
+           "description": "Custom HTTP headers to put on HTTP request",
+           "key": "key",
+           "leaf": {
+            "key": {
+             "description": "HTTP header key",
+             "type": "string"
+            },
+            "value": {
+             "description": "HTTP header value",
+             "type": "string"
+            }
+           }
+          }
+         }
+        },
+        "monitoring-param": {
+         "description": "List of monitoring parameters at the NS level",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "http-endpoint-ref": {
+           "type": {
+            "leafref": {
+             "path": "../../http-endpoint/path"
+            }
+           }
+          },
+          "json-query-method": {
+           "type": "manotypes:json-query-method",
+           "default": "NAMEKEY"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameters",
+           "type": "string"
+          },
+          "value-type": {
+           "type": "manotypes:param-value-type",
+           "default": "INT"
+          },
+          "value-integer": {
+           "description": "Current value for an integer parameter",
+           "type": "int64"
+          },
+          "value-decimal": {
+           "description": "Current value for a decimal parameter",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "4"
+            }
+           }
+          },
+          "value-string": {
+           "description": "Current value for a string parameter",
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "units": {
+           "type": "string"
+          }
+         },
+         "container": {
+          "json-query-params": {
+           "leaf": {
+            "json-path": {
+             "description": "The jsonpath to use to extract value from JSON structure",
+             "type": "string"
+            },
+            "object-path": {
+             "description": "The objectpath to use to extract value from JSON structure",
+             "type": "string"
+            }
+           }
+          },
+          "numeric-constraints": {
+           "leaf": {
+            "min-value": {
+             "description": "Minimum value for the parameter",
+             "type": "uint64"
+            },
+            "max-value": {
+             "description": "Maxium value for the parameter",
+             "type": "uint64"
+            }
+           }
+          },
+          "text-constraints": {
+           "leaf": {
+            "min-length": {
+             "description": "Minimum string length for the parameter",
+             "type": "uint8"
+            },
+            "max-length": {
+             "description": "Maximum string length for the parameter",
+             "type": "uint8"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "control-param": {
+       "list": {
+        "control-param": {
+         "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group control parameters",
+           "type": "string"
+          },
+          "min-value": {
+           "description": "Minimum value for the parameter",
+           "type": "uint64"
+          },
+          "max-value": {
+           "description": "Maxium value for the parameter",
+           "type": "uint64"
+          },
+          "current-value": {
+           "description": "Current value for the parameter",
+           "type": "uint64"
+          },
+          "step-value": {
+           "description": "Step value for the parameter",
+           "type": "uint64"
+          },
+          "units": {
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-param": {
+       "list": {
+        "action-param": {
+         "description": "List of action parameters to\ncontrol VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameter",
+           "type": "string"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter": {
+       "description": "",
+       "list": {
+        "input-parameter": {
+         "description": "List of input parameters",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          },
+          "value": {
+           "description": "The value that the element specified by the xpath should take when a\nrecord is created.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter-xpath": {
+       "list": {
+        "input-parameter-xpath": {
+         "description": "List of xpaths to parameters inside the NSD\nthe can be customized during the instantiation.",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "An xpath that specifies the element in a descriptor.",
+           "type": "string"
+          },
+          "label": {
+           "description": "A descriptive string",
+           "type": "string"
+          },
+          "default-value": {
+           "description": " A default value for this input parameter",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "nfvi-metrics": {
+       "container": {
+        "vcpu": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "VCPU"
+          },
+          "total": {
+           "description": "The total number of VCPUs available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The VCPU utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "memory": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "MEMORY"
+          },
+          "used": {
+           "description": "The amount of memory (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of memory (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The memory utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "storage": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "STORAGE"
+          },
+          "used": {
+           "description": "The amount of storage (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of storage (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The storage utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "external-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "EXTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of external ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "internal-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "INTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of internal ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "network": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "NETWORK TRAFFIC"
+          }
+         },
+         "container": {
+          "incoming": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "INCOMING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of incoming bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of incoming packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current incoming byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current incoming packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          },
+          "outgoing": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "OUTGOING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of outgoing bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of outgoing packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current outgoing byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current outgoing packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "alarm": {
+       "leaf": {
+        "alarm-id": {
+         "description": "This field is reserved for the identifier assigned by the cloud\nprovider",
+         "type": "string"
+        },
+        "name": {
+         "description": "A human readable string to identify the alarm",
+         "type": "string"
+        },
+        "description": {
+         "description": "A string containing a description of this alarm",
+         "type": "string"
+        },
+        "vdur-id": {
+         "description": "The identifier of the VDUR that the alarm is associated with",
+         "type": "string"
+        },
+        "repeat": {
+         "description": "This flag indicates whether the alarm should be repeatedly emitted\nwhile the associated threshold has been crossed.",
+         "type": "boolean",
+         "default": "true"
+        },
+        "enabled": {
+         "description": "This flag indicates whether the alarm has been enabled or\ndisabled.",
+         "type": "boolean",
+         "default": "true"
+        },
+        "severity": {
+         "description": "A measure of the important or urgency of the alarm",
+         "type": "manotypes:alarm-severity-type"
+        },
+        "metric": {
+         "description": "The metric to be tracked by this alarm.",
+         "type": "manotypes:alarm-metric-type"
+        },
+        "statistic": {
+         "description": "The type of metric statistic that is tracked by this alarm",
+         "type": "manotypes:alarm-statistic-type"
+        },
+        "operation": {
+         "description": "The relational operator that defines whether the alarm should be\ntriggered when the metric statistic is, say, above or below the\nspecified threshold value.",
+         "type": "manotypes:alarm-operation-type"
+        },
+        "value": {
+         "description": "This value defines the threshold that, if crossed, will trigger\nthe alarm.",
+         "type": {
+          "decimal64": {
+           "fraction-digits": "4"
+          }
+         }
+        },
+        "period": {
+         "description": "The period defines the length of time (seconds) that the metric\ndata are collected over in oreder to evaluate the chosen\nstatistic.",
+         "type": "uint32"
+        },
+        "evaluations": {
+         "description": "This is the number of samples of the metric statistic used to\nevaluate threshold crossing. Each sample or evaluation is equal to\nthe metric statistic obtained for a given period. This can be used\nto mitigate spikes in the metric that may skew the statistic of\ninterest.",
+         "type": "uint32"
+        }
+       },
+       "container": {
+        "actions": {
+         "list": {
+          "ok": {
+           "key": "url",
+           "leaf": {
+            "url": {
+             "type": "string"
+            }
+           }
+          },
+          "insufficient-data": {
+           "key": "url",
+           "leaf": {
+            "url": {
+             "type": "string"
+            }
+           }
+          },
+          "alarm": {
+           "key": "url",
+           "leaf": {
+            "url": {
+             "type": "string"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "host-aggregate": {
+       "list": {
+        "host-aggregate": {
+         "description": "Name of the Host Aggregate",
+         "key": "metadata-key",
+         "leaf": {
+          "metadata-key": {
+           "type": "string"
+          },
+          "metadata-value": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "placement-group-input": {
+       "leaf": {
+        "cloud-type": {
+         "type": "manotypes:cloud-account-type"
+        }
+       },
+       "choice": {
+        "cloud-provider": {
+         "case": {
+          "openstack": {
+           "container": {
+            "availability-zone": {
+             "description": "Name of the Availability Zone",
+             "leaf": {
+              "name": {
+               "type": "string"
+              }
+             }
+            },
+            "server-group": {
+             "description": "Name of the Affinity/Anti-Affinity Server Group",
+             "leaf": {
+              "name": {
+               "type": "string"
+              }
+             }
+            }
+           },
+           "list": {
+            "host-aggregate": {
+             "description": "Name of the Host Aggregate",
+             "key": "metadata-key",
+             "leaf": {
+              "metadata-key": {
+               "type": "string"
+              },
+              "metadata-value": {
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "aws": {
+           "leaf": {
+            "aws-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "openmano": {
+           "leaf": {
+            "openmano-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "vsphere": {
+           "leaf": {
+            "vsphere-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "mock": {
+           "leaf": {
+            "mock-construct": {
+             "type": "empty"
+            }
+           }
+          },
+          "cloudsim": {
+           "leaf": {
+            "cloudsim-construct": {
+             "type": "empty"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "placement-group-info": {
+       "description": "",
+       "leaf": {
+        "name": {
+         "description": "Place group construct to define the compute resource placement strategy\nin cloud environment",
+         "type": "string"
+        },
+        "requirement": {
+         "description": "This is free text space used to describe the intent/rationale\nbehind this placement group. This is for human consumption only",
+         "type": "string"
+        },
+        "strategy": {
+         "description": "Strategy associated with this placement group\n  Following values are possible\n    - COLOCATION: Colocation strategy imply intent to share the physical\n                  infrastructure (hypervisor/network) among all members\n                  of this group.\n    - ISOLATION: Isolation strategy imply intent to not share the physical\n                 infrastructure (hypervisor/network) among the members\n                 of this group.\n  ",
+         "type": {
+          "enumeration": {
+           "enum": {
+            "COLOCATION": {
+             "value": 0
+            },
+            "ISOLATION": {
+             "value": 1
+            }
+           }
+          }
+         },
+         "default": "COLOCATION"
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "rw-pb-ext": {
+   "module": {
+    "rw-pb-ext": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-pb-ext",
+     "prefix": "rwpb",
+     "revision": {
+      "2014-03-28": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang extensions for converting yang files to Google\nProtocol Buffers (protobuf) using rift protoc-c extensions."
+      }
+     }
+    }
+   }
+  },
+  "rwvcs-types": {
+   "module": {
+    "rwvcs-types": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rwvcs-types",
+     "prefix": "rwvcstypes",
+     "import": {
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "rw-yang-types": {
+       "prefix": "rwt"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet",
+       "revision-date": "2013-07-15"
+      }
+     },
+     "revision": {
+      "2014-03-12": {
+       "description": "Initial implementation of RW.Manifest.",
+       "reference": "RW.VX Software Component Document"
+      }
+     },
+     "typedef": {
+      "component_type": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "RWCOLLECTION": null,
+          "RWVM": null,
+          "RWPROC": null,
+          "PROC": null,
+          "RWTASKLET": null
+         }
+        }
+       }
+      },
+      "recovery-type": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NONE": null,
+          "RESTART": null,
+          "FAILCRITICAL": null,
+          "IGNORE": null,
+          "CUSTOM": null
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "rwvcs-variable-list": {
+       "leaf-list": {
+        "python-variable": {
+         "description": "List of Python variable assignments",
+         "type": "string"
+        }
+       }
+      },
+      "valgrind": {
+       "container": {
+        "valgrind": {
+         "leaf": {
+          "enable": {
+           "description": "Run the component under valgrind",
+           "type": "boolean"
+          }
+         },
+         "leaf-list": {
+          "opts": {
+           "description": "Command line options to pass to valgrind",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-list": {
+       "list": {
+        "action": {
+         "description": "This section contains a sequence\nof RW.VCS actions",
+         "key": "name",
+         "leaf": {
+          "name": {
+           "description": "Name of the action within the sequence",
+           "type": "string"
+          }
+         },
+         "grouping": {
+          "rwvcs-python-loop": {
+           "leaf": {
+            "python-loop-expression": {
+             "description": "Python expression",
+             "type": "string"
+            },
+            "python-loop-iterate": {
+             "description": "Python iteration",
+             "type": "string"
+            }
+           }
+          }
+         },
+         "uses": "rwvcs-python-loop",
+         "choice": {
+          "action": {
+           "case": {
+            "annex": {
+             "container": {
+              "annex": {
+               "leaf": {
+                "component-name": {
+                 "description": "Name of the component type\nin the inventory",
+                 "type": {
+                  "leafref": {
+                   "path": "../../../../../../../component/component-name"
+                  }
+                 }
+                },
+                "instance-id": {
+                 "description": "ID of the component instance\nin the inventory",
+                 "type": "string"
+                }
+               }
+              }
+             }
+            },
+            "start": {
+             "container": {
+              "start": {
+               "uses": "rwvcs-variable-list",
+               "leaf": {
+                "component-name": {
+                 "description": "Name of the component type in\nthe inventory",
+                 "type": {
+                  "leafref": {
+                   "path": "../../../../../../../component/component-name"
+                  }
+                 }
+                },
+                "instance-id": {
+                 "description": "ID of the component instance\nin the inventory",
+                 "type": "string"
+                },
+                "config-ready": {
+                 "description": "Config readiness check enable",
+                 "type": "boolean",
+                 "default": "true"
+                },
+                "recovery-action": {
+                 "description": "Define recovery action if this component fail",
+                 "type": "recovery-type"
+                }
+               }
+              }
+             }
+            },
+            "sleep": {
+             "container": {
+              "sleep": {
+               "leaf": {
+                "wait-time-usec": {
+                 "description": "Time to wait while sleeping",
+                 "type": "uint32"
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "rwvcs-event-list": {
+       "container": {
+        "event-list": {
+         "description": "",
+         "list": {
+          "event": {
+           "description": "This section contains a list\nof RW.VCS events",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the event",
+             "type": "string"
+            }
+           },
+           "uses": "action-list"
+          }
+         }
+        }
+       }
+      },
+      "rwvcs-rwcollection": {
+       "container": {
+        "rwcollection": {
+         "description": "This section defines a RW.VCS\nrwollection component",
+         "leaf": {
+          "collection-type": {
+           "description": "Collection type",
+           "type": "string"
+          }
+         },
+         "uses": "rwvcs-event-list"
+        }
+       }
+      },
+      "rwvcs-rwvm": {
+       "container": {
+        "rwvm": {
+         "description": "This section defines a RW.VCS\nrwvm component",
+         "leaf": {
+          "pool-name": {
+           "description": "Name of the pool from which to\nallocate the VM",
+           "type": "string"
+          },
+          "leader": {
+           "description": "True if this VM is designated as a leader for\nthe parent collection.",
+           "type": "boolean"
+          }
+         },
+         "uses": {
+          "rwvcs-event-list": null,
+          "valgrind": null
+         }
+        }
+       }
+      },
+      "rwvcs-rwproc": {
+       "container": {
+        "rwproc": {
+         "description": "This section defines a RW.VCS\nrwproc component",
+         "leaf": {
+          "run-as": {
+           "description": "Host OS user that should run this\nprocess, requires sudo -E access\nand non-collapsed processes",
+           "type": "string"
+          }
+         },
+         "list": {
+          "tasklet": {
+           "description": "List of tasklets to be run within\nthis process",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Local description of the tasklet",
+             "type": "string"
+            },
+            "component-name": {
+             "description": "Component name of the tasklet",
+             "mandatory": "true",
+             "type": "string"
+            },
+            "instance-id": {
+             "description": "If specified, the desired instance-id of\ntasklet component instance",
+             "type": "uint32"
+            },
+            "config-ready": {
+             "description": "Config readiness check enable",
+             "type": "boolean",
+             "default": "true"
+            },
+            "recovery-action": {
+             "description": "Define recovery action if this component fail",
+             "type": "recovery-type"
+            }
+           },
+           "uses": "rwvcs-variable-list"
+          }
+         },
+         "uses": "valgrind"
+        }
+       }
+      },
+      "native-proc": {
+       "container": {
+        "native-proc": {
+         "leaf": {
+          "run-as": {
+           "description": "Host OS user that should run this\nprocess, requires sudo -E access",
+           "type": "string"
+          },
+          "environment": {
+           "description": "Runtime environment for native process",
+           "type": "string"
+          },
+          "exe-path": {
+           "description": "Path to native process executable",
+           "type": "string"
+          },
+          "args": {
+           "description": "Arguments to pass to native process",
+           "type": "string"
+          },
+          "network-namespace": {
+           "description": "Namespace to start process in",
+           "type": "string"
+          },
+          "stdout": {
+           "description": "Redirect stdout to the file at the\nspecified path",
+           "type": "string"
+          },
+          "stderr": {
+           "description": "Redirect stderr to the file at the\nspecified path. Optionally, 'stdout'\nmay be used to redirect to the same\nfile as stdout",
+           "type": "string"
+          },
+          "interactive": {
+           "description": "Native process is interactive and needs\nterminal control",
+           "type": "empty"
+          }
+         },
+         "uses": "valgrind"
+        }
+       }
+      },
+      "rwvcs-rwtasklet": {
+       "container": {
+        "rwtasklet": {
+         "description": "This section defines a RW.VCS\nrwtasklet component",
+         "leaf": {
+          "plugin-directory": {
+           "description": "",
+           "type": "string"
+          },
+          "plugin-name": {
+           "description": "",
+           "type": "string"
+          },
+          "plugin-version": {
+           "description": "",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "rwvcs-component-list": {
+       "list": {
+        "component": {
+         "description": "This section defines the RIFT.ware\nvirtual components",
+         "key": "component-name",
+         "leaf": {
+          "component-name": {
+           "description": "",
+           "type": "string"
+          },
+          "component-type": {
+           "description": "",
+           "type": "component_type",
+           "mandatory": "true"
+          }
+         },
+         "choice": {
+          "component": {
+           "case": {
+            "rwvcs-rwcollection": {
+             "uses": "rwvcs-rwcollection"
+            },
+            "rwvcs-rwvm": {
+             "uses": "rwvcs-rwvm"
+            },
+            "rwvcs-rwproc": {
+             "uses": "rwvcs-rwproc"
+            },
+            "native-proc": {
+             "uses": "native-proc"
+            },
+            "rwvcs-rwtasklet": {
+             "uses": "rwvcs-rwtasklet"
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "rw-yang-types": {
+   "module": {
+    "rw-yang-types": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-yang-types",
+     "prefix": "rwt",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet",
+       "revision-date": "2013-07-15"
+      },
+      "ietf-yang-types": {
+       "prefix": "ietf-yang-types",
+       "revision-date": "2013-07-15"
+      }
+     },
+     "description": "This module contains redefinitions of the ietf-yang-types and\nietf-inet-types modules, which allows customized extensions to be\ndefined for these types when used in RiftWare applications.",
+     "revision": {
+      "2014-04-01": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang types that redefine the IETF types."
+      }
+     },
+     "typedef": {
+      "ip-version": {
+       "type": "inet:ip-version"
+      },
+      "dscp": {
+       "type": "inet:dscp"
+      },
+      "ipv6-flow-label": {
+       "type": "inet:ipv6-flow-label"
+      },
+      "port-number": {
+       "type": "inet:port-number"
+      },
+      "as-number": {
+       "type": "inet:as-number"
+      },
+      "ip-address": {
+       "type": "inet:ip-address"
+      },
+      "ipv4-address": {
+       "type": "inet:ipv4-address"
+      },
+      "ipv6-address": {
+       "type": "inet:ipv6-address"
+      },
+      "ip-address-no-zone": {
+       "type": "inet:ip-address-no-zone"
+      },
+      "ipv4-address-no-zone": {
+       "type": "inet:ipv4-address-no-zone"
+      },
+      "ipv6-address-no-zone": {
+       "type": "inet:ipv6-address-no-zone"
+      },
+      "ip-prefix": {
+       "type": "inet:ip-prefix"
+      },
+      "ip-prefix-non-canonical": {
+       "type": {
+        "union": {
+         "type": {
+          "rwt:ipv4-prefix-non-canonical": null,
+          "rwt:ipv6-prefix-non-canonical": null
+         }
+        }
+       },
+       "description": "The ip-prefix type represents an IP prefix and is IP\nversion neutral.  The format of the textual representations\nimplies the IP version."
+      },
+      "ipv4-prefix": {
+       "type": "inet:ipv4-prefix"
+      },
+      "ipv4-prefix-non-canonical": {
+       "type": {
+        "string": {
+         "pattern": "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))"
+        }
+       },
+       "description": "The ipv4-prefix type represents an IPv4 address prefix.\nThe prefix length is given by the number following the\nslash character and must be less than or equal to 32.\n\nA prefix length value of n corresponds to an IP address\nmask that has n contiguous 1-bits from the most\nsignificant bit (MSB) and all other bits set to 0."
+      },
+      "ipv6-prefix": {
+       "type": "inet:ipv6-prefix"
+      },
+      "ipv6-prefix-non-canonical": {
+       "type": {
+        "string": {
+         "pattern": {
+          "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))": null,
+          "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+)": null
+         }
+        }
+       },
+       "description": "The ipv6-prefix type represents an IPv6 address prefix.\nThe prefix length is given by the number following the\nslash character and must be less than or equal to 128.\n\nA prefix length value of n corresponds to an IP address\nmask that has n contiguous 1-bits from the most\nsignificant bit (MSB) and all other bits set to 0.\n\nThe IPv6 address should have all bits that do not belong\nto the prefix set to zero."
+      },
+      "domain-name": {
+       "type": "inet:domain-name"
+      },
+      "host": {
+       "type": "inet:host"
+      },
+      "uri": {
+       "type": "inet:uri"
+      },
+      "counter32": {
+       "type": "ietf-yang-types:counter32"
+      },
+      "zero-based-counter32": {
+       "type": "ietf-yang-types:zero-based-counter32"
+      },
+      "counter64": {
+       "type": "ietf-yang-types:counter64"
+      },
+      "zero-based-counter64": {
+       "type": "ietf-yang-types:zero-based-counter64"
+      },
+      "gauge32": {
+       "type": "ietf-yang-types:gauge32"
+      },
+      "gauge64": {
+       "type": "ietf-yang-types:gauge64"
+      },
+      "object-identifier": {
+       "type": "ietf-yang-types:object-identifier"
+      },
+      "object-identifier-128": {
+       "type": "ietf-yang-types:object-identifier-128"
+      },
+      "yang-identifier": {
+       "type": "ietf-yang-types:yang-identifier"
+      },
+      "date-and-time": {
+       "type": "ietf-yang-types:date-and-time"
+      },
+      "timeticks": {
+       "type": "ietf-yang-types:timeticks"
+      },
+      "timestamp": {
+       "type": "ietf-yang-types:timestamp"
+      },
+      "phys-address": {
+       "type": "ietf-yang-types:phys-address"
+      },
+      "mac-address": {
+       "type": "ietf-yang-types:mac-address"
+      },
+      "xpath1.0": {
+       "type": "ietf-yang-types:xpath1.0"
+      },
+      "hex-string": {
+       "type": "ietf-yang-types:hex-string"
+      },
+      "uuid": {
+       "type": "ietf-yang-types:uuid"
+      },
+      "dotted-quad": {
+       "type": "ietf-yang-types:dotted-quad"
+      },
+      "call-id": {
+       "type": {
+        "string": {
+         "pattern": "[0-9]{1,20}:[0-9]{1,20}"
+        }
+       }
+      },
+      "base64-binary": {
+       "type": {
+        "string": {
+         "pattern": "[0-9a-zA-Z+/]{4,}[=]{0,2}"
+        }
+       }
+      },
+      "hex-binary": {
+       "type": {
+        "string": {
+         "pattern": "[0-9A-Fa-f]{2}([0-9A-Fa-f]{2})*"
+        }
+       }
+      },
+      "rw-ip-protocol": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "icmp": {
+           "value": 1
+          },
+          "tcp": {
+           "value": 6
+          },
+          "udp": {
+           "value": 17
+          },
+          "gre": {
+           "value": 47
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "pkgdir": "/Users/larsmaultsby/Documents/ATG_Branch/rift/modules/ui/rw.ui/skyquake/plugins/composer/src/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/mano-base.yang.src b/skyquake/plugins/composer/src/schemas/yang/mano-base.yang.src
new file mode 100755 (executable)
index 0000000..7220c79
--- /dev/null
@@ -0,0 +1,94 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module mano-base
+{
+  namespace "http://riftio.com/ns/riftware-1.0/mano-base";
+  prefix "manobase";
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import rw-cli-ext {
+    prefix "rwcli";
+  }
+
+  revision 2015-08-25 {
+    description
+      "This YANG file provides agument points for VNF specific 
+       configuration and operational data";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  container vnf-config {
+    description
+        "Container for VNF configuration data";
+    list vnf {
+      description
+          "The VNF configuration data YANG moodel augments this path";
+      rwcli:new-mode "vnf";
+      key "name instance";
+      leaf name {
+        description
+            "Name of the VNF.";
+        type string;
+      }
+      leaf instance{
+        description
+          "Instance number of the VNF.";
+        type uint32;
+      }
+      leaf id {
+        description
+            "Identifier for the VNF";
+        type yang:uuid;
+      }
+    }
+  }
+
+  container vnf-opdata {
+    description
+        "Container for VNF operational data";
+    config false;
+    list vnf {
+      description
+          "The VNF operational data YANG model augments this path";
+      key "name instance";
+      config false;
+      leaf name {
+        description
+          "Name of the VNF.";
+        type string;
+      }
+      leaf instance{
+        description
+          "Instance number of the VNF.";
+        type uint32;
+      }
+      leaf id {
+        description
+            "Identifier for the VNF";
+        type yang:uuid;
+      }
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/mano-types.yang.src b/skyquake/plugins/composer/src/schemas/yang/mano-types.yang.src
new file mode 100755 (executable)
index 0000000..17c16e6
--- /dev/null
@@ -0,0 +1,1865 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module mano-types
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:mano-types";
+  prefix "manotypes";
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  revision 2015-04-23 {
+    description
+      "Initial revision. This YANG file defines
+       the reusable base types for VNF Management
+       and Orchestration (MANO).";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  typedef parameter-data-type {
+    type enumeration {
+      enum STRING;
+      enum INTEGER;
+      enum BOOLEAN;
+    }
+  }
+
+  grouping primitive-parameter {
+    leaf name {
+      description
+          "Name of the parameter.";
+      type string;
+    }
+
+    leaf data-type {
+      description
+          "Data type associated with the name.";
+      type manotypes:parameter-data-type;
+    }
+
+    leaf mandatory {
+      description "Is this field mandatory";
+      type boolean;
+      default false;
+    }
+
+    leaf default-value {
+      description "The default value for this field";
+      type string;
+    }
+
+    leaf parameter-pool {
+      description "NSD Parameter pool name to use for this paramter";
+      type string;
+    }
+
+    leaf read-only {
+      description
+        "The value should be greyed out by the UI.
+        Only applies to parameters with default values.";
+      type boolean;
+    }
+
+    leaf hidden {
+      description
+        "The value should be hidden by the UI.
+        Only applies to parameters with default values.";
+      type boolean;
+    }
+  }
+
+
+  grouping vnf-configuration {
+    container vnf-configuration {
+      ////rwpb:msg-new VnfConfiguration;
+      description
+          "Information regarding the VNF configuration
+           is captured here. ";
+
+      choice config-method {
+        description
+            "Defines the configuration method for the VNF.";
+        case netconf {
+          description
+              "Use NETCONF for configuring the VNF.";
+          container netconf {
+            leaf target {
+              description
+                  "Netconf configuration target";
+              type enumeration {
+                enum running;
+                enum candidate;
+              }
+            }
+
+            leaf protocol {
+              description
+                  "Protocol to use for netconf (e.g. ssh)";
+              type enumeration {
+                enum None;
+                enum ssh;
+              }
+            }
+
+            leaf port {
+              description
+                  "Port for the netconf server.";
+              type inet:port-number;
+            }
+          }
+        }
+
+        case rest {
+          description
+              "Use REST for configuring the VNF.";
+          container rest {
+            leaf port {
+              description
+                  "Port for the REST server.";
+              type inet:port-number;
+            }
+          }
+        }
+
+        case script {
+          description
+              "Use custom script for configuring the VNF.
+               This script is executed in the context of
+               Orchestrator.";
+          container script {
+            leaf script-type {
+              description
+                  "Script type - currently supported : bash, expect";
+              type enumeration {
+                enum bash;
+                enum expect;
+              }
+            }
+          }
+        }
+
+        case juju {
+          description
+            "Configure the VNF through Juju.";
+          container juju {
+            leaf charm {
+              description "Juju charm to use with the VNF.";
+              type string;
+            }
+          }
+        }
+      }
+
+      container config-access {
+        leaf mgmt-ip-address {
+          description
+              "IP address to be used to configure this VNF,
+               optional if it is possible to resolve dynamically.";
+          type inet:ip-address;
+        }
+
+        leaf username {
+          description
+              "username for configuration.";
+          type string;
+        }
+
+        leaf password {
+          description
+              "Password for configuration access authentication.";
+          type string;
+        }
+      }
+
+      container config-attributes {
+        description
+            "Miscelaneous input parameters to be considered
+             while processing the NSD to apply configuration";
+
+        leaf config-priority {
+          description
+              "Configuration priority - order of confgiration
+               to be applied to each VNF in this NS,
+               low number gets precedence over high number";
+          type uint64;
+        }
+
+        leaf config-delay {
+          description
+              "Wait (seconds) before applying the configuration to VNF";
+          type uint64;
+        }
+      }
+
+      list config-primitive {
+        ////rwpb:msg-new ConfigPrimitive;
+        description
+            "List of configuration primitives supported by the
+            configuration agent for this VNF.";
+        key "name";
+
+        leaf name {
+          description
+              "Name of the configuration primitive.";
+          type string;
+        }
+
+        list parameter {
+          description
+              "List of parameters to the configuration primitive.";
+          key "name";
+          uses primitive-parameter;
+        }
+      }
+
+      list initial-config-primitive {
+        ////rwpb:msg-new InitialConfigPrimitive;
+        description
+            "Initial set of configuration primitives.";
+        key "seq";
+        leaf seq {
+          description
+              "Sequence number for the configuration primitive.";
+          type uint64;
+        }
+
+        leaf name {
+          description
+              "Name of the configuration primitive.";
+          type string;
+        }
+
+        list parameter {
+          key "name";
+          leaf name {
+            type string;
+          }
+
+          leaf value {
+            type string;
+          }
+        }
+      }
+
+      leaf config-template {
+        description
+            "Configuration template for each VNF";
+        type string;
+      }
+    }
+  } // END - grouping vnf-configuration
+
+  typedef virtual-link-type {
+    description
+        "Type of virtual link
+         ELAN: A multipoint service connecting a set of VNFs
+         // ELINE: For a simple point to point connection
+         //        between a VNF and the existing network.
+         // ETREE: A multipoint service connecting one or
+         //        more roots and a set of leaves, but
+         //        preventing inter-leaf communication.";
+    type enumeration {
+      enum ELAN;
+      // enum ETREE;
+      // enum ELINE;
+    }
+  }
+
+  grouping named-value {
+    leaf name {
+      type string;
+    }
+
+    leaf value {
+      type string;
+    }
+  }
+
+  typedef http-method {
+    description
+      "Type of HTTP operation";
+
+    type enumeration {
+      enum POST;
+      enum PUT;
+      enum GET;
+      enum DELETE;
+      enum OPTIONS;
+      enum PATCH;
+    }
+  }
+
+  typedef api-type {
+    description
+      "Type of API to fetch monitoring params";
+
+    type enumeration {
+      enum HTTP;
+      enum NETCONF;
+      enum SOAP;
+    }
+  }
+
+  typedef json-query-method {
+    description
+      "The method to extract a value from a JSON response
+
+       NAMEKEY - Use the name as the key for a non-nested value.
+       JSONPATH - Use jsonpath-rw implemenation to extract a value.
+       OBJECTPATH - Use objectpath implemenation to extract a value.";
+      type enumeration {
+        enum NAMEKEY;
+        enum JSONPATH;
+        enum OBJECTPATH;
+      }
+  }
+
+  typedef param-value-type {
+    description
+      "The type of the parameter value";
+    type enumeration {
+       enum INT;
+       enum DECIMAL;
+       enum STRING;
+    }
+  }
+
+  typedef connection-point-type {
+    description
+        "Type of connection point
+        VPORT: Virtual Port
+        // VNIC_ADDR: Virtual NIC Address
+        // PNIC_ADDR: Physical NIC Address
+        // PPORT: Phsical Port.";
+
+    type enumeration {
+      enum VPORT;
+    }
+  }
+
+  typedef widget-type {
+    description
+        "Type of the widget, typically used by the UI.";
+    type enumeration {
+      enum HISTOGRAM;
+      enum BAR;
+      enum GAUGE;
+      enum SLIDER;
+      enum COUNTER;
+      enum TEXTBOX;
+    }
+  }
+
+  typedef cpu-feature-type {
+    description
+        "Enumeration for CPU features.
+
+         AES: CPU supports advanced instruction set for
+         AES (Advanced Encryption Standard).
+
+         CAT: Cache Allocation Technology (CAT) allows
+         an Operating System, Hypervisor, or similar
+         system management agent to specify the amount
+         of L3 cache (currently the last-level cache
+         in most server and client platforms) space an
+         application can fill (as a hint to hardware
+         functionality, certain features such as power
+         management may override CAT settings).
+
+         CMT: Cache Monitoring Technology (CMT) allows
+         an Operating System, Hypervisor, or similar
+         system management agent to determine the
+         usage of cache based on applications running
+         on the platform. The implementation is
+         directed at L3 cache monitoring (currently
+         the last-level cache in most server and
+         client platforms).
+
+         DDIO: Intel Data Direct I/O (DDIO) enables
+         Ethernet server NICs and controllers talk
+         directly to the processor cache without a
+         detour via system memory. This enumeration
+         specifies if the VM requires a DDIO
+         capable host.";
+
+    type enumeration {
+      enum PREFER_AES;
+      enum REQUIRE_AES;
+      enum PREFER_CAT;
+      enum REQUIRE_CAT;
+      enum PREFER_CMT;
+      enum REQUIRE_CMT;
+      enum PREFER_DDIO;
+      enum REQUIRE_DDIO;
+      enum REQUIRE_VME;
+      enum PREFER_VME;
+      enum REQUIRE_DE;
+      enum PREFER_DE;
+      enum REQUIRE_PSE;
+      enum PREFER_PSE;
+      enum REQUIRE_TSC;
+      enum PREFER_TSC;
+      enum REQUIRE_MSR;
+      enum PREFER_MSR;
+      enum REQUIRE_PAE;
+      enum PREFER_PAE;
+      enum REQUIRE_MCE;
+      enum PREFER_MCE;
+      enum REQUIRE_CX8;
+      enum PREFER_CX8;
+      enum REQUIRE_APIC;
+      enum PREFER_APIC;
+      enum REQUIRE_SEP;
+      enum PREFER_SEP;
+      enum REQUIRE_MTRR;
+      enum PREFER_MTRR;
+      enum REQUIRE_PGE;
+      enum PREFER_PGE;
+      enum REQUIRE_MCA;
+      enum PREFER_MCA;
+      enum REQUIRE_CMOV;
+      enum PREFER_CMOV;
+      enum REQUIRE_PAT;
+      enum PREFER_PAT;
+      enum REQUIRE_PSE36;
+      enum PREFER_PSE36;
+      enum REQUIRE_CLFLUSH;
+      enum PREFER_CLFLUSH;
+      enum REQUIRE_DTS;
+      enum PREFER_DTS;
+      enum REQUIRE_ACPI;
+      enum PREFER_ACPI;
+      enum REQUIRE_MMX;
+      enum PREFER_MMX;
+      enum REQUIRE_FXSR;
+      enum PREFER_FXSR;
+      enum REQUIRE_SSE;
+      enum PREFER_SSE;
+      enum REQUIRE_SSE2;
+      enum PREFER_SSE2;
+      enum REQUIRE_SS;
+      enum PREFER_SS;
+      enum REQUIRE_HT;
+      enum PREFER_HT;
+      enum REQUIRE_TM;
+      enum PREFER_TM;
+      enum REQUIRE_IA64;
+      enum PREFER_IA64;
+      enum REQUIRE_PBE;
+      enum PREFER_PBE;
+      enum REQUIRE_RDTSCP;
+      enum PREFER_RDTSCP;
+      enum REQUIRE_PNI;
+      enum PREFER_PNI;
+      enum REQUIRE_PCLMULQDQ;
+      enum PREFER_PCLMULQDQ;
+      enum REQUIRE_DTES64;
+      enum PREFER_DTES64;
+      enum REQUIRE_MONITOR;
+      enum PREFER_MONITOR;
+      enum REQUIRE_DS_CPL;
+      enum PREFER_DS_CPL;
+      enum REQUIRE_VMX;
+      enum PREFER_VMX;
+      enum REQUIRE_SMX;
+      enum PREFER_SMX;
+      enum REQUIRE_EST;
+      enum PREFER_EST;
+      enum REQUIRE_TM2;
+      enum PREFER_TM2;
+      enum REQUIRE_SSSE3;
+      enum PREFER_SSSE3;
+      enum REQUIRE_CID;
+      enum PREFER_CID;
+      enum REQUIRE_FMA;
+      enum PREFER_FMA;
+      enum REQUIRE_CX16;
+      enum PREFER_CX16;
+      enum REQUIRE_XTPR;
+      enum PREFER_XTPR;
+      enum REQUIRE_PDCM;
+      enum PREFER_PDCM;
+      enum REQUIRE_PCID;
+      enum PREFER_PCID;
+      enum REQUIRE_DCA;
+      enum PREFER_DCA;
+      enum REQUIRE_SSE4_1;
+      enum PREFER_SSE4_1;
+      enum REQUIRE_SSE4_2;
+      enum PREFER_SSE4_2;
+      enum REQUIRE_X2APIC;
+      enum PREFER_X2APIC;
+      enum REQUIRE_MOVBE;
+      enum PREFER_MOVBE;
+      enum REQUIRE_POPCNT;
+      enum PREFER_POPCNT;
+      enum REQUIRE_TSC_DEADLINE_TIMER;
+      enum PREFER_TSC_DEADLINE_TIMER;
+      enum REQUIRE_XSAVE;
+      enum PREFER_XSAVE;
+      enum REQUIRE_AVX;
+      enum PREFER_AVX;
+      enum REQUIRE_F16C;
+      enum PREFER_F16C;
+      enum REQUIRE_RDRAND;
+      enum PREFER_RDRAND;
+      enum REQUIRE_FSGSBASE;
+      enum PREFER_FSGSBASE;
+      enum REQUIRE_BMI1;
+      enum PREFER_BMI1;
+      enum REQUIRE_HLE;
+      enum PREFER_HLE;
+      enum REQUIRE_AVX2;
+      enum PREFER_AVX2;
+      enum REQUIRE_SMEP;
+      enum PREFER_SMEP;
+      enum REQUIRE_BMI2;
+      enum PREFER_BMI2;
+      enum REQUIRE_ERMS;
+      enum PREFER_ERMS;
+      enum REQUIRE_INVPCID;
+      enum PREFER_INVPCID;
+      enum REQUIRE_RTM;
+      enum PREFER_RTM;
+      enum REQUIRE_MPX;
+      enum PREFER_MPX;
+      enum REQUIRE_RDSEED;
+      enum PREFER_RDSEED;
+      enum REQUIRE_ADX;
+      enum PREFER_ADX;
+      enum REQUIRE_SMAP;
+      enum PREFER_SMAP;
+    }
+  }
+
+  grouping vm-flavor {
+    container vm-flavor {
+      leaf vcpu-count {
+        description
+            "Number of vcpus for the VM.";
+        type uint16;
+      }
+
+      leaf memory-mb {
+        description
+            "Amount of memory in MB.";
+        type uint64;
+      }
+
+      leaf storage-gb {
+        description
+            "Amount of disk space in GB.";
+        type uint64;
+      }
+    }
+  } //grouping vm-flavor
+
+  grouping vswitch-epa {
+    container vswitch-epa {
+      leaf ovs-acceleration {
+        description
+            "Specifies Open vSwitch acceleration mode.
+             MANDATORY: OVS acceleration is required
+             PREFERRED: OVS acceleration is preferred";
+        type enumeration {
+          enum MANDATORY;
+          enum PREFERRED;
+          enum DISABLED;
+        }
+      }
+
+      leaf ovs-offload {
+        description
+            "Specifies Open vSwitch hardware offload mode.
+             MANDATORY: OVS offload is required
+             PREFERRED: OVS offload is preferred";
+        type enumeration {
+          enum MANDATORY;
+          enum PREFERRED;
+          enum DISABLED;
+        }
+      }
+    }
+  }
+
+  grouping hypervisor-epa {
+    container hypervisor-epa {
+      leaf type {
+        description
+            "Specifies the type of hypervisor.
+             KVM: KVM
+             XEN: XEN";
+        type enumeration {
+          enum PREFER_KVM;
+          enum REQUIRE_KVM;
+        }
+      }
+      leaf version {
+        type string;
+      }
+    }
+  }
+
+  grouping host-epa {
+    container host-epa {
+      description "Specifies the host level EPA attributes.";
+      leaf cpu-model {
+        description
+            "Host CPU model. Examples include: SandyBridge,
+             IvyBridge";
+        type enumeration {
+          enum PREFER_WESTMERE;
+          enum REQUIRE_WESTMERE;
+          enum PREFER_SANDYBRIDGE;
+          enum REQUIRE_SANDYBRIDGE;
+          enum PREFER_IVYBRIDGE;
+          enum REQUIRE_IVYBRIDGE;
+          enum PREFER_HASWELL;
+          enum REQUIRE_HASWELL;
+          enum PREFER_BROADWELL;
+          enum REQUIRE_BROADWELL;
+          enum PREFER_NEHALEM;
+          enum REQUIRE_NEHALEM;
+          enum PREFER_PENRYN;
+          enum REQUIRE_PENRYN;
+          enum PREFER_CONROE;
+          enum REQUIRE_CONROE;
+          enum PREFER_CORE2DUO;
+          enum REQUIRE_CORE2DUO;
+        }
+      }
+
+      leaf cpu-arch {
+        description "Host CPU architecture.";
+        type enumeration {
+          enum PREFER_X86;
+          enum REQUIRE_X86;
+          enum PREFER_X86_64;
+          enum REQUIRE_X86_64;
+          enum PREFER_I686;
+          enum REQUIRE_I686;
+          enum PREFER_IA64;
+          enum REQUIRE_IA64;
+          enum PREFER_ARMV7;
+          enum REQUIRE_ARMV7;
+          enum PREFER_ARMV8;
+          enum REQUIRE_ARMV8;
+        }
+      }
+
+      leaf cpu-vendor {
+        description "Host CPU Vendor.";
+        type enumeration {
+          enum PREFER_INTEL;
+          enum REQUIRE_INTEL;
+          enum PREFER_AMD;
+          enum REQUIRE_AMD;
+        }
+      }
+
+      leaf cpu-socket-count {
+        description "Number of sockets on the host.";
+        type uint64;
+      }
+
+      leaf cpu-core-count {
+        description "Number of cores on the host.";
+        type uint64;
+      }
+
+      leaf cpu-core-thread-count {
+        description "Number of threads per cores on the host.";
+        type uint64;
+      }
+
+      leaf-list cpu-feature {
+        description
+            "List of CPU features.";
+        type manotypes:cpu-feature-type;
+      }
+
+
+      leaf om-cpu-model-string {
+        description "Openmano CPU model string";
+        type string;
+      }
+
+      leaf-list om-cpu-feature {
+        description "Openmano CPU features";
+        type string;
+      }
+    }
+  }
+
+  grouping guest-epa {
+    description "EPA attributes for the guest";
+    container guest-epa {
+      leaf trusted-execution {
+        description "This VM should be allocated from trusted pool";
+        type boolean;
+      }
+
+      leaf mempage-size {
+        description
+            "Memory page allocation size. If a VM requires
+             hugepages, it should choose LARGE or SIZE_2MB
+             or SIZE_1GB. If the VM prefers hugepages it
+             should chose PREFER_LARGE.
+             LARGE        : Require hugepages (either 2MB or 1GB)
+             SMALL        : Doesn't require hugepages
+             SIZE_2MB     : Requires 2MB hugepages
+             SIZE_1GB     : Requires 1GB hugepages
+             PREFER_LARGE : Application perfers hugepages";
+        type enumeration {
+          enum LARGE;
+          enum SMALL;
+          enum SIZE_2MB;
+          enum SIZE_1GB;
+          enum PREFER_LARGE;
+        }
+      }
+
+      leaf cpu-pinning-policy {
+        description
+            "CPU pinning policy describes association
+             between virtual CPUs in guest and the
+             physical CPUs in the host.
+             DEDICATED : Virtual CPUs are pinned to
+                         physical CPUs
+             SHARED    : Multiple VMs may share the
+                         same physical CPUs.
+             ANY       : Any policy is acceptable for the VM";
+        type enumeration {
+          enum DEDICATED;
+          enum SHARED;
+          enum ANY;
+        }
+        default "ANY";
+      }
+
+      leaf cpu-thread-pinning-policy {
+          description
+            "CPU thread pinning policy describes how to
+             place the guest CPUs when the host supports
+             hyper threads:
+             AVOID   : Avoids placing a guest on a host
+                       with threads.
+             SEPARATE: Places vCPUs on separate cores,
+                       and avoids placing two vCPUs on
+                       two threads of same core.
+             ISOLATE : Places each vCPU on a different core,
+                       and places no vCPUs from a different
+                       guest on the same core.
+             PREFER  : Attempts to place vCPUs on threads
+                       of the same core.";
+        type enumeration {
+          enum AVOID;
+          enum SEPARATE;
+          enum ISOLATE;
+          enum PREFER;
+        }
+      }
+
+      list pcie-device {
+        description
+            "List of pcie passthrough devices.";
+        key device-id;
+        leaf device-id {
+          description
+              "Device identifier.";
+          type string;
+        }
+        leaf count {
+          description
+              "Number of devices to attach to the VM.";
+          type uint64;
+        }
+      }
+
+      choice numa-policy {
+        case numa-unware {
+          leaf numa-unware {
+            type empty;
+          }
+        }
+
+        case numa-aware {
+          container numa-node-policy {
+            description
+                "This policy defines numa topology of the
+                 guest. Specifically identifies if the guest
+                 should be run on a host with one numa
+                 node or multiple numa nodes. As an example
+                 a guest may want 8 vcpus and 4 GB of
+                 memory. But may want the vcpus and memory
+                 distributed across multiple numa nodes.
+                 The NUMA node 1 may run with 6 vcpus and
+                 3GB, and NUMA node 2 may run with 2 vcpus
+                 and 1GB.";
+
+            leaf node-cnt {
+              description
+                  "The number of numa nodes to expose to the VM.";
+              type uint16;
+            }
+
+            leaf mem-policy {
+              description
+                  "This policy specifies how the memory should
+                   be allocated in a multi-node scenario.
+                   STRICT    : The memory must be allocated
+                               strictly from the memory attached
+                               to the NUMA node.
+                   PREFERRED : The memory should be allocated
+                               perferentially from the memory
+                               attached to the NUMA node";
+              type enumeration {
+                enum STRICT;
+                enum PREFERRED;
+              }
+            }
+
+           list node {
+              key id;
+              leaf id {
+                description
+                    "NUMA node identification. Typically
+                     it's 0 or 1";
+                type uint64;
+              }
+
+              leaf-list vcpu {
+                description
+                    "List of vcpus to allocate on
+                     this numa node.";
+                type uint64;
+              }
+
+              leaf memory-mb {
+                description
+                    "Memory size expressed in MB
+                     for this NUMA node.";
+                type uint64;
+              }
+
+              choice om-numa-type {
+                description
+                    "Openmano Numa type selection";
+
+                case cores {
+                  leaf num-cores {
+                    type uint8;
+                  }
+                }
+
+                case paired-threads {
+                  container paired-threads {
+                    leaf num-paired-threads {
+                      type uint8;
+                    }
+
+                    list paired-thread-ids {
+                      description
+                          "List of thread pairs to use in case of paired-thread numa";
+                      max-elements 16;
+                      key thread-a;
+
+                      leaf thread-a {
+                          type uint8;
+                      }
+
+                      leaf thread-b {
+                          type uint8;
+                      }
+                    }
+                  }
+                }
+                case threads {
+                  leaf num-threads {
+                    type uint8;
+                  }
+                }
+              }
+            }
+
+          }
+        }
+      }
+    }
+  }
+
+  grouping provider-network {
+    container provider-network {
+      description "Container for the provider network.";
+      leaf physical-network {
+        description
+            "Name of the phsyical network on which the provider
+             network is built.";
+        type string;
+      }
+
+      leaf overlay-type {
+        description
+            "Type of the overlay network.";
+        type enumeration {
+          enum LOCAL;
+          enum FLAT;
+          enum VLAN;
+          enum VXLAN;
+          enum GRE;
+        }
+      }
+      leaf segmentation_id {
+        description
+            "Segmentation ID";
+            type uint32;
+      }
+    }
+  }
+  grouping config-primitive {
+    list config-primitive {
+      description
+          "Network service level configuration primitives.";
+
+      key "name";
+
+      leaf name {
+        description
+            "Name of the configuration primitive.";
+        type string;
+      }
+
+      list parameter {
+        description
+            "List of parameters to the configuration primitive.";
+
+        key "name";
+        uses manotypes:primitive-parameter;
+      }
+
+      list parameter-group {
+        description
+            "Grouping of parameters which are logically grouped in UI";
+        key "name";
+
+        leaf name {
+          description
+              "Name of the parameter group";
+          type string;
+        }
+
+        list parameter {
+          description
+              "List of parameters to the configuration primitive.";
+          key "name";
+          uses manotypes:primitive-parameter;
+        }
+
+        leaf mandatory {
+          description "Is this parameter group mandatory";
+          type boolean;
+          default true;
+        }
+      }
+
+      list vnf-primitive-group {
+        description
+            "List of configuration primitives grouped by VNF.";
+
+        key "member-vnf-index-ref";
+        leaf member-vnf-index-ref {
+          description
+              "Reference to member-vnf within constituent-vnfds";
+          type uint64;
+        }
+
+        leaf vnfd-id-ref {
+          description
+              "A reference to a vnfd. This is a
+               leafref to path:
+                   ../../../../nsd:constituent-vnfd
+                   + [nsd:id = current()/../nsd:id-ref]
+                   + /nsd:vnfd-id-ref
+               NOTE: An issue with confd is preventing the
+               use of xpath. Seems to be an issue with leafref
+               to leafref, whose target is in a different module.
+               Once that is resovled this will switched to use
+               leafref";
+
+          type string;
+        }
+
+        leaf vnfd-name {
+          description
+              "Name of the VNFD";
+          type string;
+        }
+
+        list primitive {
+          key "index";
+
+          leaf index {
+            description "Index of this primitive";
+            type uint32;
+          }
+
+          leaf name {
+            description "Name of the primitive in the VNF primitive ";
+            type string;
+          }
+        }
+      }
+
+      leaf user-defined-script {
+        description
+            "A user defined script.";
+        type string;
+      }
+      }
+  }
+
+  grouping monitoring-param {
+    list http-endpoint {
+      description
+          "List of http endpoints to be used by monitoring params";
+      key path;
+
+      leaf path {
+        description "The HTTP path on the management server";
+        type string;
+      }
+
+      leaf https {
+        description "Pick HTTPS instead of HTTP , Default is false";
+        type boolean;
+        default "false";
+      }
+
+      leaf port {
+        description "The HTTP port to connect to";
+        type inet:port-number;
+      }
+
+      leaf username {
+        description "The HTTP basic auth username";
+        type string;
+      }
+
+      leaf password {
+        description "The HTTP basic auth password";
+        type string;
+      }
+
+      leaf polling_interval_secs {
+        description "The HTTP polling interval in seconds";
+        type uint8;
+        default 2;
+      }
+
+      leaf method {
+        description
+          "This is the method to be performed at the uri.
+           GET by default for action";
+
+        type manotypes:http-method;
+        default "GET";
+      }
+
+      list headers {
+        description "Custom HTTP headers to put on HTTP request";
+        key key;
+        leaf key{
+          description "HTTP header key";
+          type string;
+        }
+
+        leaf value{
+          description "HTTP header value";
+          type string;
+        }
+      }
+    }
+
+    list monitoring-param {
+      description
+          "List of monitoring parameters at the NS level";
+      key id;
+      leaf id {
+        type string;
+      }
+
+      leaf name {
+        type string;
+      }
+
+      leaf http-endpoint-ref {
+        type leafref {
+          path "../../http-endpoint/path";
+        }
+      }
+
+      leaf json-query-method {
+        type manotypes:json-query-method;
+        default "NAMEKEY";
+      }
+
+      container json-query-params {
+        leaf json-path {
+          description
+            "The jsonpath to use to extract value from JSON structure";
+          type string;
+        }
+        leaf object-path {
+          description
+            "The objectpath to use to extract value from JSON structure";
+          type string;
+        }
+      }
+
+      leaf description {
+        type string;
+      }
+
+      leaf group-tag {
+        description "A simple tag to group monitoring parameters";
+        type string;
+      }
+
+      leaf value-type {
+        type manotypes:param-value-type;
+        default "INT";
+      }
+
+      container numeric-constraints {
+        leaf min-value {
+          description
+              "Minimum value for the parameter";
+          type uint64;
+        }
+        leaf max-value {
+          description
+              "Maxium value for the parameter";
+          type uint64;
+        }
+      }
+
+      container text-constraints {
+        leaf min-length {
+          description
+              "Minimum string length for the parameter";
+          type uint8;
+        }
+        leaf max-length {
+          description
+              "Maximum string length for the parameter";
+          type uint8;
+        }
+      }
+
+      leaf value-integer {
+        description
+            "Current value for an integer parameter";
+        type int64;
+      }
+
+      leaf value-decimal {
+        description
+            "Current value for a decimal parameter";
+        type decimal64 {
+          fraction-digits 4;
+        }
+      }
+
+      leaf value-string {
+        description
+            "Current value for a string parameter";
+        type string;
+      }
+
+      leaf widget-type {
+        type manotypes:widget-type;
+      }
+
+      leaf units {
+        type string;
+      }
+    }
+  }
+
+  grouping control-param {
+    list control-param {
+      description
+          "List of control parameters to manage and
+           update the running configuration of the VNF";
+      key id;
+
+      leaf id {
+        type string;
+      }
+
+      leaf name {
+        type string;
+      }
+
+      leaf description {
+        type string;
+      }
+
+      leaf group-tag {
+        description "A simple tag to group control parameters";
+        type string;
+      }
+
+      leaf min-value {
+        description
+            "Minimum value for the parameter";
+        type uint64;
+      }
+
+      leaf max-value {
+        description
+            "Maxium value for the parameter";
+        type uint64;
+      }
+
+      leaf current-value {
+        description
+            "Current value for the parameter";
+        type uint64;
+      }
+
+      leaf step-value {
+        description
+            "Step value for the parameter";
+        type uint64;
+      }
+
+      leaf units {
+        type string;
+      }
+
+      leaf widget-type {
+        type manotypes:widget-type;
+      }
+
+      leaf url {
+        description
+          "This is the URL where to perform the operation";
+
+        type inet:uri;
+      }
+
+      leaf method {
+        description
+          "This is the method to be performed at the uri.
+           POST by default for action";
+
+        type manotypes:http-method;
+        default "POST";
+      }
+
+      leaf payload {
+        description
+          "This is the operation payload or payload template as stringified
+           JSON. This field provides the data  to be sent for this operation
+           call";
+
+        type string;
+      }
+    }
+  }
+
+  grouping action-param {
+    list action-param {
+      description
+          "List of action parameters to
+           control VNF";
+      key id;
+      leaf id {
+        type string;
+      }
+
+      leaf name {
+        type string;
+      }
+
+      leaf description {
+        type string;
+      }
+
+      leaf group-tag {
+        description "A simple tag to group monitoring parameter";
+        type string;
+      }
+
+      leaf url {
+        description
+          "This is the URL where to perform the operation";
+        type inet:uri;
+      }
+
+      leaf method {
+        description
+          "This is the method to be performed at the uri.
+           POST by default for action";
+
+        type manotypes:http-method;
+        default "POST";
+      }
+
+      leaf payload {
+        description
+          "This is the operation payload or payload template to be sent in
+           the data for this operation call";
+
+        type string;
+      }
+    }
+  }
+
+  grouping input-parameter {
+    description "";
+
+    list input-parameter {
+      description
+          "List of input parameters";
+
+      key xpath;
+
+
+      leaf xpath {
+        description
+          "A an xpath that specfies which element in a descriptor is to be
+          modified.";
+        type string;
+      }
+
+      leaf value {
+        description
+          "The value that the element specified by the xpath should take when a
+          record is created.";
+        type string;
+      }
+    }
+  }
+
+  grouping input-parameter-xpath {
+    list input-parameter-xpath {
+      description
+          "List of xpaths to parameters inside the NSD
+           the can be customized during the instantiation.";
+
+      key "xpath";
+      leaf xpath {
+        description
+            "An xpath that specifies the element in a descriptor.";
+        type string;
+      }
+
+      leaf label {
+        description "A descriptive string";
+        type string;
+      }
+
+      leaf default-value {
+        description " A default value for this input parameter";
+        type string;
+      }
+    }
+  }
+
+  grouping nfvi-metrics {
+    container vcpu {
+      leaf label {
+        description
+          "Label to show in UI";
+        type string;
+        default "VCPU";
+      }
+
+      leaf total {
+        description
+          "The total number of VCPUs available.";
+        type uint64;
+      }
+
+      leaf utilization {
+        description
+          "The VCPU utilization (percentage).";
+        type decimal64 {
+          fraction-digits 2;
+          range "0 .. 100";
+        }
+      }
+    }
+
+    container memory {
+      leaf label {
+        description
+          "Label to show in UI";
+        type string;
+        default "MEMORY";
+      }
+
+      leaf used {
+        description
+          "The amount of memory (bytes) currently in use.";
+        type uint64;
+      }
+
+      leaf total {
+        description
+          "The amount of memory (bytes) available.";
+        type uint64;
+      }
+
+      leaf utilization {
+        description
+          "The memory utilization (percentage).";
+        type decimal64 {
+          fraction-digits 2;
+          range "0 .. 100";
+        }
+      }
+    }
+
+    container storage {
+      leaf label {
+        description
+          "Label to show in UI";
+        type string;
+        default "STORAGE";
+      }
+
+      leaf used {
+        description
+          "The amount of storage (bytes) currently in use.";
+        type uint64;
+      }
+
+      leaf total {
+        description
+          "The amount of storage (bytes) available.";
+        type uint64;
+      }
+
+      leaf utilization {
+        description
+          "The storage utilization (percentage).";
+        type decimal64 {
+          fraction-digits 2;
+          range "0 .. 100";
+        }
+      }
+    }
+
+    container external-ports {
+      leaf label {
+        description
+          "Label to show in UI";
+        type string;
+        default "EXTERNAL PORTS";
+      }
+
+      leaf total {
+        description
+          "The total number of external ports.";
+        type uint64;
+      }
+    }
+
+    container internal-ports {
+      leaf label {
+        description
+          "Label to show in UI";
+        type string;
+        default "INTERNAL PORTS";
+      }
+
+      leaf total {
+        description
+          "The total number of internal ports.";
+        type uint64;
+      }
+    }
+
+    container network {
+      leaf label {
+        description
+          "Label to show in UI";
+        type string;
+        default "NETWORK TRAFFIC";
+      }
+
+      container incoming {
+        leaf label {
+          description
+            "Label to show in UI";
+          type string;
+          default "INCOMING NETWORK TRAFFIC";
+        }
+
+        leaf bytes {
+          description
+            "The cumulative number of incoming bytes.";
+          type uint64;
+        }
+
+        leaf packets {
+          description
+            "The cumulative number of incoming packets.";
+          type uint64;
+        }
+
+        leaf byte-rate {
+          description
+            "The current incoming byte-rate (bytes per second).";
+          type decimal64 {
+            fraction-digits 2;
+          }
+        }
+
+        leaf packet-rate {
+          description
+            "The current incoming packet (packets per second).";
+          type decimal64 {
+            fraction-digits 2;
+          }
+        }
+      }
+
+      container outgoing {
+        leaf label {
+          description
+            "Label to show in UI";
+          type string;
+          default "OUTGOING NETWORK TRAFFIC";
+        }
+
+        leaf bytes {
+          description
+            "The cumulative number of outgoing bytes.";
+          type uint64;
+        }
+
+        leaf packets {
+          description
+            "The cumulative number of outgoing packets.";
+          type uint64;
+        }
+
+        leaf byte-rate {
+          description
+            "The current outgoing byte-rate (bytes per second).";
+          type decimal64 {
+            fraction-digits 2;
+          }
+        }
+
+        leaf packet-rate {
+          description
+            "The current outgoing packet (packets per second).";
+          type decimal64 {
+            fraction-digits 2;
+          }
+        }
+      }
+    }
+  }
+
+  typedef alarm-severity-type {
+    description "An indication of the importance or ugency of the alarm";
+    type enumeration {
+      enum LOW;
+      enum MODERATE;
+      enum CRITICAL;
+    }
+  }
+
+  typedef alarm-metric-type {
+    description "The type of metrics to register the alarm for";
+    type enumeration {
+      enum CPU_UTILIZATION;
+      enum MEMORY_UTILIZATION;
+      enum STORAGE_UTILIZATION;
+    }
+  }
+
+  typedef alarm-statistic-type {
+    description
+        "The type of statistic to used to measure a metric to determine
+        threshold crossing for an alarm.";
+    type enumeration {
+      enum AVERAGE;
+      enum MINIMUM;
+      enum MAXIMUM;
+      enum COUNT;
+      enum SUM;
+    }
+  }
+
+  typedef alarm-operation-type {
+    description
+        "The relational operator used to define whether an alarm should be
+        triggered when, say, the metric statistic goes above or below a
+        specified value.";
+    type enumeration {
+      enum GE; // greater than or equal
+      enum LE; // less than or equal
+      enum GT; // greater than
+      enum LT; // less than
+      enum EQ; // equal
+    }
+  }
+
+  grouping alarm {
+    leaf alarm-id {
+      description
+          "This field is reserved for the identifier assigned by the cloud
+          provider";
+
+      type string;
+    }
+
+    leaf name {
+      description "A human readable string to identify the alarm";
+      type string;
+    }
+
+    leaf description {
+      description "A string containing a description of this alarm";
+      type string;
+    }
+
+    leaf vdur-id {
+      description
+          "The identifier of the VDUR that the alarm is associated with";
+      type string;
+    }
+
+    container actions {
+      list ok {
+        key "url";
+        leaf url {
+          type string;
+        }
+      }
+
+      list insufficient-data {
+        key "url";
+        leaf url {
+          type string;
+        }
+      }
+
+      list alarm {
+        key "url";
+        leaf url {
+          type string;
+        }
+      }
+    }
+
+    leaf repeat {
+      description
+          "This flag indicates whether the alarm should be repeatedly emitted
+          while the associated threshold has been crossed.";
+
+      type boolean;
+      default true;
+    }
+
+    leaf enabled {
+      description
+          "This flag indicates whether the alarm has been enabled or
+          disabled.";
+
+      type boolean;
+      default true;
+    }
+
+    leaf severity {
+      description "A measure of the important or urgency of the alarm";
+      type manotypes:alarm-severity-type;
+    }
+
+    leaf metric {
+      description "The metric to be tracked by this alarm.";
+      type manotypes:alarm-metric-type;
+    }
+
+    leaf statistic {
+      description "The type of metric statistic that is tracked by this alarm";
+      type manotypes:alarm-statistic-type;
+    }
+
+    leaf operation {
+      description
+          "The relational operator that defines whether the alarm should be
+          triggered when the metric statistic is, say, above or below the
+          specified threshold value.";
+      type manotypes:alarm-operation-type;
+    }
+
+    leaf value {
+      description
+          "This value defines the threshold that, if crossed, will trigger
+          the alarm.";
+      type decimal64 {
+        fraction-digits 4;
+      }
+    }
+
+    leaf period {
+      description
+          "The period defines the length of time (seconds) that the metric
+          data are collected over in oreder to evaluate the chosen
+          statistic.";
+      type uint32;
+    }
+
+    leaf evaluations {
+      description
+          "This is the number of samples of the metric statistic used to
+          evaluate threshold crossing. Each sample or evaluation is equal to
+          the metric statistic obtained for a given period. This can be used
+          to mitigate spikes in the metric that may skew the statistic of
+          interest.";
+      type uint32;
+    }
+  }
+
+  typedef cloud-account-type {
+    description "cloud account type";
+    type enumeration {
+      enum aws;
+      enum cloudsim;
+      enum cloudsim_proxy;
+      enum mock;
+      enum openmano;
+      enum openstack;
+      enum vsphere;
+    }
+  }
+
+  grouping host-aggregate {
+    list host-aggregate {
+      description "Name of the Host Aggregate";
+      key "metadata-key";
+
+      leaf metadata-key {
+        type string;
+      }
+      leaf metadata-value {
+        type string;
+      }
+    }
+  }
+
+  grouping placement-group-input {
+    leaf cloud-type {
+      type manotypes:cloud-account-type;
+    }
+    choice cloud-provider {
+      case openstack {
+        container availability-zone {
+          description "Name of the Availability Zone";
+          leaf name {
+            type string;
+          }
+        }
+        container server-group {
+          description "Name of the Affinity/Anti-Affinity Server Group";
+          leaf name {
+            type string;
+          }
+        }
+        uses host-aggregate;
+      }
+      case aws {
+        leaf aws-construct {
+          type empty;
+        }
+      }
+      case openmano {
+        leaf openmano-construct {
+          type empty;
+        }
+      }
+      case vsphere {
+        leaf vsphere-construct {
+          type empty;
+        }
+      }
+      case mock {
+        leaf mock-construct {
+          type empty;
+        }
+      }
+      case cloudsim {
+        leaf cloudsim-construct {
+          type empty;
+        }
+      }
+    }
+  }
+
+  grouping placement-group-info {
+    description "";
+
+    leaf name {
+      description
+          "Place group construct to define the compute resource placement strategy
+           in cloud environment";
+      type string;
+    }
+
+    leaf requirement {
+      description "This is free text space used to describe the intent/rationale
+                   behind this placement group. This is for human consumption only";
+      type string;
+    }
+
+    leaf strategy {
+      description
+          "Strategy associated with this placement group
+             Following values are possible
+               - COLOCATION: Colocation strategy imply intent to share the physical
+                             infrastructure (hypervisor/network) among all members
+                             of this group.
+               - ISOLATION: Isolation strategy imply intent to not share the physical
+                            infrastructure (hypervisor/network) among the members
+                            of this group.
+             ";
+      type enumeration {
+        enum COLOCATION;
+        enum ISOLATION;
+      }
+      default "COLOCATION";
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/model-meta.json b/skyquake/plugins/composer/src/schemas/yang/model-meta.json
new file mode 100644 (file)
index 0000000..56f4a50
--- /dev/null
@@ -0,0 +1,4337 @@
+{
+     "nsd": {
+          "name": "nsd",
+          "type": "list",
+          "cardinality": "0..N",
+          "properties": [
+               {
+                    "name": "id",
+                    "type": "leaf",
+                    "description": "Identifier for the NSD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "name",
+                    "type": "leaf",
+                    "description": "NSD name.",
+                    "cardinality": "1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "short-name",
+                    "type": "leaf",
+                    "description": "NSD short name.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "vendor",
+                    "type": "leaf",
+                    "description": "Vendor of the NSD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "logo",
+                    "type": "leaf",
+                    "description": "File path for the vendor specific logo. For example icons/mylogo.png. The logo should be part of the network service",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "description",
+                    "type": "leaf",
+                    "description": "Description of the NSD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "version",
+                    "type": "leaf",
+                    "description": "Version of the NSD",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "meta",
+                    "type": "leaf",
+                    "description": "Any meta-data needed by the UI",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "connection-point",
+                    "type": "list",
+                    "description": "List for external connection points. Each NS has one or more external connection points. As the name implies that external connection points are used for connecting the NS to other NS or to external networks. Each NS exposes these connection points to the orchestrator. The orchestrator can construct network service chains by connecting the connection points between different NS.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the NS connection point.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "VPORT"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "vld",
+                    "type": "list",
+                    "description": "List of Virtual Link Descriptors.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the VLD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Virtual Link Descriptor (VLD) name.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name for VLD for UI",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "vendor",
+                              "type": "leaf",
+                              "description": "Provider of the VLD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "description": "Description of the VLD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "version",
+                              "type": "leaf",
+                              "description": "Version of the VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "ELAN"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "root-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the aggregate bandwidth.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "leaf-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the bandwidth of branches.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "vnfd-connection-point-ref",
+                              "type": "list",
+                              "description": "A list of references to connection points.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to member-vnf within constituent-vnfds",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a vnfd. This is a leafref to path: ../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         },
+                         {
+                              "name": "provider-network",
+                              "type": "container",
+                              "description": "Container for the provider network.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "physical-network",
+                                        "type": "leaf",
+                                        "description": "Name of the phsyical network on which the provider network is built.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "overlay-type",
+                                        "type": "leaf",
+                                        "description": "Type of the overlay network.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LOCAL": {
+                                                            "value": 0
+                                                       },
+                                                       "FLAT": {
+                                                            "value": 1
+                                                       },
+                                                       "VLAN": {
+                                                            "value": 2
+                                                       },
+                                                       "VXLAN": {
+                                                            "value": 3
+                                                       },
+                                                       "GRE": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "segmentation_id",
+                                        "type": "leaf",
+                                        "description": "Segmentation ID",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "constituent-vnfd",
+                    "type": "list",
+                    "description": "List of VNFDs that are part of this network service.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "member-vnf-index",
+                              "type": "leaf",
+                              "description": "Identifier/index for the VNFD. This separate id is required to ensure that multiple VNFs can be part of single NS",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "vnfd-id-ref",
+                              "type": "leaf",
+                              "description": "Identifier for the VNFD.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "start-by-default",
+                              "type": "leaf",
+                              "description": "VNFD is started as part of the NS instantiation",
+                              "cardinality": "0..1",
+                              "data-type": "boolean",
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "member-vnf-index"
+                    ]
+               },
+               {
+                    "name": "scaling-group-descriptor",
+                    "type": "list",
+                    "description": "scaling group descriptor within this network service. The scaling group defines a group of VNFs, and the ratio of VNFs in the network service that is used as target for scaling action",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of this scaling group.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "min-instance-count",
+                              "type": "leaf",
+                              "description": "Minimum instances of the scaling group which are allowed. These instances are created by default when the network service is instantiated.",
+                              "cardinality": "0..1",
+                              "data-type": "uint32",
+                              "properties": []
+                         },
+                         {
+                              "name": "max-instance-count",
+                              "type": "leaf",
+                              "description": "Maximum instances of this scaling group that are allowed in a single network service. The network service scaling will fail, when the number of service group instances exceed the max-instance-count specified.",
+                              "cardinality": "0..1",
+                              "data-type": "uint32",
+                              "properties": []
+                         },
+                         {
+                              "name": "vnfd-member",
+                              "type": "list",
+                              "description": "List of VNFs in this scaling group",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "member VNF index of this member VNF",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../constituent-vnfd/member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "count",
+                                        "type": "leaf",
+                                        "description": "count of this member VNF within this scaling group. The count allows to define the number of instances when a scaling action targets this scaling group",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         },
+                         {
+                              "name": "scaling-config-action",
+                              "type": "list",
+                              "description": "List of scaling config actions",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "trigger",
+                                        "type": "leaf",
+                                        "description": "scaling trigger",
+                                        "cardinality": "0..1",
+                                        "data-type": "scaling-trigger",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "ns-config-primitive-name-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to the NS config name primitive",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../config-primitive/name"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "trigger"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "placement-groups",
+                    "type": "list",
+                    "description": "List of placement groups at NS level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "member-vnfd",
+                              "type": "list",
+                              "description": "List of VNFDs that are part of this placement group",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "member VNF index of this member VNF",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../constituent-vnfd/member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "Identifier for the VNFD.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Place group construct to define the compute resource placement strategy in cloud environment",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "requirement",
+                              "type": "leaf",
+                              "description": "This is free text space used to describe the intent/rationale behind this placement group. This is for human consumption only",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "strategy",
+                              "type": "leaf",
+                              "description": "Strategy associated with this placement group Following values are possible - COLOCATION: Colocation strategy imply intent to share the physical infrastructure (hypervisor/network) among all members of this group. - ISOLATION: Isolation strategy imply intent to not share the physical infrastructure (hypervisor/network) among the members of this group. ",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "COLOCATION": {
+                                                  "value": 0
+                                             },
+                                             "ISOLATION": {
+                                                  "value": 1
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "vnf-dependency",
+                    "type": "list",
+                    "description": "List of VNF dependencies.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "vnf-source-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "vnf-depends-on-ref",
+                              "type": "leaf",
+                              "description": "Reference to VNF that sorce VNF depends.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "vnf-source-ref"
+                    ]
+               },
+               {
+                    "name": "vnffgd",
+                    "type": "list",
+                    "description": "List of VNF Forwarding Graph Descriptors (VNFFGD).",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the VNFFGD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "VNFFGD name.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name for VNFFGD for UI",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "vendor",
+                              "type": "leaf",
+                              "description": "Provider of the VNFFGD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "description": "Description of the VNFFGD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "version",
+                              "type": "leaf",
+                              "description": "Version of the VNFFGD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "rsp",
+                              "type": "list",
+                              "description": "List of Rendered Service Paths (RSP).",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "id",
+                                        "type": "leaf",
+                                        "description": "Identifier for the RSP.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "RSP name.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "list",
+                                        "description": "A list of references to connection points.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "member-vnf-index-ref",
+                                                  "type": "leaf",
+                                                  "description": "Reference to member-vnf within constituent-vnfds",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "leafref": {
+                                                            "path": "../../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "order",
+                                                  "type": "leaf",
+                                                  "description": "A number that denotes the order of a VNF in a chain",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint8",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vnfd-id-ref",
+                                                  "type": "leaf",
+                                                  "description": "A reference to a vnfd. This is a leafref to path: ../../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vnfd-connection-point-ref",
+                                                  "type": "leaf",
+                                                  "description": "A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "member-vnf-index-ref"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "id"
+                              ]
+                         },
+                         {
+                              "name": "classifier",
+                              "type": "list",
+                              "description": "List of classifier rules.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "id",
+                                        "type": "leaf",
+                                        "description": "Identifier for the classifier rule.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the classifier.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "rsp-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to the RSP.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../nsd:rsp/nsd:id"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to member-vnf within constituent-vnfds",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a vnfd. This is a leafref to path: ../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "match-attributes",
+                                        "type": "list",
+                                        "description": "List of match attributes.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "id",
+                                                  "type": "leaf",
+                                                  "description": "Identifier for the classifier match attribute rule.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "ip-proto",
+                                                  "type": "leaf",
+                                                  "description": "IP Protocol.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint8",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "source-ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "destination-ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "source-port",
+                                                  "type": "leaf",
+                                                  "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "uint16": {
+                                                            "range": "0..65535"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "destination-port",
+                                                  "type": "leaf",
+                                                  "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "uint16": {
+                                                            "range": "0..65535"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "id"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "id"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "parameter-pool",
+                    "type": "list",
+                    "description": "Pool of parameter values which must be pulled from during configuration",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the configuration value pool",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "range",
+                              "type": "container",
+                              "description": "Create a range of values to populate the pool with",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "start-value",
+                                        "type": "leaf",
+                                        "description": "Generated pool values start at this value",
+                                        "cardinality": "1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "end-value",
+                                        "type": "leaf",
+                                        "description": "Generated pool values stop at this value",
+                                        "cardinality": "1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "http-endpoint",
+                    "type": "list",
+                    "description": "List of http endpoints to be used by monitoring params",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "path",
+                              "type": "leaf",
+                              "description": "The HTTP path on the management server",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "https",
+                              "type": "leaf",
+                              "description": "Pick HTTPS instead of HTTP , Default is false",
+                              "cardinality": "0..1",
+                              "data-type": "boolean",
+                              "properties": []
+                         },
+                         {
+                              "name": "port",
+                              "type": "leaf",
+                              "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "uint16": {
+                                        "range": "0..65535"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "username",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth username",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "password",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth password",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "polling_interval_secs",
+                              "type": "leaf",
+                              "description": "The HTTP polling interval in seconds",
+                              "cardinality": "0..1",
+                              "data-type": "uint8",
+                              "properties": []
+                         },
+                         {
+                              "name": "method",
+                              "type": "leaf",
+                              "description": "Type of HTTP operation",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "POST": {
+                                                  "value": 0
+                                             },
+                                             "PUT": {
+                                                  "value": 1
+                                             },
+                                             "GET": {
+                                                  "value": 2
+                                             },
+                                             "DELETE": {
+                                                  "value": 3
+                                             },
+                                             "OPTIONS": {
+                                                  "value": 4
+                                             },
+                                             "PATCH": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "headers",
+                              "type": "list",
+                              "description": "Custom HTTP headers to put on HTTP request",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "key",
+                                        "type": "leaf",
+                                        "description": "HTTP header key",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "value",
+                                        "type": "leaf",
+                                        "description": "HTTP header value",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "key"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "path"
+                    ]
+               },
+               {
+                    "name": "monitoring-param",
+                    "type": "list",
+                    "description": "List of monitoring parameters at the NS level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "http-endpoint-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../http-endpoint/path"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-method",
+                              "type": "leaf",
+                              "description": "The method to extract a value from a JSON response NAMEKEY - Use the name as the key for a non-nested value. JSONPATH - Use jsonpath-rw implemenation to extract a value. OBJECTPATH - Use objectpath implemenation to extract a value.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "NAMEKEY": {
+                                                  "value": 0
+                                             },
+                                             "JSONPATH": {
+                                                  "value": 1
+                                             },
+                                             "OBJECTPATH": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "group-tag",
+                              "type": "leaf",
+                              "description": "A simple tag to group monitoring parameters",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-type",
+                              "type": "leaf",
+                              "description": "The type of the parameter value",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "INT": {
+                                                  "value": 0
+                                             },
+                                             "DECIMAL": {
+                                                  "value": 1
+                                             },
+                                             "STRING": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-integer",
+                              "type": "leaf",
+                              "description": "Current value for an integer parameter",
+                              "cardinality": "0..1",
+                              "data-type": "int64",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-decimal",
+                              "type": "leaf",
+                              "description": "Current value for a decimal parameter",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "decimal64": {
+                                        "fraction-digits": "4"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-string",
+                              "type": "leaf",
+                              "description": "Current value for a string parameter",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "widget-type",
+                              "type": "leaf",
+                              "description": "Type of the widget, typically used by the UI.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "HISTOGRAM": {
+                                                  "value": 0
+                                             },
+                                             "BAR": {
+                                                  "value": 1
+                                             },
+                                             "GAUGE": {
+                                                  "value": 2
+                                             },
+                                             "SLIDER": {
+                                                  "value": 3
+                                             },
+                                             "COUNTER": {
+                                                  "value": 4
+                                             },
+                                             "TEXTBOX": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "units",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-params",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "json-path",
+                                        "type": "leaf",
+                                        "description": "The jsonpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "object-path",
+                                        "type": "leaf",
+                                        "description": "The objectpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "numeric-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-value",
+                                        "type": "leaf",
+                                        "description": "Minimum value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-value",
+                                        "type": "leaf",
+                                        "description": "Maxium value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "text-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-length",
+                                        "type": "leaf",
+                                        "description": "Minimum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-length",
+                                        "type": "leaf",
+                                        "description": "Maximum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "input-parameter-xpath",
+                    "type": "list",
+                    "description": "List of xpaths to parameters inside the NSD the can be customized during the instantiation.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "xpath",
+                              "type": "leaf",
+                              "description": "An xpath that specifies the element in a descriptor.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "label",
+                              "type": "leaf",
+                              "description": "A descriptive string",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "default-value",
+                              "type": "leaf",
+                              "description": " A default value for this input parameter",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "xpath"
+                    ]
+               },
+               {
+                    "name": "config-primitive",
+                    "type": "list",
+                    "description": "Network service level configuration primitives.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the configuration primitive.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "user-defined-script",
+                              "type": "leaf",
+                              "description": "A user defined script.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "parameter",
+                              "type": "list",
+                              "description": "List of parameters to the configuration primitive.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the parameter.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "data-type",
+                                        "type": "leaf",
+                                        "description": "Data type associated with the name.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "STRING": {
+                                                            "value": 0
+                                                       },
+                                                       "INTEGER": {
+                                                            "value": 1
+                                                       },
+                                                       "BOOLEAN": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "mandatory",
+                                        "type": "leaf",
+                                        "description": "Is this field mandatory",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "default-value",
+                                        "type": "leaf",
+                                        "description": "The default value for this field",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "parameter-pool",
+                                        "type": "leaf",
+                                        "description": "NSD Parameter pool name to use for this paramter",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "read-only",
+                                        "type": "leaf",
+                                        "description": "The value should be greyed out by the UI. Only applies to parameters with default values.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "hidden",
+                                        "type": "leaf",
+                                        "description": "The value should be hidden by the UI. Only applies to parameters with default values.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "parameter-group",
+                              "type": "list",
+                              "description": "Grouping of parameters which are logically grouped in UI",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the parameter group",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "mandatory",
+                                        "type": "leaf",
+                                        "description": "Is this parameter group mandatory",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "parameter",
+                                        "type": "list",
+                                        "description": "List of parameters to the configuration primitive.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the parameter.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "data-type",
+                                                  "type": "leaf",
+                                                  "description": "Data type associated with the name.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "enumeration": {
+                                                            "enum": {
+                                                                 "STRING": {
+                                                                      "value": 0
+                                                                 },
+                                                                 "INTEGER": {
+                                                                      "value": 1
+                                                                 },
+                                                                 "BOOLEAN": {
+                                                                      "value": 2
+                                                                 }
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "mandatory",
+                                                  "type": "leaf",
+                                                  "description": "Is this field mandatory",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "boolean",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "default-value",
+                                                  "type": "leaf",
+                                                  "description": "The default value for this field",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "parameter-pool",
+                                                  "type": "leaf",
+                                                  "description": "NSD Parameter pool name to use for this paramter",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "read-only",
+                                                  "type": "leaf",
+                                                  "description": "The value should be greyed out by the UI. Only applies to parameters with default values.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "boolean",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "hidden",
+                                                  "type": "leaf",
+                                                  "description": "The value should be hidden by the UI. Only applies to parameters with default values.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "boolean",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "name"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "vnf-primitive-group",
+                              "type": "list",
+                              "description": "List of configuration primitives grouped by VNF.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to member-vnf within constituent-vnfds",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a vnfd. This is a leafref to path: ../../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-name",
+                                        "type": "leaf",
+                                        "description": "Name of the VNFD",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "primitive",
+                                        "type": "list",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "index",
+                                                  "type": "leaf",
+                                                  "description": "Index of this primitive",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint32",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the primitive in the VNF primitive ",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "index"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               }
+          ],
+          "key": [
+               "id"
+          ]
+     },
+     "vnfd": {
+          "name": "vnfd",
+          "type": "list",
+          "cardinality": "0..N",
+          "properties": [
+               {
+                    "name": "id",
+                    "type": "leaf",
+                    "description": "Identifier for the VNFD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "name",
+                    "type": "leaf",
+                    "description": "VNFD name.",
+                    "cardinality": "1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "short-name",
+                    "type": "leaf",
+                    "description": "VNFD short name.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "vendor",
+                    "type": "leaf",
+                    "description": "Vendor of the VNFD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "logo",
+                    "type": "leaf",
+                    "description": "Vendor logo for the Virtual Network Function",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "description",
+                    "type": "leaf",
+                    "description": "Description of the VNFD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "version",
+                    "type": "leaf",
+                    "description": "Version of the VNFD",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "service-function-chain",
+                    "type": "leaf",
+                    "description": "Type of node in Service Function Chaining Architecture",
+                    "cardinality": "0..1",
+                    "data-type": {
+                         "enumeration": {
+                              "enum": {
+                                   "UNAWARE": null,
+                                   "CLASSIFIER": null,
+                                   "SF": null,
+                                   "SFF": null
+                              }
+                         }
+                    },
+                    "properties": []
+               },
+               {
+                    "name": "service-function-type",
+                    "type": "leaf",
+                    "description": "Type of Service Function. NOTE: This needs to map with Service Function Type in ODL to support VNFFG. Service Function Type is manadatory param in ODL SFC. This is temporarily set to string for ease of use",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "meta",
+                    "type": "leaf",
+                    "description": "Any meta-data needed by the UI",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "mgmt-interface",
+                    "type": "container",
+                    "description": "Interface over which the VNF is managed.",
+                    "cardinality": "0..1",
+                    "properties": [
+                         {
+                              "name": "endpoint-type",
+                              "type": "choice",
+                              "description": "Indicates the type of management endpoint.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "ip",
+                                        "type": "case",
+                                        "description": "Specifies the static IP address for managing the VNF.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "vdu-id",
+                                        "type": "case",
+                                        "description": "Use the default management interface on this VDU.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "vdu-id",
+                                                  "type": "leaf",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "leafref": {
+                                                            "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "cp",
+                                        "type": "case",
+                                        "description": "Use the ip address associated with this connection point.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "cp",
+                                                  "type": "leaf",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "leafref": {
+                                                            "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ]
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "port",
+                              "type": "leaf",
+                              "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "uint16": {
+                                        "range": "0..65535"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "dashboard-params",
+                              "type": "container",
+                              "description": "Parameters for the VNF dashboard",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "path",
+                                        "type": "leaf",
+                                        "description": "The HTTP path for the dashboard",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "https",
+                                        "type": "leaf",
+                                        "description": "Pick HTTPS instead of HTTP , Default is false",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "port",
+                                        "type": "leaf",
+                                        "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "uint16": {
+                                                  "range": "0..65535"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "vnf-configuration",
+                              "type": "container",
+                              "description": "Information regarding the VNF configuration is captured here. ",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "config-method",
+                                        "type": "choice",
+                                        "description": "Defines the configuration method for the VNF.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "netconf",
+                                                  "type": "case",
+                                                  "description": "Use NETCONF for configuring the VNF.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "netconf",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "target",
+                                                                      "type": "leaf",
+                                                                      "description": "Netconf configuration target",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "running": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "candidate": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "protocol",
+                                                                      "type": "leaf",
+                                                                      "description": "Protocol to use for netconf (e.g. ssh)",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "None": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "ssh": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "port",
+                                                                      "type": "leaf",
+                                                                      "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "uint16": {
+                                                                                "range": "0..65535"
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "rest",
+                                                  "type": "case",
+                                                  "description": "Use REST for configuring the VNF.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "rest",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "port",
+                                                                      "type": "leaf",
+                                                                      "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "uint16": {
+                                                                                "range": "0..65535"
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "script",
+                                                  "type": "case",
+                                                  "description": "Use custom script for configuring the VNF. This script is executed in the context of Orchestrator.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "script",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "script-type",
+                                                                      "type": "leaf",
+                                                                      "description": "Script type - currently supported : bash, expect",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "bash": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "expect": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "juju",
+                                                  "type": "case",
+                                                  "description": "Configure the VNF through Juju.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "juju",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "charm",
+                                                                      "type": "leaf",
+                                                                      "description": "Juju charm to use with the VNF.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": "string",
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-access",
+                                        "type": "container",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "mgmt-ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "username",
+                                                  "type": "leaf",
+                                                  "description": "username for configuration.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "password",
+                                                  "type": "leaf",
+                                                  "description": "Password for configuration access authentication.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-attributes",
+                                        "type": "container",
+                                        "description": "Miscelaneous input parameters to be considered while processing the NSD to apply configuration",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "config-priority",
+                                                  "type": "leaf",
+                                                  "description": "Configuration priority - order of confgiration to be applied to each VNF in this NS, low number gets precedence over high number",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "config-delay",
+                                                  "type": "leaf",
+                                                  "description": "Wait (seconds) before applying the configuration to VNF",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-primitive",
+                                        "type": "list",
+                                        "description": "List of configuration primitives supported by the configuration agent for this VNF.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the configuration primitive.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "parameter",
+                                                  "type": "list",
+                                                  "description": "List of parameters to the configuration primitive.",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "name",
+                                                            "type": "leaf",
+                                                            "description": "Name of the parameter.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "data-type",
+                                                            "type": "leaf",
+                                                            "description": "Data type associated with the name.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": {
+                                                                 "enumeration": {
+                                                                      "enum": {
+                                                                           "STRING": {
+                                                                                "value": 0
+                                                                           },
+                                                                           "INTEGER": {
+                                                                                "value": 1
+                                                                           },
+                                                                           "BOOLEAN": {
+                                                                                "value": 2
+                                                                           }
+                                                                      }
+                                                                 }
+                                                            },
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "mandatory",
+                                                            "type": "leaf",
+                                                            "description": "Is this field mandatory",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "boolean",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "default-value",
+                                                            "type": "leaf",
+                                                            "description": "The default value for this field",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "parameter-pool",
+                                                            "type": "leaf",
+                                                            "description": "NSD Parameter pool name to use for this paramter",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "read-only",
+                                                            "type": "leaf",
+                                                            "description": "The value should be greyed out by the UI. Only applies to parameters with default values.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "boolean",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "hidden",
+                                                            "type": "leaf",
+                                                            "description": "The value should be hidden by the UI. Only applies to parameters with default values.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "boolean",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "name"
+                                                  ]
+                                             }
+                                        ],
+                                        "key": [
+                                             "name"
+                                        ]
+                                   },
+                                   {
+                                        "name": "initial-config-primitive",
+                                        "type": "list",
+                                        "description": "Initial set of configuration primitives.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "seq",
+                                                  "type": "leaf",
+                                                  "description": "Sequence number for the configuration primitive.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the configuration primitive.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "parameter",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "name",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "value",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "name"
+                                                  ]
+                                             }
+                                        ],
+                                        "key": [
+                                             "seq"
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-template",
+                                        "type": "leaf",
+                                        "description": "Configuration template for each VNF",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ]
+               },
+               {
+                    "name": "internal-vld",
+                    "type": "list",
+                    "description": "List of Internal Virtual Link Descriptors (VLD). The internal VLD describes the basic topology of the connectivity (e.g. E-LAN, E-Line, E-Tree) between internal VNF components of the system.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the internal VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name of the internal VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "ELAN"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "root-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the aggregate bandwidth.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "leaf-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the bandwidth of branches.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "internal-connection-point-ref",
+                              "type": "leaf-list",
+                              "cardinality": "0..N",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../vdu/internal-connection-point/id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "provider-network",
+                              "type": "container",
+                              "description": "Container for the provider network.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "physical-network",
+                                        "type": "leaf",
+                                        "description": "Name of the phsyical network on which the provider network is built.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "overlay-type",
+                                        "type": "leaf",
+                                        "description": "Type of the overlay network.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LOCAL": {
+                                                            "value": 0
+                                                       },
+                                                       "FLAT": {
+                                                            "value": 1
+                                                       },
+                                                       "VLAN": {
+                                                            "value": 2
+                                                       },
+                                                       "VXLAN": {
+                                                            "value": 3
+                                                       },
+                                                       "GRE": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "segmentation_id",
+                                        "type": "leaf",
+                                        "description": "Segmentation ID",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "connection-point",
+                    "type": "list",
+                    "description": "List for external connection points. Each VNF has one or more external connection points. As the name implies that external connection points are used for connecting the VNF to other VNFs or to external networks. Each VNF exposes these connection points to the orchestrator. The orchestrator can construct network services by connecting the connection points between different VNFs. The NFVO will use VLDs and VNFFGs at the network service level to construct network services.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the connection point",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the internal connection points",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name of the connection point",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "VPORT"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "vdu",
+                    "type": "list",
+                    "description": "List of Virtual Deployment Units",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Unique id for the VDU",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Unique name for the VDU",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "description": "Description of the VDU.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "count",
+                              "type": "leaf",
+                              "description": "Number of instances of VDU",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "mgmt-vpci",
+                              "type": "leaf",
+                              "description": "Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "image",
+                              "type": "leaf",
+                              "description": "Image name for the software image. If the image name is found within the VNF packaage it will be uploaded to all cloud accounts during onboarding process. Otherwise, the image must be added to the cloud account with the same name as entered here. ",
+                              "cardinality": "1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "image-checksum",
+                              "type": "leaf",
+                              "description": "Image md5sum for the software image. The md5sum, if provided, along with the image name uniquely identifies an image uploaded to the CAL. ",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "cloud-init",
+                              "type": "leaf",
+                              "description": "Content of cloud-init script",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "alarm",
+                              "type": "list",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "alarm-id",
+                                        "type": "leaf",
+                                        "description": "This field is reserved for the identifier assigned by the cloud provider",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "A human readable string to identify the alarm",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "description",
+                                        "type": "leaf",
+                                        "description": "A string containing a description of this alarm",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vdur-id",
+                                        "type": "leaf",
+                                        "description": "The identifier of the VDUR that the alarm is associated with",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "repeat",
+                                        "type": "leaf",
+                                        "description": "This flag indicates whether the alarm should be repeatedly emitted while the associated threshold has been crossed.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "enabled",
+                                        "type": "leaf",
+                                        "description": "This flag indicates whether the alarm has been enabled or disabled.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "severity",
+                                        "type": "leaf",
+                                        "description": "An indication of the importance or ugency of the alarm",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LOW": {
+                                                            "value": 0
+                                                       },
+                                                       "MODERATE": {
+                                                            "value": 1
+                                                       },
+                                                       "CRITICAL": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "metric",
+                                        "type": "leaf",
+                                        "description": "The type of metrics to register the alarm for",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "CPU_UTILIZATION": {
+                                                            "value": 0
+                                                       },
+                                                       "MEMORY_UTILIZATION": {
+                                                            "value": 1
+                                                       },
+                                                       "STORAGE_UTILIZATION": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "statistic",
+                                        "type": "leaf",
+                                        "description": "The type of statistic to used to measure a metric to determine threshold crossing for an alarm.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "AVERAGE": {
+                                                            "value": 0
+                                                       },
+                                                       "MINIMUM": {
+                                                            "value": 1
+                                                       },
+                                                       "MAXIMUM": {
+                                                            "value": 2
+                                                       },
+                                                       "COUNT": {
+                                                            "value": 3
+                                                       },
+                                                       "SUM": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "operation",
+                                        "type": "leaf",
+                                        "description": "The relational operator used to define whether an alarm should be triggered when, say, the metric statistic goes above or below a specified value.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "GE": {
+                                                            "value": 0
+                                                       },
+                                                       "LE": {
+                                                            "value": 1
+                                                       },
+                                                       "GT": {
+                                                            "value": 2
+                                                       },
+                                                       "LT": {
+                                                            "value": 3
+                                                       },
+                                                       "EQ": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "value",
+                                        "type": "leaf",
+                                        "description": "This value defines the threshold that, if crossed, will trigger the alarm.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "decimal64": {
+                                                  "fraction-digits": "4"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "period",
+                                        "type": "leaf",
+                                        "description": "The period defines the length of time (seconds) that the metric data are collected over in oreder to evaluate the chosen statistic.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "evaluations",
+                                        "type": "leaf",
+                                        "description": "This is the number of samples of the metric statistic used to evaluate threshold crossing. Each sample or evaluation is equal to the metric statistic obtained for a given period. This can be used to mitigate spikes in the metric that may skew the statistic of interest.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "actions",
+                                        "type": "container",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "ok",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "url",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "url"
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "insufficient-data",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "url",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "url"
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "alarm",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "url",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "url"
+                                                  ]
+                                             }
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "alarm-id"
+                              ]
+                         },
+                         {
+                              "name": "internal-connection-point",
+                              "type": "list",
+                              "description": "List for internal connection points. Each VNFC has zero or more internal connection points. Internal connection points are used for connecting the VNF components internal to the VNF. If a VNF has only one VNFC, it may not have any internal connection points.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "internal-vld-ref",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../internal-vld/id"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the connection point",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "id",
+                                        "type": "leaf",
+                                        "description": "Identifier for the internal connection points",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "short-name",
+                                        "type": "leaf",
+                                        "description": "Short name of the connection point",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "type",
+                                        "type": "leaf",
+                                        "description": "Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": "VPORT"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "id"
+                              ]
+                         },
+                         {
+                              "name": "internal-interface",
+                              "type": "list",
+                              "description": "List of internal interfaces for the VNF",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of internal interface. Note that this name has only local significance to the VDU.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vdu-internal-connection-point-ref",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../internal-connection-point/id"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "virtual-interface",
+                                        "type": "container",
+                                        "description": "Container for the virtual interface properties",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "type",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the type of virtual interface between VM and host. VIRTIO : Use the traditional VIRTIO interface. PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface. SR-IOV : Use SR-IOV interface. OM-MGMT : Used to specify openmano mgmt external-connection type",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "enumeration": {
+                                                            "enum": {
+                                                                 "OM-MGMT": null,
+                                                                 "PCI-PASSTHROUGH": null,
+                                                                 "SR-IOV": null,
+                                                                 "VIRTIO": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vpci",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "bandwidth",
+                                                  "type": "leaf",
+                                                  "description": "Aggregate bandwidth of the NIC.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "external-interface",
+                              "type": "list",
+                              "description": "List of external interfaces for the VNF. The external interfaces enable sending traffic to and from VNF.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the external interface. Note that this name has only local significance.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "leaf",
+                                        "description": "Name of the external connection point.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../connection-point/name"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "virtual-interface",
+                                        "type": "container",
+                                        "description": "Container for the virtual interface properties",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "type",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the type of virtual interface between VM and host. VIRTIO : Use the traditional VIRTIO interface. PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface. SR-IOV : Use SR-IOV interface. OM-MGMT : Used to specify openmano mgmt external-connection type",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "enumeration": {
+                                                            "enum": {
+                                                                 "OM-MGMT": null,
+                                                                 "PCI-PASSTHROUGH": null,
+                                                                 "SR-IOV": null,
+                                                                 "VIRTIO": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vpci",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "bandwidth",
+                                                  "type": "leaf",
+                                                  "description": "Aggregate bandwidth of the NIC.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "vm-flavor",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "vcpu-count",
+                                        "type": "leaf",
+                                        "description": "Number of vcpus for the VM.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint16",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "memory-mb",
+                                        "type": "leaf",
+                                        "description": "Amount of memory in MB.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "storage-gb",
+                                        "type": "leaf",
+                                        "description": "Amount of disk space in GB.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "guest-epa",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "trusted-execution",
+                                        "type": "leaf",
+                                        "description": "This VM should be allocated from trusted pool",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "mempage-size",
+                                        "type": "leaf",
+                                        "description": "Memory page allocation size. If a VM requires hugepages, it should choose LARGE or SIZE_2MB or SIZE_1GB. If the VM prefers hugepages it should chose PREFER_LARGE. LARGE : Require hugepages (either 2MB or 1GB) SMALL : Doesn't require hugepages SIZE_2MB : Requires 2MB hugepages SIZE_1GB : Requires 1GB hugepages PREFER_LARGE : Application perfers hugepages",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LARGE": {
+                                                            "value": 0
+                                                       },
+                                                       "SMALL": {
+                                                            "value": 1
+                                                       },
+                                                       "SIZE_2MB": {
+                                                            "value": 2
+                                                       },
+                                                       "SIZE_1GB": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_LARGE": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-pinning-policy",
+                                        "type": "leaf",
+                                        "description": "CPU pinning policy describes association between virtual CPUs in guest and the physical CPUs in the host. DEDICATED : Virtual CPUs are pinned to physical CPUs SHARED : Multiple VMs may share the same physical CPUs. ANY : Any policy is acceptable for the VM",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "DEDICATED": {
+                                                            "value": 0
+                                                       },
+                                                       "SHARED": {
+                                                            "value": 1
+                                                       },
+                                                       "ANY": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-thread-pinning-policy",
+                                        "type": "leaf",
+                                        "description": "CPU thread pinning policy describes how to place the guest CPUs when the host supports hyper threads: AVOID : Avoids placing a guest on a host with threads. SEPARATE: Places vCPUs on separate cores, and avoids placing two vCPUs on two threads of same core. ISOLATE : Places each vCPU on a different core, and places no vCPUs from a different guest on the same core. PREFER : Attempts to place vCPUs on threads of the same core.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "AVOID": {
+                                                            "value": 0
+                                                       },
+                                                       "SEPARATE": {
+                                                            "value": 1
+                                                       },
+                                                       "ISOLATE": {
+                                                            "value": 2
+                                                       },
+                                                       "PREFER": {
+                                                            "value": 3
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "pcie-device",
+                                        "type": "list",
+                                        "description": "List of pcie passthrough devices.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "device-id",
+                                                  "type": "leaf",
+                                                  "description": "Device identifier.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "count",
+                                                  "type": "leaf",
+                                                  "description": "Number of devices to attach to the VM.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "device-id"
+                                        ]
+                                   },
+                                   {
+                                        "name": "numa-policy",
+                                        "type": "choice",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "numa-unware",
+                                                  "type": "case",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "numa-unware",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "empty",
+                                                            "properties": []
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "numa-aware",
+                                                  "type": "case",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "numa-node-policy",
+                                                            "type": "container",
+                                                            "description": "This policy defines numa topology of the guest. Specifically identifies if the guest should be run on a host with one numa node or multiple numa nodes. As an example a guest may want 8 vcpus and 4 GB of memory. But may want the vcpus and memory distributed across multiple numa nodes. The NUMA node 1 may run with 6 vcpus and 3GB, and NUMA node 2 may run with 2 vcpus and 1GB.",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "node-cnt",
+                                                                      "type": "leaf",
+                                                                      "description": "The number of numa nodes to expose to the VM.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": "uint16",
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "mem-policy",
+                                                                      "type": "leaf",
+                                                                      "description": "This policy specifies how the memory should be allocated in a multi-node scenario. STRICT : The memory must be allocated strictly from the memory attached to the NUMA node. PREFERRED : The memory should be allocated perferentially from the memory attached to the NUMA node",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "STRICT": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "PREFERRED": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "node",
+                                                                      "type": "list",
+                                                                      "cardinality": "0..N",
+                                                                      "properties": [
+                                                                           {
+                                                                                "name": "id",
+                                                                                "type": "leaf",
+                                                                                "description": "NUMA node identification. Typically it's 0 or 1",
+                                                                                "cardinality": "0..1",
+                                                                                "data-type": "uint64",
+                                                                                "properties": []
+                                                                           },
+                                                                           {
+                                                                                "name": "memory-mb",
+                                                                                "type": "leaf",
+                                                                                "description": "Memory size expressed in MB for this NUMA node.",
+                                                                                "cardinality": "0..1",
+                                                                                "data-type": "uint64",
+                                                                                "properties": []
+                                                                           },
+                                                                           {
+                                                                                "name": "vcpu",
+                                                                                "type": "leaf-list",
+                                                                                "description": "List of vcpus to allocate on this numa node.",
+                                                                                "cardinality": "0..N",
+                                                                                "data-type": "uint64",
+                                                                                "properties": []
+                                                                           },
+                                                                           {
+                                                                                "name": "om-numa-type",
+                                                                                "type": "choice",
+                                                                                "description": "Openmano Numa type selection",
+                                                                                "cardinality": "0..1",
+                                                                                "properties": [
+                                                                                     {
+                                                                                          "name": "cores",
+                                                                                          "type": "case",
+                                                                                          "cardinality": "0..1",
+                                                                                          "properties": [
+                                                                                               {
+                                                                                                    "name": "num-cores",
+                                                                                                    "type": "leaf",
+                                                                                                    "cardinality": "0..1",
+                                                                                                    "data-type": "uint8",
+                                                                                                    "properties": []
+                                                                                               }
+                                                                                          ]
+                                                                                     },
+                                                                                     {
+                                                                                          "name": "paired-threads",
+                                                                                          "type": "case",
+                                                                                          "cardinality": "0..1",
+                                                                                          "properties": [
+                                                                                               {
+                                                                                                    "name": "paired-threads",
+                                                                                                    "type": "container",
+                                                                                                    "cardinality": "0..1",
+                                                                                                    "properties": [
+                                                                                                         {
+                                                                                                              "name": "num-paired-threads",
+                                                                                                              "type": "leaf",
+                                                                                                              "cardinality": "0..1",
+                                                                                                              "data-type": "uint8",
+                                                                                                              "properties": []
+                                                                                                         },
+                                                                                                         {
+                                                                                                              "name": "paired-thread-ids",
+                                                                                                              "type": "list",
+                                                                                                              "description": "List of thread pairs to use in case of paired-thread numa",
+                                                                                                              "cardinality": "0..16",
+                                                                                                              "properties": [
+                                                                                                                   {
+                                                                                                                        "name": "thread-a",
+                                                                                                                        "type": "leaf",
+                                                                                                                        "cardinality": "0..1",
+                                                                                                                        "data-type": "uint8",
+                                                                                                                        "properties": []
+                                                                                                                   },
+                                                                                                                   {
+                                                                                                                        "name": "thread-b",
+                                                                                                                        "type": "leaf",
+                                                                                                                        "cardinality": "0..1",
+                                                                                                                        "data-type": "uint8",
+                                                                                                                        "properties": []
+                                                                                                                   }
+                                                                                                              ],
+                                                                                                              "key": [
+                                                                                                                   "thread-a"
+                                                                                                              ]
+                                                                                                         }
+                                                                                                    ]
+                                                                                               }
+                                                                                          ]
+                                                                                     },
+                                                                                     {
+                                                                                          "name": "threads",
+                                                                                          "type": "case",
+                                                                                          "cardinality": "0..1",
+                                                                                          "properties": [
+                                                                                               {
+                                                                                                    "name": "num-threads",
+                                                                                                    "type": "leaf",
+                                                                                                    "cardinality": "0..1",
+                                                                                                    "data-type": "uint8",
+                                                                                                    "properties": []
+                                                                                               }
+                                                                                          ]
+                                                                                     }
+                                                                                ]
+                                                                           }
+                                                                      ],
+                                                                      "key": [
+                                                                           "id"
+                                                                      ]
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             }
+                                        ]
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "vswitch-epa",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "ovs-acceleration",
+                                        "type": "leaf",
+                                        "description": "Specifies Open vSwitch acceleration mode. MANDATORY: OVS acceleration is required PREFERRED: OVS acceleration is preferred",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "MANDATORY": {
+                                                            "value": 0
+                                                       },
+                                                       "PREFERRED": {
+                                                            "value": 1
+                                                       },
+                                                       "DISABLED": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "ovs-offload",
+                                        "type": "leaf",
+                                        "description": "Specifies Open vSwitch hardware offload mode. MANDATORY: OVS offload is required PREFERRED: OVS offload is preferred",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "MANDATORY": {
+                                                            "value": 0
+                                                       },
+                                                       "PREFERRED": {
+                                                            "value": 1
+                                                       },
+                                                       "DISABLED": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "hypervisor-epa",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "type",
+                                        "type": "leaf",
+                                        "description": "Specifies the type of hypervisor. KVM: KVM XEN: XEN",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_KVM": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_KVM": {
+                                                            "value": 1
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "version",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "host-epa",
+                              "type": "container",
+                              "description": "Specifies the host level EPA attributes.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "cpu-model",
+                                        "type": "leaf",
+                                        "description": "Host CPU model. Examples include: SandyBridge, IvyBridge",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_WESTMERE": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_WESTMERE": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_SANDYBRIDGE": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_SANDYBRIDGE": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_IVYBRIDGE": {
+                                                            "value": 4
+                                                       },
+                                                       "REQUIRE_IVYBRIDGE": {
+                                                            "value": 5
+                                                       },
+                                                       "PREFER_HASWELL": {
+                                                            "value": 6
+                                                       },
+                                                       "REQUIRE_HASWELL": {
+                                                            "value": 7
+                                                       },
+                                                       "PREFER_BROADWELL": {
+                                                            "value": 8
+                                                       },
+                                                       "REQUIRE_BROADWELL": {
+                                                            "value": 9
+                                                       },
+                                                       "PREFER_NEHALEM": {
+                                                            "value": 10
+                                                       },
+                                                       "REQUIRE_NEHALEM": {
+                                                            "value": 11
+                                                       },
+                                                       "PREFER_PENRYN": {
+                                                            "value": 12
+                                                       },
+                                                       "REQUIRE_PENRYN": {
+                                                            "value": 13
+                                                       },
+                                                       "PREFER_CONROE": {
+                                                            "value": 14
+                                                       },
+                                                       "REQUIRE_CONROE": {
+                                                            "value": 15
+                                                       },
+                                                       "PREFER_CORE2DUO": {
+                                                            "value": 16
+                                                       },
+                                                       "REQUIRE_CORE2DUO": {
+                                                            "value": 17
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-arch",
+                                        "type": "leaf",
+                                        "description": "Host CPU architecture.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_X86": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_X86": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_X86_64": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_X86_64": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_I686": {
+                                                            "value": 4
+                                                       },
+                                                       "REQUIRE_I686": {
+                                                            "value": 5
+                                                       },
+                                                       "PREFER_IA64": {
+                                                            "value": 6
+                                                       },
+                                                       "REQUIRE_IA64": {
+                                                            "value": 7
+                                                       },
+                                                       "PREFER_ARMV7": {
+                                                            "value": 8
+                                                       },
+                                                       "REQUIRE_ARMV7": {
+                                                            "value": 9
+                                                       },
+                                                       "PREFER_ARMV8": {
+                                                            "value": 10
+                                                       },
+                                                       "REQUIRE_ARMV8": {
+                                                            "value": 11
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-vendor",
+                                        "type": "leaf",
+                                        "description": "Host CPU Vendor.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_INTEL": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_INTEL": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_AMD": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_AMD": {
+                                                            "value": 3
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-socket-count",
+                                        "type": "leaf",
+                                        "description": "Number of sockets on the host.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-core-count",
+                                        "type": "leaf",
+                                        "description": "Number of cores on the host.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-core-thread-count",
+                                        "type": "leaf",
+                                        "description": "Number of threads per cores on the host.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "om-cpu-model-string",
+                                        "type": "leaf",
+                                        "description": "Openmano CPU model string",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-feature",
+                                        "type": "leaf-list",
+                                        "description": "Enumeration for CPU features. AES: CPU supports advanced instruction set for AES (Advanced Encryption Standard). CAT: Cache Allocation Technology (CAT) allows an Operating System, Hypervisor, or similar system management agent to specify the amount of L3 cache (currently the last-level cache in most server and client platforms) space an application can fill (as a hint to hardware functionality, certain features such as power management may override CAT settings). CMT: Cache Monitoring Technology (CMT) allows an Operating System, Hypervisor, or similar system management agent to determine the usage of cache based on applications running on the platform. The implementation is directed at L3 cache monitoring (currently the last-level cache in most server and client platforms). DDIO: Intel Data Direct I/O (DDIO) enables Ethernet server NICs and controllers talk directly to the processor cache without a detour via system memory. This enumeration specifies if the VM requires a DDIO capable host.",
+                                        "cardinality": "0..N",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_AES": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_AES": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_CAT": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_CAT": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_CMT": {
+                                                            "value": 4
+                                                       },
+                                                       "REQUIRE_CMT": {
+                                                            "value": 5
+                                                       },
+                                                       "PREFER_DDIO": {
+                                                            "value": 6
+                                                       },
+                                                       "REQUIRE_DDIO": {
+                                                            "value": 7
+                                                       },
+                                                       "REQUIRE_VME": {
+                                                            "value": 8
+                                                       },
+                                                       "PREFER_VME": {
+                                                            "value": 9
+                                                       },
+                                                       "REQUIRE_DE": {
+                                                            "value": 10
+                                                       },
+                                                       "PREFER_DE": {
+                                                            "value": 11
+                                                       },
+                                                       "REQUIRE_PSE": {
+                                                            "value": 12
+                                                       },
+                                                       "PREFER_PSE": {
+                                                            "value": 13
+                                                       },
+                                                       "REQUIRE_TSC": {
+                                                            "value": 14
+                                                       },
+                                                       "PREFER_TSC": {
+                                                            "value": 15
+                                                       },
+                                                       "REQUIRE_MSR": {
+                                                            "value": 16
+                                                       },
+                                                       "PREFER_MSR": {
+                                                            "value": 17
+                                                       },
+                                                       "REQUIRE_PAE": {
+                                                            "value": 18
+                                                       },
+                                                       "PREFER_PAE": {
+                                                            "value": 19
+                                                       },
+                                                       "REQUIRE_MCE": {
+                                                            "value": 20
+                                                       },
+                                                       "PREFER_MCE": {
+                                                            "value": 21
+                                                       },
+                                                       "REQUIRE_CX8": {
+                                                            "value": 22
+                                                       },
+                                                       "PREFER_CX8": {
+                                                            "value": 23
+                                                       },
+                                                       "REQUIRE_APIC": {
+                                                            "value": 24
+                                                       },
+                                                       "PREFER_APIC": {
+                                                            "value": 25
+                                                       },
+                                                       "REQUIRE_SEP": {
+                                                            "value": 26
+                                                       },
+                                                       "PREFER_SEP": {
+                                                            "value": 27
+                                                       },
+                                                       "REQUIRE_MTRR": {
+                                                            "value": 28
+                                                       },
+                                                       "PREFER_MTRR": {
+                                                            "value": 29
+                                                       },
+                                                       "REQUIRE_PGE": {
+                                                            "value": 30
+                                                       },
+                                                       "PREFER_PGE": {
+                                                            "value": 31
+                                                       },
+                                                       "REQUIRE_MCA": {
+                                                            "value": 32
+                                                       },
+                                                       "PREFER_MCA": {
+                                                            "value": 33
+                                                       },
+                                                       "REQUIRE_CMOV": {
+                                                            "value": 34
+                                                       },
+                                                       "PREFER_CMOV": {
+                                                            "value": 35
+                                                       },
+                                                       "REQUIRE_PAT": {
+                                                            "value": 36
+                                                       },
+                                                       "PREFER_PAT": {
+                                                            "value": 37
+                                                       },
+                                                       "REQUIRE_PSE36": {
+                                                            "value": 38
+                                                       },
+                                                       "PREFER_PSE36": {
+                                                            "value": 39
+                                                       },
+                                                       "REQUIRE_CLFLUSH": {
+                                                            "value": 40
+                                                       },
+                                                       "PREFER_CLFLUSH": {
+                                                            "value": 41
+                                                       },
+                                                       "REQUIRE_DTS": {
+                                                            "value": 42
+                                                       },
+                                                       "PREFER_DTS": {
+                                                            "value": 43
+                                                       },
+                                                       "REQUIRE_ACPI": {
+                                                            "value": 44
+                                                       },
+                                                       "PREFER_ACPI": {
+                                                            "value": 45
+                                                       },
+                                                       "REQUIRE_MMX": {
+                                                            "value": 46
+                                                       },
+                                                       "PREFER_MMX": {
+                                                            "value": 47
+                                                       },
+                                                       "REQUIRE_FXSR": {
+                                                            "value": 48
+                                                       },
+                                                       "PREFER_FXSR": {
+                                                            "value": 49
+                                                       },
+                                                       "REQUIRE_SSE": {
+                                                            "value": 50
+                                                       },
+                                                       "PREFER_SSE": {
+                                                            "value": 51
+                                                       },
+                                                       "REQUIRE_SSE2": {
+                                                            "value": 52
+                                                       },
+                                                       "PREFER_SSE2": {
+                                                            "value": 53
+                                                       },
+                                                       "REQUIRE_SS": {
+                                                            "value": 54
+                                                       },
+                                                       "PREFER_SS": {
+                                                            "value": 55
+                                                       },
+                                                       "REQUIRE_HT": {
+                                                            "value": 56
+                                                       },
+                                                       "PREFER_HT": {
+                                                            "value": 57
+                                                       },
+                                                       "REQUIRE_TM": {
+                                                            "value": 58
+                                                       },
+                                                       "PREFER_TM": {
+                                                            "value": 59
+                                                       },
+                                                       "REQUIRE_IA64": {
+                                                            "value": 60
+                                                       },
+                                                       "PREFER_IA64": {
+                                                            "value": 61
+                                                       },
+                                                       "REQUIRE_PBE": {
+                                                            "value": 62
+                                                       },
+                                                       "PREFER_PBE": {
+                                                            "value": 63
+                                                       },
+                                                       "REQUIRE_RDTSCP": {
+                                                            "value": 64
+                                                       },
+                                                       "PREFER_RDTSCP": {
+                                                            "value": 65
+                                                       },
+                                                       "REQUIRE_PNI": {
+                                                            "value": 66
+                                                       },
+                                                       "PREFER_PNI": {
+                                                            "value": 67
+                                                       },
+                                                       "REQUIRE_PCLMULQDQ": {
+                                                            "value": 68
+                                                       },
+                                                       "PREFER_PCLMULQDQ": {
+                                                            "value": 69
+                                                       },
+                                                       "REQUIRE_DTES64": {
+                                                            "value": 70
+                                                       },
+                                                       "PREFER_DTES64": {
+                                                            "value": 71
+                                                       },
+                                                       "REQUIRE_MONITOR": {
+                                                            "value": 72
+                                                       },
+                                                       "PREFER_MONITOR": {
+                                                            "value": 73
+                                                       },
+                                                       "REQUIRE_DS_CPL": {
+                                                            "value": 74
+                                                       },
+                                                       "PREFER_DS_CPL": {
+                                                            "value": 75
+                                                       },
+                                                       "REQUIRE_VMX": {
+                                                            "value": 76
+                                                       },
+                                                       "PREFER_VMX": {
+                                                            "value": 77
+                                                       },
+                                                       "REQUIRE_SMX": {
+                                                            "value": 78
+                                                       },
+                                                       "PREFER_SMX": {
+                                                            "value": 79
+                                                       },
+                                                       "REQUIRE_EST": {
+                                                            "value": 80
+                                                       },
+                                                       "PREFER_EST": {
+                                                            "value": 81
+                                                       },
+                                                       "REQUIRE_TM2": {
+                                                            "value": 82
+                                                       },
+                                                       "PREFER_TM2": {
+                                                            "value": 83
+                                                       },
+                                                       "REQUIRE_SSSE3": {
+                                                            "value": 84
+                                                       },
+                                                       "PREFER_SSSE3": {
+                                                            "value": 85
+                                                       },
+                                                       "REQUIRE_CID": {
+                                                            "value": 86
+                                                       },
+                                                       "PREFER_CID": {
+                                                            "value": 87
+                                                       },
+                                                       "REQUIRE_FMA": {
+                                                            "value": 88
+                                                       },
+                                                       "PREFER_FMA": {
+                                                            "value": 89
+                                                       },
+                                                       "REQUIRE_CX16": {
+                                                            "value": 90
+                                                       },
+                                                       "PREFER_CX16": {
+                                                            "value": 91
+                                                       },
+                                                       "REQUIRE_XTPR": {
+                                                            "value": 92
+                                                       },
+                                                       "PREFER_XTPR": {
+                                                            "value": 93
+                                                       },
+                                                       "REQUIRE_PDCM": {
+                                                            "value": 94
+                                                       },
+                                                       "PREFER_PDCM": {
+                                                            "value": 95
+                                                       },
+                                                       "REQUIRE_PCID": {
+                                                            "value": 96
+                                                       },
+                                                       "PREFER_PCID": {
+                                                            "value": 97
+                                                       },
+                                                       "REQUIRE_DCA": {
+                                                            "value": 98
+                                                       },
+                                                       "PREFER_DCA": {
+                                                            "value": 99
+                                                       },
+                                                       "REQUIRE_SSE4_1": {
+                                                            "value": 100
+                                                       },
+                                                       "PREFER_SSE4_1": {
+                                                            "value": 101
+                                                       },
+                                                       "REQUIRE_SSE4_2": {
+                                                            "value": 102
+                                                       },
+                                                       "PREFER_SSE4_2": {
+                                                            "value": 103
+                                                       },
+                                                       "REQUIRE_X2APIC": {
+                                                            "value": 104
+                                                       },
+                                                       "PREFER_X2APIC": {
+                                                            "value": 105
+                                                       },
+                                                       "REQUIRE_MOVBE": {
+                                                            "value": 106
+                                                       },
+                                                       "PREFER_MOVBE": {
+                                                            "value": 107
+                                                       },
+                                                       "REQUIRE_POPCNT": {
+                                                            "value": 108
+                                                       },
+                                                       "PREFER_POPCNT": {
+                                                            "value": 109
+                                                       },
+                                                       "REQUIRE_TSC_DEADLINE_TIMER": {
+                                                            "value": 110
+                                                       },
+                                                       "PREFER_TSC_DEADLINE_TIMER": {
+                                                            "value": 111
+                                                       },
+                                                       "REQUIRE_XSAVE": {
+                                                            "value": 112
+                                                       },
+                                                       "PREFER_XSAVE": {
+                                                            "value": 113
+                                                       },
+                                                       "REQUIRE_AVX": {
+                                                            "value": 114
+                                                       },
+                                                       "PREFER_AVX": {
+                                                            "value": 115
+                                                       },
+                                                       "REQUIRE_F16C": {
+                                                            "value": 116
+                                                       },
+                                                       "PREFER_F16C": {
+                                                            "value": 117
+                                                       },
+                                                       "REQUIRE_RDRAND": {
+                                                            "value": 118
+                                                       },
+                                                       "PREFER_RDRAND": {
+                                                            "value": 119
+                                                       },
+                                                       "REQUIRE_FSGSBASE": {
+                                                            "value": 120
+                                                       },
+                                                       "PREFER_FSGSBASE": {
+                                                            "value": 121
+                                                       },
+                                                       "REQUIRE_BMI1": {
+                                                            "value": 122
+                                                       },
+                                                       "PREFER_BMI1": {
+                                                            "value": 123
+                                                       },
+                                                       "REQUIRE_HLE": {
+                                                            "value": 124
+                                                       },
+                                                       "PREFER_HLE": {
+                                                            "value": 125
+                                                       },
+                                                       "REQUIRE_AVX2": {
+                                                            "value": 126
+                                                       },
+                                                       "PREFER_AVX2": {
+                                                            "value": 127
+                                                       },
+                                                       "REQUIRE_SMEP": {
+                                                            "value": 128
+                                                       },
+                                                       "PREFER_SMEP": {
+                                                            "value": 129
+                                                       },
+                                                       "REQUIRE_BMI2": {
+                                                            "value": 130
+                                                       },
+                                                       "PREFER_BMI2": {
+                                                            "value": 131
+                                                       },
+                                                       "REQUIRE_ERMS": {
+                                                            "value": 132
+                                                       },
+                                                       "PREFER_ERMS": {
+                                                            "value": 133
+                                                       },
+                                                       "REQUIRE_INVPCID": {
+                                                            "value": 134
+                                                       },
+                                                       "PREFER_INVPCID": {
+                                                            "value": 135
+                                                       },
+                                                       "REQUIRE_RTM": {
+                                                            "value": 136
+                                                       },
+                                                       "PREFER_RTM": {
+                                                            "value": 137
+                                                       },
+                                                       "REQUIRE_MPX": {
+                                                            "value": 138
+                                                       },
+                                                       "PREFER_MPX": {
+                                                            "value": 139
+                                                       },
+                                                       "REQUIRE_RDSEED": {
+                                                            "value": 140
+                                                       },
+                                                       "PREFER_RDSEED": {
+                                                            "value": 141
+                                                       },
+                                                       "REQUIRE_ADX": {
+                                                            "value": 142
+                                                       },
+                                                       "PREFER_ADX": {
+                                                            "value": 143
+                                                       },
+                                                       "REQUIRE_SMAP": {
+                                                            "value": 144
+                                                       },
+                                                       "PREFER_SMAP": {
+                                                            "value": 145
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "om-cpu-feature",
+                                        "type": "leaf-list",
+                                        "description": "Openmano CPU features",
+                                        "cardinality": "0..N",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "vdu-dependency",
+                    "type": "list",
+                    "description": "List of VDU dependencies.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "vdu-source-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../vdu/id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "vdu-depends-on-ref",
+                              "type": "leaf",
+                              "description": "Reference to the VDU that source VDU depends.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../vdu/id"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "vdu-source-ref"
+                    ]
+               },
+               {
+                    "name": "placement-groups",
+                    "type": "list",
+                    "description": "List of placement groups at VNF level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "member-vdus",
+                              "type": "list",
+                              "description": "List of VDUs that are part of this placement group",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vdu-ref",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../vdu/id"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vdu-ref"
+                              ]
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Place group construct to define the compute resource placement strategy in cloud environment",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "requirement",
+                              "type": "leaf",
+                              "description": "This is free text space used to describe the intent/rationale behind this placement group. This is for human consumption only",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "strategy",
+                              "type": "leaf",
+                              "description": "Strategy associated with this placement group Following values are possible - COLOCATION: Colocation strategy imply intent to share the physical infrastructure (hypervisor/network) among all members of this group. - ISOLATION: Isolation strategy imply intent to not share the physical infrastructure (hypervisor/network) among the members of this group. ",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "COLOCATION": {
+                                                  "value": 0
+                                             },
+                                             "ISOLATION": {
+                                                  "value": 1
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "http-endpoint",
+                    "type": "list",
+                    "description": "List of http endpoints to be used by monitoring params",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "path",
+                              "type": "leaf",
+                              "description": "The HTTP path on the management server",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "https",
+                              "type": "leaf",
+                              "description": "Pick HTTPS instead of HTTP , Default is false",
+                              "cardinality": "0..1",
+                              "data-type": "boolean",
+                              "properties": []
+                         },
+                         {
+                              "name": "port",
+                              "type": "leaf",
+                              "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "uint16": {
+                                        "range": "0..65535"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "username",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth username",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "password",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth password",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "polling_interval_secs",
+                              "type": "leaf",
+                              "description": "The HTTP polling interval in seconds",
+                              "cardinality": "0..1",
+                              "data-type": "uint8",
+                              "properties": []
+                         },
+                         {
+                              "name": "method",
+                              "type": "leaf",
+                              "description": "Type of HTTP operation",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "POST": {
+                                                  "value": 0
+                                             },
+                                             "PUT": {
+                                                  "value": 1
+                                             },
+                                             "GET": {
+                                                  "value": 2
+                                             },
+                                             "DELETE": {
+                                                  "value": 3
+                                             },
+                                             "OPTIONS": {
+                                                  "value": 4
+                                             },
+                                             "PATCH": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "headers",
+                              "type": "list",
+                              "description": "Custom HTTP headers to put on HTTP request",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "key",
+                                        "type": "leaf",
+                                        "description": "HTTP header key",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "value",
+                                        "type": "leaf",
+                                        "description": "HTTP header value",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "key"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "path"
+                    ]
+               },
+               {
+                    "name": "monitoring-param",
+                    "type": "list",
+                    "description": "List of monitoring parameters at the NS level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "http-endpoint-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../http-endpoint/path"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-method",
+                              "type": "leaf",
+                              "description": "The method to extract a value from a JSON response NAMEKEY - Use the name as the key for a non-nested value. JSONPATH - Use jsonpath-rw implemenation to extract a value. OBJECTPATH - Use objectpath implemenation to extract a value.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "NAMEKEY": {
+                                                  "value": 0
+                                             },
+                                             "JSONPATH": {
+                                                  "value": 1
+                                             },
+                                             "OBJECTPATH": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "group-tag",
+                              "type": "leaf",
+                              "description": "A simple tag to group monitoring parameters",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-type",
+                              "type": "leaf",
+                              "description": "The type of the parameter value",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "INT": {
+                                                  "value": 0
+                                             },
+                                             "DECIMAL": {
+                                                  "value": 1
+                                             },
+                                             "STRING": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-integer",
+                              "type": "leaf",
+                              "description": "Current value for an integer parameter",
+                              "cardinality": "0..1",
+                              "data-type": "int64",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-decimal",
+                              "type": "leaf",
+                              "description": "Current value for a decimal parameter",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "decimal64": {
+                                        "fraction-digits": "4"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-string",
+                              "type": "leaf",
+                              "description": "Current value for a string parameter",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "widget-type",
+                              "type": "leaf",
+                              "description": "Type of the widget, typically used by the UI.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "HISTOGRAM": {
+                                                  "value": 0
+                                             },
+                                             "BAR": {
+                                                  "value": 1
+                                             },
+                                             "GAUGE": {
+                                                  "value": 2
+                                             },
+                                             "SLIDER": {
+                                                  "value": 3
+                                             },
+                                             "COUNTER": {
+                                                  "value": 4
+                                             },
+                                             "TEXTBOX": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "units",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-params",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "json-path",
+                                        "type": "leaf",
+                                        "description": "The jsonpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "object-path",
+                                        "type": "leaf",
+                                        "description": "The objectpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "numeric-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-value",
+                                        "type": "leaf",
+                                        "description": "Minimum value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-value",
+                                        "type": "leaf",
+                                        "description": "Maxium value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "text-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-length",
+                                        "type": "leaf",
+                                        "description": "Minimum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-length",
+                                        "type": "leaf",
+                                        "description": "Maximum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               }
+          ],
+          "key": [
+               "id"
+          ]
+     }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/nsd.yang.src b/skyquake/plugins/composer/src/schemas/yang/nsd.yang.src
new file mode 100644 (file)
index 0000000..256511b
--- /dev/null
@@ -0,0 +1,655 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module nsd
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:nsd";
+  prefix "nsd";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import vld {
+    prefix "vld";
+  }
+
+  import vnfd {
+    prefix "vnfd";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  revision 2014-10-27 {
+    description
+      "Initial revision. This YANG file defines
+       the Network Service Descriptor (NSD)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  typedef scaling-trigger {
+    type enumeration {
+      enum pre-scale-in {
+        value 1;
+      }
+      enum post-scale-in {
+        value 2;
+      }
+      enum pre-scale-out {
+        value 3;
+      }
+      enum post-scale-out {
+        value 4;
+      }
+    }
+  }
+
+  container nsd-catalog {
+
+    list nsd {
+      key "id";
+
+      leaf id {
+        description "Identifier for the NSD.";
+        type string;
+      }
+
+      leaf name {
+        description "NSD name.";
+        mandatory true;
+        type string;
+      }
+
+      leaf short-name {
+        description "NSD short name.";
+        type string;
+      }
+
+
+      leaf vendor {
+        description "Vendor of the NSD.";
+        type string;
+      }
+
+      leaf logo {
+        description
+          "File path for  the vendor specific logo. For example icons/mylogo.png.
+           The logo  should be part of the network service";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the NSD.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the NSD";
+        type string;
+      }
+
+      list connection-point {
+        description
+            "List for external connection points.
+            Each NS has one or more external connection
+            points. As the name implies that external
+            connection points are used for connecting
+            the NS to other NS or to external networks.
+            Each NS exposes these connection points to
+            the orchestrator. The orchestrator can
+            construct network service chains by
+            connecting the connection points between
+            different NS.";
+
+        key "name";
+        leaf name {
+          description
+              "Name of the NS connection point.";
+          type string;
+        }
+
+        leaf type {
+          description
+              "Type of the connection point.";
+          type manotypes:connection-point-type;
+        }
+      }
+
+      /* Still having issues modelling this,
+         see the comments under vnfd-connection-point-ref
+       */
+      list vld {
+        description
+            "List of Virtual Link Descriptors.";
+
+        key "id";
+
+        leaf id {
+          description
+              "Identifier for the VLD.";
+          type string;
+        }
+
+        leaf name {
+          description
+              "Virtual Link Descriptor (VLD) name.";
+          type string;
+        }
+
+        leaf short-name {
+          description
+              "Short name for VLD for UI";
+          type string;
+        }
+
+        leaf vendor {
+          description "Provider of the VLD.";
+          type string;
+        }
+
+        leaf description {
+          description "Description of the VLD.";
+          type string;
+        }
+
+        leaf version {
+          description "Version of the VLD";
+          type string;
+        }
+
+        leaf type {
+          type manotypes:virtual-link-type;
+        }
+
+        leaf root-bandwidth {
+          description
+              "For ELAN this is the aggregate bandwidth.";
+          type uint64;
+        }
+
+        leaf leaf-bandwidth {
+          description
+              "For ELAN this is the bandwidth of branches.";
+          type uint64;
+        }
+
+        list vnfd-connection-point-ref {
+          description
+              "A list of references to connection points.";
+          key "member-vnf-index-ref";
+
+          leaf member-vnf-index-ref {
+            description "Reference to member-vnf within constituent-vnfds";
+            type leafref {
+              path "../../../nsd:constituent-vnfd/nsd:member-vnf-index";
+            }
+          }
+
+           leaf vnfd-id-ref {
+             description
+                 "A reference to a vnfd. This is a
+                  leafref to path:
+                      ../../../nsd:constituent-vnfd
+                      + [nsd:id = current()/../nsd:id-ref]
+                      + /nsd:vnfd-id-ref
+                  NOTE: An issue with confd is preventing the
+                  use of xpath. Seems to be an issue with leafref
+                  to leafref, whose target is in a different module.
+                  Once that is resovled this will switched to use
+                  leafref";
+             type string;
+           }
+
+           leaf vnfd-connection-point-ref {
+             description
+                 "A reference to a connection point name
+                  in a vnfd. This is a leafref to path:
+                      /vnfd:vnfd-catalog/vnfd:vnfd
+                      + [vnfd:id = current()/../nsd:vnfd-id-ref]
+                      + /vnfd:connection-point/vnfd:name
+                  NOTE: An issue with confd is preventing the
+                  use of xpath. Seems to be an issue with leafref
+                  to leafref, whose target is in a different module.
+                  Once that is resovled this will switched to use
+                  leafref";
+              type string;
+          }
+        }
+
+        // replicate for pnfd container here
+        uses manotypes:provider-network;
+      }
+
+      list constituent-vnfd {
+        description
+            "List of VNFDs that are part of this
+            network service.";
+
+        key "member-vnf-index";
+
+        leaf member-vnf-index {
+          description
+            "Identifier/index for the VNFD. This separate id
+             is required to ensure that multiple VNFs can be
+             part of single NS";
+          type uint64;
+        }
+
+        leaf vnfd-id-ref {
+          description
+            "Identifier for the VNFD.";
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+          }
+        }
+
+        leaf start-by-default {
+          description
+            "VNFD is started as part of the NS instantiation";
+          type boolean;
+          default true;
+        }
+      }
+
+      list scaling-group-descriptor {
+        description
+            "scaling group descriptor within this network service.
+             The scaling group defines a group of VNFs,
+             and the ratio of VNFs in the network service
+             that is used as target for scaling action";
+
+        key "name";
+
+        leaf name {
+          description "Name of this scaling group.";
+          type string;
+        }
+
+        list vnfd-member {
+          description "List of VNFs in this scaling group";
+          key "member-vnf-index-ref";
+
+          leaf member-vnf-index-ref {
+            description "member VNF index of this member VNF";
+            type leafref {
+              path "../../../constituent-vnfd/member-vnf-index";
+            }
+          }
+
+          leaf count {
+            description
+              "count of this member VNF  within this scaling group.
+               The count allows to define  the number of instances
+               when a scaling action targets this scaling group";
+            type uint32;
+            default 1;
+          }
+        }
+
+        leaf min-instance-count {
+          description
+            "Minimum instances of the scaling group which are allowed.
+            These instances are created by default when the network service
+            is instantiated.";
+          type uint32;
+          default 0;
+        }
+
+        leaf max-instance-count {
+          description
+            "Maximum instances of this scaling group that are allowed
+             in a single network service. The network service scaling
+             will fail, when the number of service group instances
+             exceed the max-instance-count specified.";
+          type uint32;
+          default 10;
+        }
+
+        list scaling-config-action {
+          description "List of scaling config actions";
+          key "trigger";
+
+          leaf trigger {
+            description "scaling trigger";
+            type scaling-trigger;
+          }
+
+          leaf ns-config-primitive-name-ref {
+            description "Reference to the NS config name primitive";
+            type leafref {
+              path "../../../config-primitive/name";
+            }
+          }
+        }
+      }
+
+      list placement-groups {
+        description "List of placement groups at NS level";
+
+        key "name";
+        uses manotypes:placement-group-info;
+        
+        list member-vnfd {
+          description
+              "List of VNFDs that are part of this placement group";
+
+          key "member-vnf-index-ref";
+
+          leaf member-vnf-index-ref {
+            description "member VNF index of this member VNF";
+            type leafref {
+              path "../../../constituent-vnfd/member-vnf-index";
+            }
+          }
+
+          leaf vnfd-id-ref {
+            description
+                "Identifier for the VNFD.";
+            type leafref {
+              path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+            }
+          }
+        }
+      }
+
+      list vnf-dependency {
+        description
+            "List of VNF dependencies.";
+        key vnf-source-ref;
+        leaf vnf-source-ref {
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+          }
+        }
+        leaf vnf-depends-on-ref {
+          description
+              "Reference to VNF that sorce VNF depends.";
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+          }
+        }
+      }
+
+      list vnffgd {
+        description
+            "List of VNF Forwarding Graph Descriptors (VNFFGD).";
+
+        key "id";
+
+        leaf id {
+          description
+              "Identifier for the VNFFGD.";
+          type string;
+        }
+
+        leaf name {
+          description
+              "VNFFGD name.";
+          type string;
+        }
+
+        leaf short-name {
+          description
+              "Short name for VNFFGD for UI";
+          type string;
+        }
+
+        leaf vendor {
+          description "Provider of the VNFFGD.";
+          type string;
+        }
+
+        leaf description {
+          description "Description of the VNFFGD.";
+          type string;
+        }
+
+        leaf version {
+          description "Version of the VNFFGD";
+          type string;
+        }
+
+        list rsp {
+          description
+              "List of Rendered Service Paths (RSP).";
+
+          key "id";
+
+          leaf id {
+            description
+                "Identifier for the RSP.";
+            type string;
+          }
+
+          leaf name {
+            description
+                "RSP name.";
+            type string;
+          }
+
+          list vnfd-connection-point-ref {
+            description
+                  "A list of references to connection points.";
+            key "member-vnf-index-ref";
+
+            leaf member-vnf-index-ref {
+              description "Reference to member-vnf within constituent-vnfds";
+              type leafref {
+                path "../../../../nsd:constituent-vnfd/nsd:member-vnf-index";
+              }
+            }
+
+            leaf order {
+              type uint8;
+              description
+                  "A number that denotes the order of a VNF in a chain";
+            }
+
+             leaf vnfd-id-ref {
+               description
+                   "A reference to a vnfd. This is a
+                    leafref to path:
+                        ../../../../nsd:constituent-vnfd
+                        + [nsd:id = current()/../nsd:id-ref]
+                        + /nsd:vnfd-id-ref
+                    NOTE: An issue with confd is preventing the
+                    use of xpath. Seems to be an issue with leafref
+                    to leafref, whose target is in a different module.
+                    Once that is resovled this will switched to use
+                    leafref";
+               type string;
+             }
+
+             leaf vnfd-connection-point-ref {
+               description
+                   "A reference to a connection point name
+                    in a vnfd. This is a leafref to path:
+                        /vnfd:vnfd-catalog/vnfd:vnfd
+                        + [vnfd:id = current()/../nsd:vnfd-id-ref]
+                        + /vnfd:connection-point/vnfd:name
+                    NOTE: An issue with confd is preventing the
+                    use of xpath. Seems to be an issue with leafref
+                    to leafref, whose target is in a different module.
+                    Once that is resovled this will switched to use
+                    leafref";
+                type string;
+            }
+          }
+        } //rsp
+
+        list classifier {
+          description
+              "List of classifier rules.";
+
+          key "id";
+
+          leaf id {
+            description
+                "Identifier for the classifier rule.";
+            type string;
+          }
+
+          leaf name {
+            description
+                "Name of the classifier.";
+            type string;
+          }
+
+          leaf rsp-id-ref {
+            description
+                "A reference to the RSP.";
+            type leafref {
+              path "../../nsd:rsp/nsd:id";
+            }
+          }
+
+          leaf member-vnf-index-ref {
+            description "Reference to member-vnf within constituent-vnfds";
+            type leafref {
+              path "../../../nsd:constituent-vnfd/nsd:member-vnf-index";
+            }
+          }
+
+          leaf vnfd-id-ref {
+            description
+                "A reference to a vnfd. This is a
+                    leafref to path:
+                        ../../../nsd:constituent-vnfd
+                        + [nsd:id = current()/../nsd:id-ref]
+                        + /nsd:vnfd-id-ref
+                    NOTE: An issue with confd is preventing the
+                    use of xpath. Seems to be an issue with leafref
+                    to leafref, whose target is in a different module.
+                    Once that is resovled this will switched to use
+                    leafref";
+            type string;
+          }
+
+          leaf vnfd-connection-point-ref {
+            description
+                "A reference to a connection point name
+                    in a vnfd. This is a leafref to path:
+                        /vnfd:vnfd-catalog/vnfd:vnfd
+                        + [vnfd:id = current()/../nsd:vnfd-id-ref]
+                        + /vnfd:connection-point/vnfd:name
+                    NOTE: An issue with confd is preventing the
+                    use of xpath. Seems to be an issue with leafref
+                    to leafref, whose target is in a different module.
+                    Once that is resovled this will switched to use
+                    leafref";
+            type string;
+          }
+
+          list match-attributes {
+            description
+                "List of match attributes.";
+
+            key "id";
+
+            leaf id {
+              description
+                  "Identifier for the classifier match attribute rule.";
+              type string;
+            }
+
+            leaf ip-proto {
+              description
+                  "IP Protocol.";
+              type uint8;
+            }
+
+            leaf source-ip-address {
+              description
+                  "Source IP address.";
+              type inet:ip-address;
+            }
+
+            leaf destination-ip-address {
+              description
+                  "Destination IP address.";
+              type inet:ip-address;
+            }
+
+            leaf source-port {
+              description
+                  "Source port number.";
+              type inet:port-number;
+            }
+
+            leaf destination-port {
+              description
+                  "Destination port number.";
+              type inet:port-number;
+            }
+            //TODO: Add more match criteria
+          } //match-attributes
+        } // classifier
+      } // vnffgd
+
+      uses manotypes:monitoring-param;
+      uses manotypes:input-parameter-xpath;
+
+      list parameter-pool {
+        description
+          "Pool of parameter values which must be
+           pulled from during configuration";
+        key "name";
+
+        leaf name {
+          description
+              "Name of the configuration value pool";
+          type string;
+        }
+
+        container range {
+          description
+              "Create a range of values to populate the pool with";
+
+          leaf start-value {
+            description
+                "Generated pool values start at this value";
+            type uint32;
+            mandatory true;
+          }
+
+          leaf end-value {
+            description
+                "Generated pool values stop at this value";
+            type uint32;
+            mandatory true;
+          }
+        }
+      }
+
+      uses manotypes:config-primitive;
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/nsr.yang.src b/skyquake/plugins/composer/src/schemas/yang/nsr.yang.src
new file mode 100755 (executable)
index 0000000..9fc3fac
--- /dev/null
@@ -0,0 +1,1118 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module nsr
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:nsr";
+  prefix "nsr";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import vlr {
+    prefix "vlr";
+  }
+
+  import vld {
+    prefix "vld";
+  }
+
+  import nsd {
+    prefix "nsd";
+  }
+
+  import vnfd {
+    prefix "vnfd";
+  }
+
+  import vnfr {
+    prefix "vnfr";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import rw-sdn {
+    prefix "rwsdn";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file defines
+       the Network Service Record (NSR)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  typedef config-states {
+    type enumeration {
+      enum init;
+      enum configuring;
+      enum config_not_needed;
+      enum configured;
+      enum failed;
+    }
+  }
+
+  container ns-instance-config {
+
+    list nsr {
+      key "id";
+      unique "name";
+
+      leaf id {
+        description "Identifier for the NSR.";
+        type yang:uuid;
+      }
+
+      leaf name {
+        description "NSR name.";
+        type string;
+      }
+
+      leaf short-name {
+        description "NSR short name.";
+        type string;
+      }
+
+      leaf description {
+        description "NSR description.";
+        type string;
+      }
+
+      leaf nsd-ref {
+        description "Reference to NSD";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd/nsd:id";
+        }
+      }
+
+      leaf admin-status {
+        description
+          "This is the administrative status of the NS instance";
+
+        type enumeration {
+          enum ENABLED;
+          enum DISABLED;
+        }
+      }
+
+      uses manotypes:input-parameter;
+
+      list scaling-group {
+        description "List of ns scaling group instances";
+        key "scaling-group-name-ref";
+
+        leaf scaling-group-name-ref {
+          description "name of the scaling group";
+          type leafref {
+            path "/nsd:nsd-catalog/nsd:nsd[nsd:id = current()/" +
+                 "../../nsr:nsd-ref]/nsd:scaling-group-descriptor/nsd:name";
+          }
+        }
+
+        list instance {
+          description "The instance of the scaling group";
+          key "id";
+          leaf id {
+            description "Scaling group instance uuid";
+            type uint16;
+          }
+        }
+      }
+
+
+      list nsd-placement-group-maps {
+        description
+            "Mapping from mano-placement groups construct from NSD to cloud
+             platform placement group construct";
+
+        key "placement-group-ref";
+
+        leaf placement-group-ref {
+          description "Reference for NSD placement group";
+          type leafref {
+            path "/nsd:nsd-catalog/nsd:nsd[nsd:id = current()/" +
+                 "../../nsr:nsd-ref]/nsd:placement-groups/nsd:name";
+          }
+        }
+        uses manotypes:placement-group-input;
+      }
+
+      list vnfd-placement-group-maps {
+        description
+            "Mapping from mano-placement groups construct from VNFD to cloud
+             platform placement group construct";
+
+        key "placement-group-ref vnfd-id-ref";
+
+        leaf vnfd-id-ref {
+          description
+              "A reference to a vnfd. This is a
+                    leafref to path:
+                        ../../../../nsd:constituent-vnfd
+                        + [nsr:id = current()/../nsd:id-ref]
+                        + /nsd:vnfd-id-ref
+               NOTE: An issue with confd is preventing the
+               use of xpath. Seems to be an issue with leafref
+               to leafref, whose target is in a different module.
+               Once that is resovled this will switched to use
+               leafref";
+          type yang:uuid;
+        }
+
+        leaf placement-group-ref {
+          description
+              "A reference to VNFD placement group";
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id = current()/" +
+                "../nsr:vnfd-id-ref]/vnfd:placement-groups/vnfd:name";
+          }
+        }
+
+        uses manotypes:placement-group-input;
+      }
+    }
+  }
+
+  grouping vnffgr {
+
+    list vnffgr {
+      key "id";
+
+      leaf id {
+        description "Identifier for the VNFFGR.";
+        type yang:uuid;
+      }
+
+      leaf nsd-id {
+        description
+            "Network sevice descriptor ID reference";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd/nsd:id";
+        }
+      }
+
+
+      leaf vnffgd-id-ref {
+        description "VNFFG descriptor id reference";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd"
+              + "[nsd:id = current()/../nsr:nsd-id]"
+              + "/nsd:vnffgd/nsd:id";
+        }
+      }
+
+      leaf vnffgd-name-ref {
+        description "VNFFG descriptor name reference";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd"
+              + "[nsd:id = current()/../nsr:nsd-id]"
+              + "/nsd:vnffgd[nsd:id = current()/../vnffgd-id-ref]"
+              + "/nsd:name";
+        }
+      }
+
+      leaf sdn-account {
+        description
+            "The SDN account to use when requesting resources for
+            this vnffgr";
+        type leafref {
+          path "/rwsdn:sdn-account/rwsdn:name";
+        }
+      }
+
+      leaf operational-status {
+        description
+          "The operational status of the VNFFGR instance
+            init                : The VNFFGR has just started.
+            running             : The VNFFGR is in running state.
+            terminate           : The VNFFGR is being terminated.
+            terminated          : The VNFFGR is in the terminated state.
+            failed              : The VNFFGR instantiation failed
+          ";
+
+        type enumeration {
+          //rwpb:enum-type "VnffgrOperationalStatus";
+          enum init;
+          enum running;
+          enum terminate;
+          enum terminated;
+          enum failed;
+        }
+      }
+
+      list rsp {
+        key "id";
+
+        leaf id {
+          description
+              "Identifier for the RSP.";
+          type yang:uuid;
+        }
+
+        leaf name {
+          description
+              "Name for the RSP";
+          type string;
+        }
+
+        leaf vnffgd-rsp-id-ref {
+          description
+              "Identifier for the VNFFG Descriptor RSP reference";
+          type leafref {
+            path "/nsd:nsd-catalog/nsd:nsd/nsd:vnffgd"
+                + "[nsd:id = current()/../../nsr:vnffgd-id-ref]"
+                + "/nsd:rsp/nsd:id";
+          }
+        }
+
+        leaf vnffgd-rsp-name-ref {
+          description
+              "Name for the VNFFG Descriptor RSP reference";
+          type leafref {
+            path "/nsd:nsd-catalog/nsd:nsd/nsd:vnffgd"
+                + "[nsd:id = current()/../../nsr:vnffgd-id-ref]"
+                + "/nsd:rsp[nsd:id=current()/../vnffgd-rsp-id-ref]"
+                + "/nsd:name";
+          }
+        }
+
+        leaf classifier-name {
+          type string;
+        }
+
+        leaf path-id {
+          description
+              "Unique Identifier for the service path";
+          type uint32;
+        }
+
+        list vnfr-connection-point-ref {
+          key "hop-number";
+          leaf hop-number {
+            description
+                "Monotonically increasing number to show service path hop
+                order";
+            type uint8;
+          }
+          leaf service-function-type {
+            description
+                "Type of Service Function.
+                NOTE: This needs to map with Service Function Type in ODL to
+                support VNFFG. Service Function Type is manadatory param in ODL
+                SFC. This is temporarily set to string for ease of use";
+            type string;
+          }
+
+          leaf member-vnf-index-ref {
+            type uint64;
+          }
+          leaf vnfd-id-ref {
+            description
+                "Reference to VNF Descriptor Id";
+            type string;
+          }
+          leaf vnfr-id-ref {
+            description
+                "A reference to a vnfr id";
+                type leafref {
+                  path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:id";
+                }
+          }
+          leaf vnfr-name-ref {
+            description
+                "A reference to a vnfr name";
+                type leafref {
+                  path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:name";
+                }
+          }
+          leaf vnfr-connection-point-ref {
+            description
+                "A reference to a vnfr connection point.";
+            type leafref {
+              path "/vnfr:vnfr-catalog/vnfr:vnfr"
+                 + "[vnfr:id = current()/../nsr:vnfr-id-ref]"
+                 + "/vnfr:connection-point/vnfr:name";
+            }
+          }
+          leaf service-index {
+            description
+                "Location within the service path";
+            type uint8;
+          }
+          container connection-point-params {
+            leaf mgmt-address {
+              type inet:ip-address;
+            }
+            leaf name {
+              type string;
+            }
+            leaf port-id {
+              //rwpb:field-inline "true";
+              //rwpb:field-string-max 64;
+              type string;
+            }
+            leaf vm-id {
+              //rwpb:field-inline "true";
+              //rwpb:field-string-max 64;
+              type string;
+            }
+            leaf address {
+              type inet:ip-address;
+            }
+            leaf port {
+              type inet:port-number;
+            }
+          }
+
+          container service-function-forwarder {
+            leaf name {
+              description
+                  "Service Function Forwarder name";
+              type string;
+            }
+            leaf ip-address {
+              description
+                  "Data Plane IP Address of the SFF";
+              type inet:ip-address;
+            }
+            leaf port {
+              description
+                  "Data Plane Port of the SFF";
+              type inet:port-number;
+            }
+          }
+        }
+      }
+
+      list classifier {
+          key "id";
+
+          leaf id {
+            description
+                "Identifier for the classifier rule.";
+            type yang:uuid;
+          }
+          leaf name {
+            description
+                "Name of the classifier.";
+            type string;
+          }
+          leaf rsp-id-ref {
+            description
+                "A reference to the RSP.";
+            type leafref {
+              path "../../nsr:rsp/nsr:id";
+            }
+          }
+          leaf rsp-name {
+            description
+              "Name for the RSP";
+            type string;
+          }
+          leaf vnfr-id-ref {
+            description
+                "A reference to a vnfr id";
+                type leafref {
+                  path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:id";
+                }
+          }
+          leaf vnfr-name-ref {
+            description
+                "A reference to a vnfr name";
+                type leafref {
+                  path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:name";
+                }
+          }
+          leaf vnfr-connection-point-ref {
+            description
+                "A reference to a vnfr connection point.";
+            type leafref {
+              path "/vnfr:vnfr-catalog/vnfr:vnfr"
+                 + "[vnfr:id = current()/../nsr:vnfr-id-ref]"
+                 + "/vnfr:connection-point/vnfr:name";
+            }
+          }
+          leaf port-id {
+            //rwpb:field-inline "true";
+            //rwpb:field-string-max 64;
+            type string;
+          }
+          leaf vm-id {
+            //rwpb:field-inline "true";
+            //rwpb:field-string-max 64;
+            type string;
+          }
+          leaf ip-address {
+            type string;
+          }
+          leaf sff-name {
+            type string;
+          }
+      }
+    }
+  }
+
+  container ns-instance-opdata {
+    config false;
+
+    list nsr {
+      key "ns-instance-config-ref";
+
+      leaf ns-instance-config-ref {
+        type leafref {
+          path "/nsr:ns-instance-config/nsr:nsr/nsr:id";
+        }
+      }
+
+      leaf name-ref {
+        description "Network service name reference";
+        type leafref {
+          path "/nsr:ns-instance-config/nsr:nsr/nsr:name";
+        }
+      }
+
+      leaf nsd-ref {
+        description "Network service descriptor id reference";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd/nsd:id";
+        }
+      }
+
+      leaf nsd-name-ref {
+        description "Network service descriptor name reference";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd/nsd:name";
+        }
+      }
+
+      leaf create-time {
+        description
+          "Creation timestamp of this Network Service.
+          The timestamp is expressed as seconds
+          since unix epoch - 1970-01-01T00:00:00Z";
+
+        type uint32;
+      }
+
+      list connection-point {
+        description
+            "List for external connection points.
+            Each NS has one or more external connection points.
+            As the name implies that external connection points
+            are used for connecting the NS to other NS or to
+            external networks. Each NS exposes these connection
+            points to the orchestrator. The orchestrator can
+            construct network service chains by connecting the
+            connection points between different NS.";
+
+        key "name";
+        leaf name {
+          description
+              "Name of the NS connection point.";
+          type string;
+        }
+
+        leaf type {
+          description
+              "Type of the connection point.";
+          type manotypes:connection-point-type;
+        }
+      }
+
+      list vlr {
+        key "vlr-ref";
+        leaf vlr-ref {
+          description
+              "Reference to a VLR record in the VLR catalog";
+          type leafref {
+            path "/vlr:vlr-catalog/vlr:vlr/vlr:id";
+          }
+        }
+
+
+        list vnfr-connection-point-ref {
+          description
+            "A list of references to connection points.";
+          key "vnfr-id";
+
+          leaf vnfr-id {
+            description "A reference to a vnfr";
+            type leafref {
+              path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:id";
+            }
+          }
+
+          leaf connection-point {
+            description
+                "A reference to a connection point name in a vnfr";
+            type leafref {
+              path "/vnfr:vnfr-catalog/vnfr:vnfr"
+                 + "[vnfr:id = current()/../nsr:vnfr-id]"
+                 + "/vnfr:connection-point/vnfr:name";
+            }
+          }
+        }
+      }
+
+      list constituent-vnfr-ref {
+        description
+            "List of VNFRs that are part of this
+             network service.";
+        key "vnfr-id";
+
+        leaf vnfr-id {
+          description "Reference to the VNFR id";
+          type leafref {
+            path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:id";
+          }
+        }
+      }
+
+      list scaling-group-record {
+        description "List of scaling group records";
+        key "scaling-group-name-ref";
+
+        leaf scaling-group-name-ref {
+          description "name of the scaling group";
+          type leafref {
+            path "/nsd:nsd-catalog/nsd:nsd"+
+                 "[nsd:id = current()/../../nsr:nsd-ref]" +
+                 "/nsd:scaling-group-descriptor/nsd:name";
+          }
+        }
+
+        list instance {
+          description "Reference to scaling group instance record";
+          key "instance-id";
+          leaf instance-id {
+            description "Scaling group instance id";
+            type uint16;
+          }
+
+          leaf is-default {
+            description "Flag indicating whether this instance was part of
+                default scaling group (and thus undeletable)";
+            type boolean;
+          }
+
+          leaf op-status {
+            description
+              "The operational status of the NS instance
+                init                : The scaling group has just started.
+                vnf-init-phase      : The VNFs in the scaling group are being instantiated.
+                running             : The scaling group  is in running state.
+                terminate           : The scaling group is being terminated.
+                vnf-terminate-phase : The VNFs in the scaling group are being terminated.
+                terminated          : The scaling group  is in the terminated state.
+                failed              : The scaling group instantiation failed.
+              ";
+
+            type enumeration {
+              enum init;
+              enum vnf-init-phase;
+              enum running;
+              enum terminate;
+              enum vnf-terminate-phase;
+              enum terminated;
+              enum failed;
+            }
+          }
+
+          leaf config-status {
+            description
+              "The configuration status of the scaling group instance
+               configuring : At least one of the VNFs in this scaling group instance
+                             is in configuring state
+               configured  : All the VNFs in this scaling group instance are
+                             configured or config-not-needed state
+               failed      : Configuring this scaling group instance failed
+              ";
+            type config-states;
+          }
+
+          leaf error-msg {
+            description
+              "Reason for failure in configuration of this scaling instance";
+            type string;
+          }
+
+          leaf create-time {
+            description
+              "Creation timestamp of this scaling group record.
+              The timestamp is expressed as seconds
+              since unix epoch - 1970-01-01T00:00:00Z";
+
+              type uint32;
+          }
+
+          leaf-list vnfrs {
+            description "Reference to VNFR within the scale instance";
+            type leafref {
+              path "../../../constituent-vnfr-ref/vnfr-id";
+            }
+          }
+        }
+      }
+
+      uses vnffgr;
+
+      leaf operational-status {
+        description
+          "The operational status of the NS instance
+            init                : The network service has just started.
+            vl-init-phase       : The VLs in the NS are being instantiated.
+            vnf-init-phase      : The VNFs in the NS are being instantiated.
+            running             : The NS is in running state.
+            terminate           : The NS is being terminated.
+            vnf-terminate-phase : The NS is terminating the VNFs in the NS.
+            vl-terminate-phase  : The NS is terminating the VLs in the NS.
+            terminated          : The NS is in the terminated state.
+            failed              : The NS instantiation failed.
+            scaling-out         : The NS is scaling out
+            scaling-in          : The NS is scaling in
+          ";
+
+        type enumeration {
+          enum init;
+          enum vl-init-phase;
+          enum vnf-init-phase;
+          enum running;
+          enum terminate;
+          enum vnf-terminate-phase;
+          enum vl-terminate-phase;
+          enum terminated;
+          enum failed;
+          enum scaling-out;
+          enum scaling-in;
+        }
+      }
+
+      leaf config-status {
+        description
+          "The configuration status of the NS instance
+            configuring: At least one of the VNFs in this instance is in configuring state
+            configured:  All the VNFs in this NS instance are configured or config-not-needed state
+          ";
+        type config-states;
+      }
+
+      uses manotypes:monitoring-param;
+      uses manotypes:config-primitive;
+
+      list vnf-monitoring-param {
+        description
+          "List of VNF monitoring params.";
+
+        key "vnfr-id-ref";
+
+        leaf vnfr-id-ref {
+          description
+            "Reference to vnfr-id";
+          type leafref {
+            path "/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:id";
+          }
+        }
+
+        uses manotypes:monitoring-param;
+      }
+
+      list config-agent-job {
+        key "job-id";
+
+        leaf job-id {
+          description "config agent job Identifier for the NS.";
+          type uint64;
+        }
+
+        leaf job-name {
+          description "Config agent job name";
+          type string;
+        }
+
+        leaf job-status {
+          description
+              "Job status to be set based on each VNF primitive execution,
+               pending  - if at least one VNF is in pending state
+                          and remaining VNFs are in success state.
+               Success  - if all VNF executions are in success state
+               failure  - if one of the VNF executions is failure";
+          type enumeration {
+            enum pending;
+            enum success;
+            enum failure;
+          }
+        }
+
+        list vnfr {
+          key "id";
+          leaf id {
+            description "Identifier for the VNFR.";
+            type yang:uuid;
+          }
+          leaf vnf-job-status {
+            description
+                "Job status to be set based on each VNF primitive execution,
+                 pending  - if at least one primitive is in pending state
+                            and remaining primitives are in success state.
+                 Success  - if all primitive executions are in success state
+                 failure  - if one of the primitive executions is failure";
+            type enumeration {
+              enum pending;
+              enum success;
+              enum failure;
+            }
+          }
+          list primitive {
+            key "name";
+            leaf name {
+              description "the name of the primitive";
+              type string;
+            }
+            leaf execution-id {
+              description "Execution id of the primitive";
+              type string;
+            }
+            leaf execution-status {
+              description "status of the Execution";
+              type enumeration {
+                enum pending;
+                enum success;
+                enum failure;
+              }
+            }
+            leaf execution-error-details {
+              description "Error details if execution-status is failure";
+              type string;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  rpc get-ns-config-primitive-values {
+    description "Executes a VNF configuration primitive";
+    input {
+      leaf nsr_id_ref {
+        description "Reference to NSR ID ref";
+        mandatory true;
+        type leafref {
+          path "/nsr:ns-instance-config/nsr:nsr/nsr:id";
+        }
+      }
+
+      leaf name {
+        description "Name of the NS config primitive group";
+        mandatory true;
+        type string;
+      }
+    }
+
+    output {
+      list ns-parameter {
+        description "Automatically generated parameter";
+        key "name";
+
+        leaf name {
+          description "Parameter name which should be pulled from a parameter pool";
+          type string;
+        }
+        leaf value {
+          description "Automatically generated value";
+          type string;
+        }
+      }
+
+      list ns-parameter-group {
+        description "Automatically generated parameters in parameter group";
+        key "name";
+        leaf name {
+          description "Parameter group name";
+          type string;
+        }
+        list parameter {
+          description "Automatically generated group parameter";
+          key "name";
+
+          leaf name {
+            description "Parameter name which should be pulled from a parameter pool";
+            type string;
+          }
+          leaf value {
+            description "Automatically generated value";
+            type string;
+          }
+        }
+      }
+
+      list vnf-primitive-group {
+        description
+            "List of configuration primitives grouped by VNF.";
+
+        key "member-vnf-index-ref";
+        leaf member-vnf-index-ref {
+          description
+              "Reference to member-vnf within constituent-vnfds";
+          type uint64;
+        }
+
+        leaf vnfd-id-ref {
+          description
+              "A reference to a vnfd. This is a
+               leafref to path:
+                   ../../../../nsd:constituent-vnfd
+                   + [nsd:id = current()/../nsd:id-ref]
+                   + /nsd:vnfd-id-ref
+               NOTE: An issue with confd is preventing the
+               use of xpath. Seems to be an issue with leafref
+               to leafref, whose target is in a different module.
+               Once that is resovled this will switched to use
+               leafref";
+
+          type string;
+        }
+
+        list primitive {
+          key "index";
+          leaf index {
+            description "Index of this primitive";
+            type uint32;
+          }
+
+          leaf name {
+            description "Name of the primitive associated with a value pool";
+            type string;
+          }
+
+          list parameter {
+            description "Automatically generated parameter";
+            key "name";
+
+            leaf name {
+              description "Parameter name which should be pulled from a parameter pool";
+              type string;
+            }
+            leaf value {
+              description "Automatically generated value";
+              type string;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  rpc exec-ns-config-primitive {
+    description "Executes a NS configuration primitive or script";
+
+    input {
+      leaf name {
+        description "Name of the primitive";
+        type string;
+      }
+
+      leaf nsr_id_ref {
+        description "Reference to NSR ID ref";
+        type leafref {
+          path "/nsr:ns-instance-config/nsr:nsr/nsr:id";
+        }
+      }
+
+      list parameter {
+        description
+            "List of NS Primitive parameters";
+        key "name";
+        leaf name {
+          description
+              "Name of the parameter.";
+          type string;
+        }
+
+        leaf value {
+          description
+              "Value associated with the name.";
+          type string;
+        }
+      }
+
+      list parameter-group {
+        description
+            "List of NS Primitive parameter groups";
+        key "name";
+        leaf name {
+          description
+              "Name of the parameter.";
+          type string;
+        }
+
+        list parameter {
+          description
+              "List of NS parameter group parameters";
+          key "name";
+          leaf name {
+            description
+                "Name of the parameter.";
+            type string;
+          }
+
+          leaf value {
+            description
+                "Value associated with the name.";
+            type string;
+          }
+        }
+      }
+
+      list vnf-list {
+        description
+            "List of VNFs whose primitives are being set.";
+        key "member_vnf_index_ref";
+
+        leaf member_vnf_index_ref {
+          description "Member VNF index";
+          type uint64;
+        }
+
+        leaf vnfr-id-ref {
+          description
+              "A reference to a vnfr. This is a
+               leafref to path";
+          type yang:uuid;
+        }
+
+        list vnf-primitive {
+          description
+              "List of configuration primitives supported by the
+            configuration agent for this VNF.";
+          key "index";
+
+          leaf index {
+            description
+                "index of the configuration primitive.";
+            type uint32;
+          }
+          leaf name {
+            description
+                "Name of the configuration primitive.";
+            type string;
+          }
+
+          list parameter {
+            description
+                "List of parameters to the configuration primitive.";
+            key "name";
+            leaf name {
+              description
+                  "Name of the parameter.";
+              type string;
+            }
+
+            leaf value {
+              description
+                  "Value associated with the name.";
+              type string;
+            }
+          }
+        }
+      }
+      leaf user-defined-script {
+        description
+            "A user defined script.";
+        type string;
+      }
+    }
+    output {
+      leaf job-id {
+        description "Job identifier for this RPC";
+        type uint64;
+      }
+
+      leaf name {
+        description "Name of the config";
+        type string;
+      }
+
+      leaf nsr_id_ref {
+        description "Reference to NSR ID ref";
+        type leafref {
+          path "/nsr:ns-instance-config/nsr:nsr/nsr:id";
+        }
+      }
+
+      list vnf-out-list {
+        description
+            "List of VNFs whose primitives were set.";
+        key "member_vnf_index_ref";
+
+        leaf member_vnf_index_ref {
+          description "Member VNF index";
+          type uint64;
+        }
+        leaf vnfr-id-ref {
+          description
+              "A reference to a vnfr. This is a
+               leafref to path";
+          type yang:uuid;
+        }
+
+        list vnf-out-primitive {
+          description
+              "List of configuration primitives supported by the
+            configuration agent for this VNF.";
+          key "index";
+
+          leaf index {
+            description
+                "index of the configuration primitive.";
+            type uint32;
+          }
+
+          leaf name {
+            description
+                "Name of the configuration primitive.";
+            type string;
+          }
+
+          leaf execution-id {
+            description "Execution id of this primitive";
+            type string;
+          }
+
+          leaf execution-status {
+            description "Status of the execution of this primitive";
+            type string;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/pnfd.yang.src b/skyquake/plugins/composer/src/schemas/yang/pnfd.yang.src
new file mode 100755 (executable)
index 0000000..e1f39a7
--- /dev/null
@@ -0,0 +1,104 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module pnfd
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:pnfd";
+  prefix "pnfd";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file defines 
+       the Physical Network Function Descriptor (PNFD)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  container pnfd-catalog {
+
+    list pnfd {
+      key "id";
+
+      leaf id {
+        description "Identifier for the PNFD.";
+        type yang:uuid;
+      }
+
+      leaf name {
+        description "PNFD name.";
+        type string;
+      }
+
+      leaf short-name {
+        description "PNFD short name.";
+        type string;
+      }
+
+      leaf vendor {
+        description "Vendor of the PNFD.";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the PNFD.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the PNFD";
+        type string;
+      }
+
+      list connection-point {
+        description
+            "List for external connection points. Each PNF has one or more external
+            connection points.";
+        key "id";
+        leaf id {
+          description
+              "Identifier for the external connection points";
+          type uint64;
+        }
+
+        leaf cp-type {
+          description
+              "Type of the connection point.";
+          type manotypes:connection-point-type;
+        }
+      }
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-nsd.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-nsd.yang.src
new file mode 100755 (executable)
index 0000000..4475928
--- /dev/null
@@ -0,0 +1,57 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-nsd
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-nsd";
+  prefix "rw-nsd";
+
+  import nsd {
+    prefix "nsd";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file augments
+       the base MANO NSD";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  augment /nsd:nsd-catalog/nsd:nsd {
+    uses manotypes:control-param;
+    uses manotypes:action-param;
+    leaf meta {
+      description
+        "Any meta-data needed by the UI";
+      type string;
+    }
+  }
+}
+
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-nsr.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-nsr.yang.src
new file mode 100755 (executable)
index 0000000..d259300
--- /dev/null
@@ -0,0 +1,306 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-nsr
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-nsr";
+  prefix "rw-nsr";
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import nsr {
+    prefix "nsr";
+  }
+
+  import nsd {
+    prefix "nsd";
+  }
+
+  import rw-cloud {
+    prefix "rw-cloud";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file augments
+       the base MANO VNFD";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  grouping operational-events {
+    list operational-events {
+      key "id";
+      description
+        "Recent operational events for this network service.
+        Though the model does not impose any restrictions on the numbe of events, 
+        the max operational events will be limited to the most recent 10"; 
+
+      leaf id {
+        description "The id of the instance";
+        type uint64;
+      }
+
+      leaf timestamp {
+        description
+          "The timestamp of this event expressed as seconds since
+          unix epoch - 1970-01-01T00:00:00Z";
+        type uint32;
+      }
+      leaf event {
+        description "Short description of the event";
+        type string;
+      }
+      leaf description {
+        description
+          "The description of this event";
+        type string;
+      }
+    }
+  }
+
+  grouping nsd-ref-count {
+    list nsd-ref-count {
+      key "nsd-id-ref";
+      description "This table maintains the number of NSRs used by each NSD";
+
+      leaf nsd-id-ref {
+        description "Reference to NSD";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd/nsd:id";
+        }
+      }
+      leaf instance-ref-count {
+        description
+          "Reference count for the number of NSRs refering this NSD.
+           Every NS record instantiated using this descriptor takes
+           a reference on the NSD and releases the reference when the
+           network service is terminated. This desciptor cannot be
+           deleted when this counter is non zero";
+        type uint64;
+      }
+    }
+  }
+
+  augment /nsr:ns-instance-config/nsr:nsr {
+    leaf cloud-account {
+      description
+        "The configured cloud account which the NSR is instantiated within.
+         All VDU's, Virtual Links, and provider networks will be requested
+         using the cloud-account's associated CAL instance";
+      type leafref {
+        path "/rw-cloud:cloud/rw-cloud:account/rw-cloud:name";
+      }
+    }
+
+    leaf om-datacenter {
+      description
+        "Openmano datacenter name to use when instantiating
+         the network service.  This is only used when openmano
+         is selected as the cloud account.  This should be superceded
+         by multiple cloud accounts when that becomes available.";
+      type string;
+    }
+  }
+
+  augment /nsr:ns-instance-opdata/nsr:nsr {
+    uses manotypes:action-param;
+    uses manotypes:control-param;
+
+    leaf cloud-account {
+      description
+        "The configured cloud account which the NSR is instantiated within.
+         All VDU's, Virtual Links, and provider networks will be requested
+         using the cloud-account's associated CAL instance";
+      type leafref {
+        path "/rw-cloud:cloud/rw-cloud:account/rw-cloud:name";
+      }
+    }
+
+    container nfvi-metrics {
+      container vm {
+        leaf label {
+          description
+            "Label to show in UI";
+          type string;
+          default "VM";
+        }
+
+        leaf active-vm {
+          description
+            "The number of active VMs.";
+          type uint64;
+        }
+
+        leaf inactive-vm {
+          description
+            "The number of inactive VMs.";
+          type uint64;
+        }
+      }
+
+      uses manotypes:nfvi-metrics;
+    }
+
+    container epa-param {
+      container ovs-acceleration {
+        leaf label {
+          description
+            "Label to show in UI for the param";
+          type string;
+          default "OVS ACCELERATION";
+        }
+
+        leaf vm {
+          description
+            "Number of VMs with the EPA attribute";
+          type uint64;
+        }
+
+        leaf unit {
+          description
+            "Unit label to show in the UI";
+          type string;
+          default "vms";
+        }
+      }
+
+      container ovs-offload {
+        leaf label {
+          description
+            "Label to show in UI for the param";
+          type string;
+          default "OVS OFFLOAD";
+        }
+
+        leaf vm {
+          description
+            "Number of VMs with the EPA attribute";
+          type uint64;
+        }
+
+        leaf unit {
+          description
+            "Unit label to show in the UI";
+          type string;
+          default "vms";
+        }
+
+      }
+
+      container ddio {
+        leaf label {
+          description
+            "Label to show in UI for the param";
+          type string;
+          default "DDIO";
+        }
+
+        leaf vm {
+          description
+            "Number of VMs with the EPA attribute";
+          type uint64;
+        }
+
+        leaf unit {
+          description
+            "Unit label to show in the UI";
+          type string;
+          default "vms";
+        }
+
+      }
+
+      container cat {
+        leaf label {
+          description
+            "Label to show in UI for the param";
+          type string;
+          default "CAT";
+        }
+
+        leaf vm {
+          description
+            "Number of VMs with the EPA attribute";
+          type uint64;
+        }
+
+        leaf unit {
+          description
+            "Unit label to show in the UI";
+          type string;
+          default "vms";
+        }
+      }
+
+      container cmt {
+        leaf label {
+          description
+            "Label to show in UI for the param";
+          type string;
+          default "CMT";
+        }
+
+        leaf vm {
+          description
+            "Number of VMs with the EPA attribute";
+          type uint64;
+        }
+
+        leaf unit {
+          description
+            "Unit label to show in the UI";
+          type string;
+          default "vms";
+        }
+
+      }
+    }
+    uses operational-events;
+  }
+
+  augment /nsr:ns-instance-opdata {
+    uses nsd-ref-count;
+  }
+
+  augment /nsr:ns-instance-opdata/nsr:nsr/nsr:vlr {
+    leaf assigned-subnet {
+      description "Subnet added for the VL";
+      type string;
+    }
+  }
+
+  augment /nsr:ns-instance-config {
+    leaf nfvi-polling-period {
+      description
+        "Defines the period (secons) that the NFVI metrics are polled at";
+      type uint64;
+      default 4;
+    }
+  }
+}
+
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-pb-ext.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-pb-ext.yang.src
new file mode 100755 (executable)
index 0000000..1a3c453
--- /dev/null
@@ -0,0 +1,377 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+
+
+/**
+ * @file rw-pb-ext.yang
+ * @author Tim Mortsolf, Anil Gunturu, Tom Seidenberg
+ * @date 2013/03/21
+ * @brief RiftWare yang to protobuf conversion extensions
+ */
+
+module rw-pb-ext
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-pb-ext";
+  prefix "rwpb";
+
+  revision 2014-03-28 {
+    description
+      "Initial revision.";
+    reference
+      "RIFT yang extensions for converting yang files to Google
+      Protocol Buffers (protobuf) using rift protoc-c extensions.";
+  }
+
+  extension msg-new {
+    argument "typename";
+    description
+      "Generate an equivalent, top-level, protobuf message for this
+      container, list, rpc input, rpc output, or notification.  The
+      argument is the name of the protobuf message type.  Allowed
+      values are valid C identifiers.
+
+      The protobuf definition will only be generated when processing
+      the same module that defines the yang object - a duplicate will
+      not be generated when importing reusing a yang object via uses,
+      or when importing the module.";
+  }
+
+  extension msg-name {
+    argument "typename";
+    description
+      "Change the name of an embedded protobuf message type for this
+      container or list.  Allowed values are valid C identifiers.
+
+      In lieu of this extension, embedded protobuf message typenames
+      are based on the fieldname, and further mangled by removing
+      underscores and CamelCased at underscore boundaries.  This
+      extension allows the automatic mangling procedure to be
+      overridden.
+
+      This extension is incompatible with msg-new, which already
+      defines the typename for top-level messages.  Use this extension
+      solely for embedded messages.";
+  }
+
+  extension msg-flat {
+    argument "selection";
+    description
+      "Set the protobuf message rw_msgopts flat option on a container
+      or list statement.  Allowed values are 'true', 'false', and
+      'auto'.  The default is 'false' for top-level messages, and
+      'auto' for embedded messages.  If 'auto' is specified, the
+      behavior is the same as the enclosing container or list.
+
+      Unless overridden, this extension effectively applies to all
+      enclosed descendent container and list statements.  Flatness will
+      be required by the protobuf compilation step.";
+  }
+
+  extension msg-tag-base {
+    argument "value";
+    description
+      "Specify a base tag value for a container, list, grouping, or
+      uses statement.  Field tags may be specified relative to this
+      base.  Allowed values are positive
+      decimal integers.";
+    // ATTN:  would really like to specify field-relative in uses!
+  }
+
+/*
+  extension msg-tag-reserve {
+    argument "value";
+    description
+      "Reserve space in the tag numbering for future expansion of the
+      enclosing grouping, container, or choice.  Must be a positive
+      decimal integer.  Choose carefully, as you cannot increase the
+      value at a later time.";
+  }
+*/
+
+  extension msg-proto-max-size {
+    argument "value";
+    description
+      "Specify the maximum size of this message in the C structure or
+      so in bytes.  Allowed values are positive decimal integers.";
+  }
+
+  extension msg-typedef {
+    argument "typename";
+    description
+      "Create a prototbuf-c message typedef for the original, base
+      definition of the container, list, grouping, rpc input, rpc
+      output, or notification.  Allowed values are valid C identifiers.
+
+      typename will be appended to the mangeled protobuf package name
+      and an underscore, to ensure name uniqueness across the global
+      schema.
+
+      The typedef will only be generated when processing
+      the same module that defines the yang object - a duplicate will
+      not be generated when importing reusing a yang object via uses,
+      or when importing the module.";
+  }
+
+  extension field-name {
+    argument "fieldname";
+    description
+      "Change the name of the element to fieldname, when converting the
+      object to protobuf.  Allowed values are valid C identifiers.
+
+      In lieu of this extension, element names will be used as-is, if
+      possible, or mangled to fit in the C identifier character space
+      (invalid C identifier characters will be replaced with
+      underscore).  This extension allows the automatic mangling
+      procedure to be overridden.";
+  }
+
+  extension field-inline {
+    argument "selection";
+    description
+      "Set the protobuf field 'inline' option on a container, list,
+      leaf-list, or leaf statement.  Allowed values are 'true',
+      'false', and 'auto'.  If 'auto' is specified, the behavior is
+      controlled by the enclosing container or list's protobuf-msg-flat
+      setting.
+
+      When applied to a container or list statement, this extension is
+      inherited by all enclosed objects, unless overridden.";
+  }
+
+  extension field-inline-max {
+    argument "limit";
+    description
+      "Set the protobuf field 'inline_max' option for list and
+      leaf-list statements.  Allowed values are a positive decimal
+      integer, 'yang', or 'none'.  Example limits:
+
+        '64'
+        'yang'
+        'none'
+
+      If 'none' is specified, then the inline_max protobuf extension
+      will not be used.
+
+      If 'yang' is specified, then the number of elements specified in
+      the yang 'max-elements' statement is used.  If there is no
+      'max-elements' statement, the behavior defaults to 'none'.
+
+      If a decimal integer is specified, that number is used as the
+      maximum length.
+
+      If this extension is not specified, the behavior defaults to
+      'yang'.  Descendant list and leaf-list objects do not inherit
+      this extension.";
+  }
+
+  extension field-string-max {
+    argument "limit";
+    description
+      "Set the protobuf field 'string_max' option for a leaf or
+      leaf-list of type string, binary, leafref, identityref, or
+      instance-identifier.  Allowed values are a positive decimal
+      integer, 'yang', or 'none'.  An optional encoding specifier may
+      also be specified, as octet or utf8, which specifies how
+      characters are counted.  If specified, the encoding must come
+      first.  Example limits:
+
+        'octet 64'
+        'utf8 20'
+        'utf8 yang'
+        'utf8'
+        '128'
+        'none'
+
+      If 'none' is specified, then the string_max protobuf extension
+      will not be used.  'none' cannot be combined with 'octet' or
+      'utf8'.
+
+      If 'yang' is specified, the yang type must be string or binary.
+      If the yang type includes the length statement, then the
+      statements maximum length is used as the length.  Otherwise,
+      behavior defaults to 'none'.
+
+      If a decimal integer is specified, that number is used as the
+      length.
+
+      The encoding specifiers are used to determine the actual number
+      of bytes used in the protobuf extension.  If the 'octet'
+      specifier is used, then the maximum length is used literally as
+      the byte length.  If the 'utf8' specified is used, then the
+      maximum length is considered to be in terms of worst-case UTF-8
+      characters, in which case the protobuf byte length will actually
+      be 4 times the specified length.
+
+      For string and binary types, the default encoding is 'octet'.
+      For the remaining types, the default encoding is 'utf8',
+      reflecting those types fundemental description as XML entities
+      assumed to be encoded in UTF-8.
+
+      If this extension is not specified, then the default is 'yang'
+      for string and binary, and 'none' for the other types.  This
+      extension cannot be specified on aggregate objects, and so it
+      cannot be inherited.";
+  }
+
+  extension field-tag {
+    argument "value";
+    description
+      "Set the protobuf field tag.  Allowed values are a positive
+      decimal integer, 'auto', a base-relative addition expression, or
+      a field-relative addition expression.
+
+      If a decimal integer is specified, then the tag is set to the
+      specified number.  You should avoid using this form in a
+      grouping, because you may not be able to guarantee uniqueness
+      across all the uses of the group.  However, the syntax will be
+      allowed.
+
+      A base-relative addition expression allows the tag of a field to
+      be defined in terms of the base tag of an enclosing grouping,
+      container, list, or uses statement.  The expression has the form
+      '+NUMBER', where NUMBER is the value to add to the base to derive
+      the current field's tag.
+
+      A field-relative addition expression allows the tag of one field
+      to be defined in terms of another field.  The expression has the
+      form 'NAME+NUMBER', where NAME is the name of the other field,
+      and NUMBER is the value to add to the other fields tag to derive
+      the current field's tag.
+
+      If this extension is not specified, the default behavior is
+      'auto'.";
+  }
+
+  extension field-type {
+    argument "type";
+    description
+      "Override the default protobuf field type mapping for a leaf or
+      leaf-list type, and use the specified protobuf type instead.
+
+      Allowed values are any of the Protobuf scalar types, as
+      restricted by the yang leaf type:
+
+      +---------------------------+-------------------------------+
+      | (pseudo) yang leaf type   | (pseudo) protobuf scalar type |
+      |---------------------------+-------------------------------+
+      | int8, int16, int32        | int32, sint32, sfixed32, auto |
+      +---------------------------+-------------------------------+
+      | int64                     | int64, sint64, sfixed64, auto |
+      +---------------------------+-------------------------------+
+      | uint8, uint16, uint32     | uint32, fixed32, auto         |
+      +---------------------------+-------------------------------+
+      | uint64                    | uint64, fixed64, auto         |
+      +---------------------------+-------------------------------+
+      | decimal                   | uint64, sint64, int64,        |
+      |                           | fixed64, sfixed64,            |
+      |                           | float, double, auto           |
+      +---------------------------+-------------------------------+
+      | empty, boolean            | bool, auto                    |
+      +---------------------------+-------------------------------+
+      | string, leafref,          | string, auto                  |
+      | identityref,              |                               |
+      | instance-identifier,      |                               |
+      | anyxml                    |                               |
+      +---------------------------+-------------------------------+
+      | bits, binary              | bytes, auto                   |
+      +---------------------------+-------------------------------+
+
+      If 'auto' is specified, the default conversion will be used.  The
+      protobuf pseudo-type utf8 is equivalent to string, except that
+      length limits will be adjusted in protobuf extentions to allow
+      the string to be composed entirely of the maximum sized UTF-8
+      multibyte characters (byte length is 4 times larger than the
+      character length).";
+  }
+
+  extension field-c-type {
+    argument "type";
+    description
+      "Override the default protoc-c C-language type mapping for a leaf
+      or leaf-list type, and use the specified C type instead.";
+  }
+
+  /* ATTN: Stop using this extension? */
+  extension package-name {
+    argument "pkgname";
+    description
+      "Specifies the name of the package name in the generated .proto
+      file on a module statement The argument is the name of the
+      package-name.  Allowed values are valid C identifiers When
+      package-name is not specified the generated package name defaults
+      to the Yang module name";
+  }
+
+  extension application-request-point {
+    description
+      "This extension is used temporarily until the config and data portions
+       are split into different namespaces and keyspecs. This allows
+       applications to provide data at a keyspec, and request config at a
+       different level";
+  }
+
+  extension enum-name {
+    argument "enumname";
+    description
+      "Use the specified name for the enum enumerator in the .proto
+      instead of the default mangled name of the yang identifer.
+      If there is a name conflict with other enum name either specified
+      explicitly or generated one, the yangpbc conversion will fail.
+      Allowed values are valid C identifiers.";
+  }
+
+  extension enum-type {
+    argument "enumtypename";
+    description
+      "Use the specified name for the enum type in the .proto instead
+      of the default mangled name of the yang identifier.  If there is
+      a name conflict with another enum type, either auto-generated or
+      explicitly specified one, the yangpbc conversion will fail.
+      Allowed values are valid C identifiers.";
+  }
+
+  extension file-pbc-include {
+    argument "pathstring";
+    description
+      "A module level extension to specify the include files for pb-c.h
+      when any rift specific c-types are used.  This extension can
+      occur multiple times as a child of module statement.  The value
+      should be a valid path string.";
+  }
+
+  extension field-merge-behavior {
+    argument "value";
+    description
+      "An extension for controlling the merge done for listy types
+       during upacking of protobuf. It can take 3 different value:
+       
+       1) default: The default is whatever protobuf-c does today 
+          (for keyed lists, the default is equivalent to by-keys).
+
+       2) by-keys: allowed on keyed lists (and leaf-lists): merge 
+          elements with matching key.
+
+       3) none: allowed on keyed lists (and leaf-lists): do not 
+          attempt to merge elements. This must ONLY be used when it 
+          is known or expected that the proto message would contain
+          large number of list items.";
+  }
+
+} // rw-pb-ext
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-topology.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-topology.yang.src
new file mode 100755 (executable)
index 0000000..ff1f2ba
--- /dev/null
@@ -0,0 +1,126 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-topology {
+    namespace "http://riftio.com/ns/riftware-1.0/rw-topology";
+    prefix rw-topology;
+
+    import ietf-inet-types {prefix inet;}
+    import ietf-network {prefix nw;}
+    import ietf-network-topology {prefix nt;}
+    import ietf-l2-topology {prefix l2t;}
+
+    revision "2015-10-20" {
+        description "Initial revision of IP level addressing for L2 host topology";
+    }
+
+    grouping  ip-address-group  {
+      description "IP addresses if present for L2 termination points";
+      container ip-attributes {
+        description "L2 termination points containing IP addresses";
+        list ip-addresses {
+          key ip;
+          leaf ip {
+            type inet:ip-address;
+            description "IPv4 or IPv6 address";
+          }
+        }
+      }
+    } // grouping  ip-address-group
+
+
+    grouping rw-network-attributes {
+      description "RW Topology scope attributes";
+      container rw-network-attributes {
+        description "Containing RW network attributes";
+        leaf name {
+          type string;
+          description "Name of the RW Topology network";
+        }
+        leaf sdn-account-name {
+          type string;
+          description "Name of the SDN account from which topology is got"; 
+        }
+      }
+    }
+
+    grouping  rw-node-attributes {
+      description "RW node attributes";
+      container rw-node-attributes {
+        description "Containing RW node attributes";
+        leaf name {
+          type string;
+          description "Node name";
+        }
+        leaf ovs-bridge-name {
+          type string;
+         description "Name of OVS bridge";
+        } 
+      }
+    }
+
+    grouping rw-link-attributes {
+      description "RW link attributes";
+      container rw-link-attributes {
+        description "Containing RW link attributes";
+        leaf name {
+          type string;
+          description "Link name";
+        }
+      }
+    }
+
+    grouping rw-termination-point-attributes {
+      description "RW termination point attributes";
+      container rw-termination-point-attributes {
+        description "Containing RW TP attributes";
+        leaf description {
+          type string;
+          description "Port description";
+        }
+        uses ip-address-group;
+      }
+    }
+
+    augment "/nw:network" {
+      description
+        "Configuration parameters for the RW network
+         as a whole";
+      uses rw-network-attributes;
+    }
+
+    augment "/nw:network/nw:node" {
+      description
+        "Configuration parameters for RW at the node
+         level";
+      uses rw-node-attributes;
+    }
+
+    augment "/nw:network/nt:link" {
+      description "Augment RW topology link information";
+      uses rw-link-attributes;
+    }
+
+    augment "/nw:network/nw:node/nt:termination-point" {
+      description
+        "Augment RW topology termination point configuration";
+      uses rw-termination-point-attributes;
+    }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-vld.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-vld.yang.src
new file mode 100755 (executable)
index 0000000..5027480
--- /dev/null
@@ -0,0 +1,39 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-vld
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-vld";
+  prefix "rw-vld";
+
+  import vld {
+    prefix "vld";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file augments
+       the base MANO VLD";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+}
+
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-vlr.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-vlr.yang.src
new file mode 100755 (executable)
index 0000000..6a31c43
--- /dev/null
@@ -0,0 +1,72 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-vlr
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-vlr";
+  prefix "rw-vlr";
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import vlr {
+    prefix "vlr";
+  }
+
+  import rw-cloud {
+    prefix "rwcloud";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  revision 2015-09-30 {
+    description
+      "Initial revision. This YANG file augments
+       the base MANO VNFD";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  augment /vlr:vlr-catalog/vlr:vlr {
+    leaf cloud-account {
+      description
+        "The cloud account to use when requesting resources for
+         this vlr";
+      type leafref {
+        path "/rwcloud:cloud/rwcloud:account/rwcloud:name";
+      }
+    }
+
+    leaf network_pool {
+      description "The network pool the resource was allocated from.";
+      type string;
+    }
+
+    leaf assigned-subnet {
+      description "Subnet added for the VL";
+      type string;
+    }
+  }
+}
+
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-vnfd.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-vnfd.yang.src
new file mode 100755 (executable)
index 0000000..7efe069
--- /dev/null
@@ -0,0 +1,117 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-vnfd
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-vnfd";
+  prefix "rw-vnfd";
+
+  import vnfd {
+    prefix "vnfd";
+  }
+
+  import rwvcs-types {
+    prefix "rwvcstypes";
+  }
+
+  import rw-pb-ext { prefix "rwpb"; }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file augments
+       the base MANO VNFD";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  augment /vnfd:vnfd-catalog/vnfd:vnfd {
+    uses manotypes:control-param;
+    uses manotypes:action-param;
+    leaf meta {
+      description
+        "Any meta-data needed by the UI";
+      type string;
+    }
+    list component {
+      description
+          "This section defines the RIFT.ware
+           virtual components";
+      key "component-name";
+      //rwpb:msg-new VcsComponent;
+      //rwpb:application-request-point;
+
+      leaf component-name {
+        description "";
+        type string;
+      }
+
+      leaf component-type {
+        description "";
+        type rwvcstypes:component_type;
+        mandatory true;
+      }
+
+      choice component {
+        case rwvcs-rwcollection {
+          uses rwvcstypes:rwvcs-rwcollection;
+        }
+        case rwvcs-rwvm {
+          uses rwvcstypes:rwvcs-rwvm;
+        }
+        case rwvcs-rwproc {
+          uses rwvcstypes:rwvcs-rwproc;
+        }
+        case native-proc {
+          uses rwvcstypes:native-proc;
+        }
+        case rwvcs-rwtasklet {
+          uses rwvcstypes:rwvcs-rwtasklet;
+        }
+      }
+    } // list component
+  }
+
+  augment /vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu {
+    leaf vcs-component-ref {
+      description
+          "This defines the software components using the
+           RIFT.ware Virtual Component System (VCS). This
+           also allows specifying a state machine during
+           the VM startup.
+           NOTE: This is an significant addition to MANO,
+           since MANO doesn't clearly specify a method to
+           identify various software components in a VM.
+           Also using a state machine is not something that
+           is well described in MANO.";
+      type leafref {
+        path "/vnfd:vnfd-catalog/vnfd:vnfd/rw-vnfd:component/rw-vnfd:component-name";
+      }
+    }
+  }
+}
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-vnfr.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-vnfr.yang.src
new file mode 100755 (executable)
index 0000000..3687a6f
--- /dev/null
@@ -0,0 +1,273 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rw-vnfr
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-vnfr";
+  prefix "rw-vnfr";
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import rw-pb-ext { prefix "rwpb"; }
+
+  import vnfr {
+    prefix "vnfr";
+  }
+
+  import vnfd {
+    prefix "vnfd";
+  }
+
+  import rw-cloud {
+    prefix "rwcloud";
+  }
+
+  import rwvcs-types {
+    prefix "rwvcstypes";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file augments
+       the base MANO VNFD";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  grouping vnfr-operational-events {
+    list operational-events {
+      key "id";
+      description
+        "Recent operational events for VNFR
+        Though the model does not impose any restrictions on the numbe of events,
+        the max operational events will be limited to the most recent 10";
+
+      leaf id {
+        description "The id of the instance";
+        type uint64;
+      }
+
+      leaf timestamp {
+        description
+          "The timestamp of this event expressed as seconds since
+          unix epoch - 1970-01-01T00:00:00Z";
+        type uint32;
+      }
+      leaf event {
+        description "The event";
+        type enumeration {
+          //rwpb:enum-type "VnfrOperationalEvent";
+          enum instantiate-rcvd;
+          enum vl-inited;
+          enum vnf-inited;
+          enum running;
+          enum terminate-rcvd;
+          enum vnf-terminated;
+          enum vl-terminated;
+          enum terminated;
+        }
+      }
+      leaf description {
+        description
+          "The description of this event";
+        type string;
+      }
+    }
+  }
+
+  grouping vdur-operational-events {
+    list operational-events {
+      key "id";
+      description
+        "Recent operational events for VDUR
+        Though the model does not impose any restrictions on the numbe of events,
+        the max operational events will be limited to the most recent 10";
+
+      leaf id {
+        description "The id of the instance";
+        type uint64;
+      }
+
+      leaf timestamp {
+        description
+          "The timestamp of this event expressed as seconds since
+          unix epoch - 1970-01-01T00:00:00Z";
+        type uint32;
+      }
+      leaf event {
+        description "The event";
+        type enumeration {
+          //rwpb:enum-type "VdurOperationalEvent";
+          enum instantiate-rcvd;
+          enum vm-allocation-requested;
+          enum running;
+          enum terminate-rcvd;
+          enum vm-terminate-requested;
+          enum terminated;
+        }
+      }
+      leaf description {
+        description
+          "The description of this event";
+        type string;
+      }
+    }
+  }
+
+  augment /vnfr:vnfr-catalog/vnfr:vnfr {
+    uses manotypes:action-param;
+    uses manotypes:control-param;
+
+    leaf cloud-account {
+      description
+        "The cloud account to use when requesting resources for
+         this vnf";
+      type leafref {
+        path "/rwcloud:cloud/rwcloud:account/rwcloud:name";
+      }
+    }
+
+    container nfvi-metrics {
+      container vm {
+        leaf label {
+          description
+            "Label to show in UI";
+          type string;
+          default "VM";
+        }
+
+        leaf active-vm {
+          description
+            "The number of active VMs.";
+          type uint64;
+        }
+
+        leaf inactive-vm {
+          description
+            "The number of inactive VMs.";
+          type uint64;
+        }
+      }
+
+      uses manotypes:nfvi-metrics;
+    }
+
+    list component {
+      description
+          "This section defines the RIFT.ware
+           virtual components";
+      key "component-name";
+      //rwpb:msg-new VcsComponentOp;
+      //rwpb:application-request-point;
+
+      leaf component-name {
+        description "";
+        type string;
+      }
+
+      leaf component-type {
+        description "";
+        type rwvcstypes:component_type;
+        mandatory true;
+      }
+
+      choice component {
+        case rwvcs-rwcollection {
+          uses rwvcstypes:rwvcs-rwcollection;
+        }
+        case rwvcs-rwvm {
+          uses rwvcstypes:rwvcs-rwvm;
+        }
+        case rwvcs-rwproc {
+          uses rwvcstypes:rwvcs-rwproc;
+        }
+        case native-proc {
+          uses rwvcstypes:native-proc;
+        }
+        case rwvcs-rwtasklet {
+          uses rwvcstypes:rwvcs-rwtasklet;
+        }
+      }
+    } // list component
+    uses vnfr-operational-events;
+  }
+
+  augment /vnfr:vnfr-catalog/vnfr:vnfr/vnfr:vdur {
+    leaf vm-pool {
+      description
+        "The pool from which this vm was allocated from";
+      type string;
+    }
+
+    container nfvi-metrics {
+      uses manotypes:nfvi-metrics;
+    }
+
+    leaf vcs-component-ref {
+      description
+          "This defines the software components using the
+           RIFT.ware Virtual Component System (VCS). This
+           also allows specifying a state machine during
+           the VM startup.
+           NOTE: This is an significant addition to MANO,
+           since MANO doesn't clearly specify a method to
+           identify various software components in a VM.
+           Also using a state machine is not something that
+           is well described in MANO.";
+      type leafref {
+        path "/vnfr:vnfr-catalog/vnfr:vnfr/rw-vnfr:component/rw-vnfr:component-name";
+      }
+    }
+    uses vdur-operational-events;
+  }
+  grouping vnfd-ref-count {
+    list vnfd-ref-count {
+      key "vnfd-id-ref";
+      description "This table maintains the number of VNFRs used by each VNFD";
+
+      leaf vnfd-id-ref {
+        description "Reference to VNFD";
+        type leafref {
+          path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+        }
+      }
+      leaf instance-ref-count {
+        description
+          "Reference count for the number of VNFRs refering this VNFD.
+           Every VNF Record instantiated using this descriptor takes
+           a reference on the VNFD and releases the reference when the
+           virtual network service is terminated. This desciptor cannot
+           be deleted when this counter is non zero";
+        type uint64;
+      }
+    }
+  }
+  augment /vnfr:vnfr-catalog {
+    uses vnfd-ref-count;
+  }
+}
+
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw-yang-types.yang.src b/skyquake/plugins/composer/src/schemas/yang/rw-yang-types.yang.src
new file mode 100755 (executable)
index 0000000..c7eb158
--- /dev/null
@@ -0,0 +1,284 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+
+
+/**
+ * @file rw-yang-types.yang
+ * @author Tom Seidenberg
+ * @date 2014/04/01
+ * @brief RiftWare yang type overrides
+ *
+ * These typedefs exist to allow RiftWare to specify special extensions
+ * to the types.
+ */
+
+module rw-yang-types
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rw-yang-types";
+  prefix "rwt";
+
+  import ietf-inet-types {
+    prefix "inet";
+    revision-date 2013-07-15;
+  }
+
+  import ietf-yang-types {
+    prefix "ietf-yang-types";
+    revision-date 2013-07-15;
+  }
+
+  description
+   "This module contains redefinitions of the ietf-yang-types and
+   ietf-inet-types modules, which allows customized extensions to be
+   defined for these types when used in RiftWare applications.";
+
+  revision 2014-04-01 {
+    description
+      "Initial revision.";
+    reference
+      "RIFT yang types that redefine the IETF types.";
+  }
+
+
+  /* ietf-inet-types */
+
+  typedef ip-version {
+    type inet:ip-version;
+  }
+
+  typedef dscp {
+    type inet:dscp;
+  }
+
+  typedef ipv6-flow-label {
+    type inet:ipv6-flow-label;
+  }
+
+  typedef port-number {
+    type inet:port-number;
+  }
+
+  typedef as-number {
+    type inet:as-number;
+  }
+
+  typedef ip-address {
+    type inet:ip-address;
+  }
+
+  typedef ipv4-address {
+    type inet:ipv4-address;
+  }
+
+  typedef ipv6-address {
+    type inet:ipv6-address;
+  }
+
+  typedef ip-address-no-zone {
+    type inet:ip-address-no-zone;
+  }
+
+  typedef ipv4-address-no-zone {
+    type inet:ipv4-address-no-zone;
+  }
+
+  typedef ipv6-address-no-zone {
+    type inet:ipv6-address-no-zone;
+  }
+
+  typedef ip-prefix {
+    type inet:ip-prefix;
+  }
+
+  typedef ip-prefix-non-canonical {
+    type union {
+      type rwt:ipv4-prefix-non-canonical;
+      type rwt:ipv6-prefix-non-canonical;
+    }
+    description
+      "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type inet:ipv4-prefix;
+  }
+
+  typedef ipv4-prefix-non-canonical {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.";
+  }
+
+  typedef ipv6-prefix {
+    type inet:ipv6-prefix;
+  }
+
+  typedef ipv6-prefix-non-canonical {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-prefix type represents an IPv6 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 128.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The IPv6 address should have all bits that do not belong
+      to the prefix set to zero.";
+  }
+
+
+  typedef domain-name {
+    type inet:domain-name;
+  }
+
+  typedef host {
+    type inet:host;
+  }
+
+  typedef uri {
+    type inet:uri;
+  }
+
+
+  /* ietf-yang-types */
+
+  typedef counter32 {
+    type ietf-yang-types:counter32;
+  }
+
+  typedef zero-based-counter32 {
+    type ietf-yang-types:zero-based-counter32;
+  }
+
+  typedef counter64 {
+    type ietf-yang-types:counter64;
+  }
+
+  typedef zero-based-counter64 {
+    type ietf-yang-types:zero-based-counter64;
+  }
+
+  typedef gauge32 {
+    type ietf-yang-types:gauge32;
+  }
+
+  typedef gauge64 {
+    type ietf-yang-types:gauge64;
+  }
+
+  typedef object-identifier {
+    type ietf-yang-types:object-identifier;
+  }
+
+  typedef object-identifier-128 {
+    type ietf-yang-types:object-identifier-128;
+  }
+
+  typedef yang-identifier {
+    type ietf-yang-types:yang-identifier;
+  }
+
+  typedef date-and-time {
+    type ietf-yang-types:date-and-time;
+  }
+
+  typedef timeticks {
+    type ietf-yang-types:timeticks;
+  }
+
+  typedef timestamp {
+    type ietf-yang-types:timestamp;
+  }
+
+  typedef phys-address {
+    type ietf-yang-types:phys-address;
+  }
+
+  typedef mac-address {
+    type ietf-yang-types:mac-address;
+  }
+
+  typedef xpath1.0 {
+    type ietf-yang-types:xpath1.0;
+  }
+
+  typedef hex-string {
+    type ietf-yang-types:hex-string;
+  }
+
+  typedef uuid {
+    type ietf-yang-types:uuid;
+  }
+
+  typedef dotted-quad {
+    type ietf-yang-types:dotted-quad;
+  }
+
+  typedef call-id {
+    type string {
+      pattern '[0-9]{1,20}:[0-9]{1,20}';
+    }
+  }
+
+  typedef base64-binary {
+    type string {
+      pattern '[0-9a-zA-Z+/]{4,}[=]{0,2}';
+    }
+  }
+  typedef hex-binary {
+    type string {
+      pattern '[0-9A-Fa-f]{2}([0-9A-Fa-f]{2})*';
+    }
+
+  }
+
+  typedef rw-ip-protocol{
+      type enumeration {
+          enum icmp { value 1; }
+          enum tcp  { value 6; }
+          enum udp  { value 17; }
+          enum gre  { value 47; }
+      }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw.nsd-yang.json b/skyquake/plugins/composer/src/schemas/yang/rw.nsd-yang.json
new file mode 100644 (file)
index 0000000..d2f1d34
--- /dev/null
@@ -0,0 +1,3788 @@
+{
+ "synth": "source",
+ "name": "rw-nsd",
+ "schema": {
+  "module": {
+   "rw-nsd": {
+    "namespace": "http://riftio.com/ns/riftware-1.0/rw-nsd",
+    "prefix": "rw-nsd",
+    "import": {
+     "nsd": {
+      "prefix": "nsd"
+     },
+     "ietf-yang-types": {
+      "prefix": "yang"
+     },
+     "mano-types": {
+      "prefix": "manotypes"
+     }
+    },
+    "revision": {
+     "2015-09-10": {
+      "description": "Initial revision. This YANG file augments\nthe base MANO NSD",
+      "reference": "Derived from earlier versions of base YANG files"
+     }
+    },
+    "augment": {
+     "/nsd:nsd-catalog/nsd:nsd": {
+      "uses": {},
+      "leaf": {
+       "meta": {
+        "description": "Any meta-data needed by the UI",
+        "type": "string"
+       },
+       "logo": {
+        "description": "Vendor logo for the Network Service",
+        "type": "string"
+       }
+      },
+      "list": {
+       "control-param": {
+        "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group control parameters",
+          "type": "string"
+         },
+         "min-value": {
+          "description": "Minimum value for the parameter",
+          "type": "uint64"
+         },
+         "max-value": {
+          "description": "Maxium value for the parameter",
+          "type": "uint64"
+         },
+         "current-value": {
+          "description": "Current value for the parameter",
+          "type": "uint64"
+         },
+         "step-value": {
+          "description": "Step value for the parameter",
+          "type": "uint64"
+         },
+         "units": {
+          "type": "string"
+         },
+         "widget-type": {
+          "type": "manotypes:widget-type"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+          "type": "string"
+         }
+        }
+       },
+       "action-param": {
+        "description": "List of action parameters to\ncontrol VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group monitoring parameter",
+          "type": "string"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+          "type": "string"
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "dependencies": {
+  "nsd": {
+   "module": {
+    "nsd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:nsd",
+     "prefix": "nsd",
+     "import": {
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "vld": {
+       "prefix": "vld"
+      },
+      "vnfd": {
+       "prefix": "vnfd"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "mano-types": {
+       "prefix": "manotypes"
+      }
+     },
+     "revision": {
+      "2014-10-27": {
+       "description": "Initial revision. This YANG file defines\nthe Network Service Descriptor (NSD)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "parameter-data-type": {
+       "type": {
+        "enumeration": {
+         "enum": {
+          "string": null,
+          "integer": null,
+          "boolean": null
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "primitive-parameter": {
+       "leaf": {
+        "name": {
+         "description": "Name of the parameter.",
+         "type": "string"
+        },
+        "data-type": {
+         "description": "Data type associated with the name.",
+         "type": "parameter-data-type"
+        },
+        "mandatory": {
+         "description": "Is this field mandatory",
+         "type": "boolean",
+         "default": "false"
+        },
+        "default-value": {
+         "description": "The default value for this field",
+         "type": "string"
+        },
+        "parameter-pool": {
+         "description": "NSD Parameter pool name to use for this paramter",
+         "type": "string"
+        }
+       }
+      },
+      "vnf-configuration": {
+       "container": {
+        "vnf-configuration": {
+         "description": "Information regarding the VNF configuration\nis captured here. Note that if the NS contains\nmultiple instances of the same VNF, each instance\nof the VNF may have different configuration",
+         "leaf": {
+          "config-type": {
+           "description": "Must use this configuration type and fill in only pertaining\nconfig-method below",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "none": null,
+              "netconf": null,
+              "rest": null,
+              "script": null,
+              "juju": null
+             }
+            }
+           }
+          },
+          "config-template": {
+           "description": "Configuration template for each VNF",
+           "type": "string"
+          }
+         },
+         "choice": {
+          "config-method": {
+           "description": "Defines the configuration method for the VNF.",
+           "case": {
+            "netconf": {
+             "description": "Use NETCONF for configuring the VNF.",
+             "container": {
+              "netconf": {
+               "leaf": {
+                "target": {
+                 "description": "Netconf configuration target",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "running": null,
+                    "candidate": null
+                   }
+                  }
+                 }
+                },
+                "protocol": {
+                 "description": "Protocol to use for netconf (e.g. ssh)",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "None": null,
+                    "ssh": null
+                   }
+                  }
+                 }
+                },
+                "port": {
+                 "description": "Port for the netconf server.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            },
+            "rest": {
+             "description": "Use REST for configuring the VNF.",
+             "container": {
+              "rest": {
+               "leaf": {
+                "port": {
+                 "description": "Port for the REST server.",
+                 "type": "inet:port-number"
+                }
+               }
+              }
+             }
+            },
+            "script": {
+             "description": "Use custom script for configuring the VNF.\nThis script is executed in the context of\nOrchestrator.",
+             "container": {
+              "script": {
+               "leaf": {
+                "script-type": {
+                 "description": "Script type - currently supported : bash, expect",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "bash": null,
+                    "expect": null
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "juju": {
+             "description": "Configure the VNF through Juju.",
+             "container": {
+              "juju": {
+               "leaf": {
+                "charm": {
+                 "description": "Juju charm to use with the VNF.",
+                 "type": "string"
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         },
+         "container": {
+          "config-access": {
+           "leaf": {
+            "mgmt-ip-address": {
+             "description": "IP address to be used to configure this VNF,\noptional if it is possible to resolve dynamically.",
+             "type": "inet:ip-address"
+            },
+            "username": {
+             "description": "username for configuration.",
+             "type": "string"
+            },
+            "password": {
+             "description": "Password for configuration access authentication.",
+             "type": "string"
+            }
+           }
+          },
+          "input-params": {
+           "description": "Miscelaneous input parameters to be considered\nwhile processing the NSD to apply configuration",
+           "leaf": {
+            "config-priority": {
+             "description": "Configuration priority - order of confgiration\nto be applied to each VNF in this NS,\nlow number gets precedence over high number",
+             "type": "uint64"
+            },
+            "config-delay": {
+             "description": "Wait (seconds) before applying the configuration to VNF",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "list": {
+          "config-primitive": {
+           "description": "List of configuration primitives supported by the\nconfiguration agent for this VNF.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "description": "List of parameters to the configuration primitive.",
+             "key": "name",
+             "uses": "primitive-parameter"
+            }
+           }
+          },
+          "initial-config-primitive": {
+           "description": "Initial set of configuration primitives.",
+           "key": "seq",
+           "leaf": {
+            "seq": {
+             "description": "Sequence number for the configuration primitive.",
+             "type": "uint64"
+            },
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "key": "name",
+             "leaf": {
+              "name": {
+               "type": "string"
+              },
+              "value": {
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "nsd-catalog": {
+       "list": {
+        "nsd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the NSD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "NSD name.",
+           "mandatory": "true",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "NSD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the NSD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the NSD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the NSD",
+           "type": "string"
+          }
+         },
+         "list": {
+          "connection-point": {
+           "description": "List for external connection points.\nEach NS has one or more external connection\npoints. As the name implies that external\nconnection points are used for connecting\nthe NS to other NS or to external networks.\nEach NS exposes these connection points to\nthe orchestrator. The orchestrator can\nconstruct network service chains by\nconnecting the connection points between\ndifferent NS.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the NS connection point.",
+             "type": "string"
+            },
+            "type": {
+             "description": "Type of the connection point.",
+             "type": "manotypes:connection-point-type"
+            }
+           }
+          },
+          "vld": {
+           "description": "List of Virtual Link Descriptors.",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD.",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Virtual Link Descriptor (VLD) name.",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name for VLD for UI",
+             "type": "string"
+            },
+            "vendor": {
+             "description": "Provider of the VLD.",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VLD.",
+             "type": "string"
+            },
+            "version": {
+             "description": "Version of the VLD",
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "list": {
+            "vnfd-connection-point-ref": {
+             "description": "A list of references to connection points.",
+             "key": "member-vnf-index-ref",
+             "leaf": {
+              "member-vnf-index-ref": {
+               "description": "Reference to member-vnf within constituent-vnfds",
+               "type": {
+                "leafref": {
+                 "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                }
+               }
+              },
+              "vnfd-id-ref": {
+               "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+               "type": "yang:uuid"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "A reference to a connection point name\nin a vnfd. This is a leafref to path:\n    /vnfd:vnfd-catalog/vnfd:vnfd\n    + [vnfd:id = current()/../nsd:vnfd-id-ref]\n    + /vnfd:connection-point/vnfd:name\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+               "type": "string"
+              }
+             }
+            }
+           },
+           "uses": "manotypes:provider-network"
+          },
+          "constituent-vnfd": {
+           "description": "List of VNFDs that are part of this\nnetwork service.",
+           "key": "member-vnf-index",
+           "leaf": {
+            "member-vnf-index": {
+             "description": "Identifier/index for the VNFD. This separate id\nis required to ensure that multiple VNFs can be\npart of single NS",
+             "type": "uint64"
+            },
+            "vnfd-id-ref": {
+             "description": "Identifier for the VNFD.",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            }
+           },
+           "uses": "vnf-configuration"
+          },
+          "vnf-dependency": {
+           "description": "List of VNF dependencies.",
+           "key": "vnf-source-ref",
+           "leaf": {
+            "vnf-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            },
+            "vnf-depends-on-ref": {
+             "description": "Reference to VNF that sorce VNF depends.",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            }
+           }
+          },
+          "vnffgd": {
+           "description": "List of VNF Forwarding Graph Descriptors (VNFFGD).",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VNFFGD.",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "VNFFGD name.",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name for VNFFGD for UI",
+             "type": "string"
+            },
+            "vendor": {
+             "description": "Provider of the VNFFGD.",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VNFFGD.",
+             "type": "string"
+            },
+            "version": {
+             "description": "Version of the VNFFGD",
+             "type": "string"
+            }
+           },
+           "list": {
+            "rsp": {
+             "description": "List of Rendered Service Paths (RSP).",
+             "key": "id",
+             "leaf": {
+              "id": {
+               "description": "Identifier for the RSP.",
+               "type": "yang:uuid"
+              },
+              "name": {
+               "description": "RSP name.",
+               "type": "string"
+              }
+             },
+             "list": {
+              "vnfd-connection-point-ref": {
+               "description": "A list of references to connection points.",
+               "key": "member-vnf-index-ref",
+               "leaf": {
+                "member-vnf-index-ref": {
+                 "description": "Reference to member-vnf within constituent-vnfds",
+                 "type": {
+                  "leafref": {
+                   "path": "../../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                  }
+                 }
+                },
+                "order": {
+                 "type": "uint8",
+                 "description": "A number that denotes the order of a VNF in a chain"
+                },
+                "vnfd-id-ref": {
+                 "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+                 "type": "yang:uuid"
+                },
+                "vnfd-connection-point-ref": {
+                 "description": "A reference to a connection point name\nin a vnfd. This is a leafref to path:\n    /vnfd:vnfd-catalog/vnfd:vnfd\n    + [vnfd:id = current()/../nsd:vnfd-id-ref]\n    + /vnfd:connection-point/vnfd:name\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+                 "type": "string"
+                }
+               },
+               "list": {
+                "classifier": {
+                 "description": "List of classifier rules.",
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "Identifier for the classifier rule.",
+                   "type": "yang:uuid"
+                  },
+                  "name": {
+                   "description": "Name of the classifier.",
+                   "type": "string"
+                  },
+                  "rsp-id-ref": {
+                   "description": "A reference to the RSP.",
+                   "type": {
+                    "leafref": {
+                     "path": "../../nsd:rsp/nsd:id"
+                    }
+                   }
+                  }
+                 },
+                 "container": {
+                  "match-attributes": {
+                   "description": "List of match attributes.",
+                   "leaf": {
+                    "ip-proto": {
+                     "description": "IP Protocol.",
+                     "type": "uint8"
+                    },
+                    "source-ip-address": {
+                     "description": "Source IP address.",
+                     "type": "inet:ip-address"
+                    },
+                    "destination-ip-address": {
+                     "description": "Destination IP address.",
+                     "type": "inet:ip-address"
+                    },
+                    "source-port": {
+                     "description": "Source port number.",
+                     "type": "inet:port-number"
+                    },
+                    "destination-port": {
+                     "description": "Destination port number.",
+                     "type": "inet:port-number"
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          },
+          "parameter-pool": {
+           "description": "Pool of parameter values which must be\npulled from during configuration",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the configuration value pool",
+             "type": "string"
+            }
+           },
+           "container": {
+            "range": {
+             "description": "Create a range of values to populate the pool with",
+             "leaf": {
+              "start-value": {
+               "description": "Generated pool values start at this value",
+               "type": "uint32",
+               "mandatory": "true"
+              },
+              "end-value": {
+               "description": "Generated pool values stop at this value",
+               "type": "uint32",
+               "mandatory": "true"
+              }
+             }
+            }
+           }
+          },
+          "config-primitive": {
+           "description": "Network service level configuration primitives.",
+           "key": "name",
+           "leaf": {
+            "name": {
+             "description": "Name of the configuration primitive.",
+             "type": "string"
+            },
+            "user-defined-script": {
+             "description": "A user defined script.",
+             "type": "string"
+            }
+           },
+           "list": {
+            "parameter": {
+             "description": "List of parameters to the configuration primitive.",
+             "key": "name",
+             "uses": "primitive-parameter"
+            },
+            "parameter-group": {
+             "description": "Grouping of parameters which are logically grouped in UI",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the parameter group",
+               "type": "string"
+              },
+              "mandatory": {
+               "description": "Is this parameter group mandatory",
+               "type": "boolean",
+               "default": "true"
+              }
+             },
+             "list": {
+              "parameter": {
+               "description": "List of parameters to the configuration primitive.",
+               "key": "name",
+               "uses": "primitive-parameter"
+              }
+             }
+            },
+            "vnf-primitive-group": {
+             "description": "List of configuration primitives grouped by VNF.",
+             "key": "member-vnf-index-ref",
+             "leaf": {
+              "member-vnf-index-ref": {
+               "description": "Reference to member-vnf within constituent-vnfds",
+               "type": "uint64"
+              },
+              "vnfd-id-ref": {
+               "description": "A reference to a vnfd. This is a\nleafref to path:\n    ../../../../nsd:constituent-vnfd\n    + [nsd:id = current()/../nsd:id-ref]\n    + /nsd:vnfd-id-ref\nNOTE: An issue with confd is preventing the\nuse of xpath. Seems to be an issue with leafref\nto leafref, whose target is in a different module.\nOnce that is resovled this will switched to use\nleafref",
+               "type": "string"
+              },
+              "vnfd-name": {
+               "description": "Name of the VNFD",
+               "type": "string"
+              }
+             },
+             "list": {
+              "primitive": {
+               "key": "index",
+               "leaf": {
+                "index": {
+                 "description": "Index of this primitive",
+                 "type": "uint32"
+                },
+                "name": {
+                 "description": "Name of the primitive in the VNF primitive ",
+                 "type": "string"
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         },
+         "leaf-list": {
+          "vld-ref": {
+           "type": {
+            "leafref": {
+             "path": "/vld:vld-catalog/vld:vld/vld:id"
+            }
+           }
+          }
+         },
+         "uses": {
+          "manotypes:monitoring-param": null,
+          "manotypes:input-parameter-xpath": null
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "rw-pb-ext": {
+   "module": {
+    "rw-pb-ext": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-pb-ext",
+     "prefix": "rwpb",
+     "revision": {
+      "2014-03-28": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang extensions for converting yang files to Google\nProtocol Buffers (protobuf) using rift protoc-c extensions."
+      }
+     }
+    }
+   }
+  },
+  "vld": {
+   "module": {
+    "vld": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vld",
+     "prefix": "vld",
+     "import": {
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "vnfd": {
+       "prefix": "vnfd"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "mano-types": {
+       "prefix": "manotypes"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Link Descriptor (VLD)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "container": {
+      "vld-catalog": {
+       "list": {
+        "vld": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VLD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "Virtual Link Descriptor (VLD) name.",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "Short name for VLD for UI",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Provider of the VLD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VLD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VLD",
+           "type": "string"
+          },
+          "type": {
+           "type": "manotypes:virtual-link-type"
+          },
+          "root-bandwidth": {
+           "description": "For ELAN this is the aggregate bandwidth.",
+           "type": "uint64"
+          },
+          "leaf-bandwidth": {
+           "description": "For ELAN this is the bandwidth of branches.",
+           "type": "uint64"
+          }
+         },
+         "list": {
+          "vnfd-connection-point-ref": {
+           "description": "A list of references to connection points.",
+           "key": "vnfd-ref member-vnf-index-ref",
+           "leaf": {
+            "vnfd-ref": {
+             "description": "A reference to a vnfd",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            },
+            "member-vnf-index-ref": {
+             "description": "A reference to the consituent-vnfd id in nsd.\nShould have been a leafref to:\n '/nsd:nsd-catalog:/nsd:nsd/constituent-vnfd/member-vnf-index-ref'.\nInstead using direct leaf to avoid circular reference.",
+             "type": "uint64"
+            },
+            "vnfd-connection-point-ref": {
+             "description": "A reference to a connection point name in a vnfd",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id = current()/../vld:vnfd-ref]/vnfd:connection-point/vnfd:name"
+              }
+             }
+            }
+           }
+          }
+         },
+         "container": {
+          "provider-network": {
+           "description": "Container for the provider network.",
+           "leaf": {
+            "physical-network": {
+             "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+             "type": "string"
+            },
+            "overlay-type": {
+             "description": "Type of the overlay network.",
+             "type": {
+              "enumeration": {
+               "enum": {
+                "LOCAL": {
+                 "value": 0
+                },
+                "FLAT": {
+                 "value": 1
+                },
+                "VLAN": {
+                 "value": 2
+                },
+                "VXLAN": {
+                 "value": 3
+                },
+                "GRE": {
+                 "value": 4
+                }
+               }
+              }
+             }
+            },
+            "segmentation_id": {
+             "description": "Segmentation ID",
+             "type": "uint32"
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "vnfd": {
+   "module": {
+    "vnfd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vnfd",
+     "prefix": "vnfd",
+     "import": {
+      "mano-types": {
+       "prefix": "manotypes"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Network Function (VNF)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "grouping": {
+      "virtual-interface": {
+       "container": {
+        "virtual-interface": {
+         "description": "Container for the virtual interface properties",
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "OM-MGMT": {
+               "value": 0
+              },
+              "PCI-PASSTHROUGH": {
+               "value": 1
+              },
+              "SR-IOV": {
+               "value": 2
+              },
+              "VIRTIO": {
+               "value": 3
+              }
+             }
+            }
+           },
+           "default": "VIRTIO"
+          },
+          "vpci": {
+           "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+           "type": "string"
+          },
+          "bandwidth": {
+           "description": "Aggregate bandwidth of the NIC.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "vnfd-catalog": {
+       "description": "Virtual Network Function Descriptor (VNFD).",
+       "list": {
+        "vnfd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VNFD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "VNFD name.",
+           "mandatory": true,
+           "type": "string"
+          },
+          "short-name": {
+           "description": "VNFD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the VNFD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VNFD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VNFD",
+           "type": "string"
+          },
+          "vnf-type": {
+           "description": "Type of VNF.\nNOTE: This needs to map with Service Function Type in ODL to\nsupport VNFFG. Service Function Type is manadatory param in ODL\nSFC. This is temporarily set to string for ease of use",
+           "type": "string"
+          }
+         },
+         "container": {
+          "mgmt-interface": {
+           "description": "Interface over which the VNF is managed.",
+           "choice": {
+            "endpoint-type": {
+             "description": "Indicates the type of management endpoint.",
+             "case": {
+              "ip": {
+               "description": "Specifies the static IP address for managing the VNF.",
+               "leaf": {
+                "ip-address": {
+                 "type": "inet:ip-address"
+                }
+               }
+              },
+              "vdu-id": {
+               "description": "Use the default management interface on this VDU.",
+               "leaf": {
+                "vdu-id": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                  }
+                 }
+                }
+               }
+              },
+              "cp": {
+               "description": "Use the ip address associated with this connection point.",
+               "leaf": {
+                "cp": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "interface-type": {
+             "case": {
+              "netconf": {
+               "leaf": {
+                "netconf": {
+                 "type": "empty"
+                }
+               }
+              }
+             }
+            }
+           },
+           "leaf": {
+            "port": {
+             "description": "Port for the management interface.",
+             "type": "inet:port-number"
+            }
+           },
+           "container": {
+            "dashboard-params": {
+             "description": "Parameters for the VNF dashboard",
+             "leaf": {
+              "path": {
+               "description": "The HTTP path for the dashboard",
+               "type": "string"
+              },
+              "https": {
+               "description": "Pick HTTPS instead of HTTP , Default is false",
+               "type": "boolean"
+              },
+              "port": {
+               "description": "The HTTP port for the dashboard",
+               "type": "inet:port-number"
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "internal-vld": {
+           "key": "id",
+           "description": "List of Internal Virtual Link Descriptors (VLD).\nThe internal VLD describes the basic topology of\nthe connectivity (e.g. E-LAN, E-Line, E-Tree)\nbetween internal VNF components of the system.",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Name of the internal VLD",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the internal VLD",
+             "type": "string"
+            },
+            "description": {
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "leaf-list": {
+            "internal-connection-point-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/internal-connection-point/id"
+              }
+             }
+            }
+           },
+           "container": {
+            "provider-network": {
+             "description": "Container for the provider network.",
+             "leaf": {
+              "physical-network": {
+               "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+               "type": "string"
+              },
+              "overlay-type": {
+               "description": "Type of the overlay network.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "LOCAL": {
+                   "value": 0
+                  },
+                  "FLAT": {
+                   "value": 1
+                  },
+                  "VLAN": {
+                   "value": 2
+                  },
+                  "VXLAN": {
+                   "value": 3
+                  },
+                  "GRE": {
+                   "value": 4
+                  }
+                 }
+                }
+               }
+              },
+              "segmentation_id": {
+               "description": "Segmentation ID",
+               "type": "uint32"
+              }
+             }
+            }
+           }
+          },
+          "connection-point": {
+           "key": "name",
+           "description": "List for external connection points. Each VNF has one\nor more external connection points. As the name\nimplies that external connection points are used for\nconnecting the VNF to other VNFs or to external networks.\nEach VNF exposes these connection points to the\norchestrator. The orchestrator can construct network\nservices by connecting the connection points between\ndifferent VNFs. The NFVO will use VLDs and VNFFGs at\nthe network service level to construct network services.",
+           "leaf": {
+            "name": {
+             "description": "Name of the connection point",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the connection point",
+             "type": "string"
+            },
+            "type": {
+             "description": "Type of the connection point.",
+             "type": "manotypes:connection-point-type"
+            }
+           }
+          },
+          "vdu": {
+           "description": "List of Virtual Deployment Units",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Unique id for the VDU",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Unique name for the VDU",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VDU.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of instances of VDU",
+             "type": "uint64"
+            },
+            "mgmt-vpci": {
+             "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+             "type": "string"
+            },
+            "image": {
+             "description": "Image name for the software image.\nIf the image name is found within the VNF packaage it will\nbe uploaded to all cloud accounts during onboarding process.\nOtherwise, the image must be added to the cloud account with\nthe same name as entered here.\n",
+             "mandatory": true,
+             "type": "string"
+            },
+            "image-checksum": {
+             "description": "Image md5sum for the software image.\nThe md5sum, if provided, along with the image name uniquely\nidentifies an image uploaded to the CAL.\n",
+             "type": "string"
+            },
+            "cloud-init": {
+             "description": "Content of cloud-init script",
+             "type": "string"
+            }
+           },
+           "uses": {},
+           "list": {
+            "internal-connection-point": {
+             "key": "id",
+             "description": "List for internal connection points. Each VNFC\nhas zero or more internal connection points.\nInternal connection points are used for connecting\nthe VNF components internal to the VNF. If a VNF\nhas only one VNFC, it may not have any internal\nconnection points.",
+             "leaf": {
+              "id": {
+               "description": "Identifier for the internal connection points",
+               "type": "yang:uuid"
+              },
+              "type": {
+               "description": "Type of the connection point.",
+               "type": "manotypes:connection-point-type"
+              },
+              "internal-vld-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../internal-vld/id"
+                }
+               }
+              }
+             }
+            },
+            "internal-interface": {
+             "description": "List of internal interfaces for the VNF",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of internal interface. Note that this\nname has only local significance to the VDU.",
+               "type": "string"
+              },
+              "vdu-internal-connection-point-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../internal-connection-point/id"
+                }
+               }
+              }
+             },
+             "container": {
+              "virtual-interface": {
+               "description": "Container for the virtual interface properties",
+               "leaf": {
+                "type": {
+                 "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "OM-MGMT": {
+                     "value": 0
+                    },
+                    "PCI-PASSTHROUGH": {
+                     "value": 1
+                    },
+                    "SR-IOV": {
+                     "value": 2
+                    },
+                    "VIRTIO": {
+                     "value": 3
+                    }
+                   }
+                  }
+                 },
+                 "default": "VIRTIO"
+                },
+                "vpci": {
+                 "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+                 "type": "string"
+                },
+                "bandwidth": {
+                 "description": "Aggregate bandwidth of the NIC.",
+                 "type": "uint64"
+                }
+               }
+              }
+             }
+            },
+            "external-interface": {
+             "description": "List of external interfaces for the VNF.\nThe external interfaces enable sending\ntraffic to and from VNF.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the external interface. Note that\nthis name has only local significance.",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "Name of the external connection point.",
+               "type": {
+                "leafref": {
+                 "path": "../../../connection-point/name"
+                }
+               }
+              }
+             },
+             "container": {
+              "virtual-interface": {
+               "description": "Container for the virtual interface properties",
+               "leaf": {
+                "type": {
+                 "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "OM-MGMT": {
+                     "value": 0
+                    },
+                    "PCI-PASSTHROUGH": {
+                     "value": 1
+                    },
+                    "SR-IOV": {
+                     "value": 2
+                    },
+                    "VIRTIO": {
+                     "value": 3
+                    }
+                   }
+                  }
+                 },
+                 "default": "VIRTIO"
+                },
+                "vpci": {
+                 "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+                 "type": "string"
+                },
+                "bandwidth": {
+                 "description": "Aggregate bandwidth of the NIC.",
+                 "type": "uint64"
+                }
+               }
+              }
+             }
+            }
+           },
+           "container": {
+            "vm-flavor": {
+             "leaf": {
+              "vcpu-count": {
+               "description": "Number of vcpus for the VM.",
+               "type": "uint16"
+              },
+              "memory-mb": {
+               "description": "Amount of memory in MB.",
+               "type": "uint64"
+              },
+              "storage-gb": {
+               "description": "Amount of disk space in GB.",
+               "type": "uint64"
+              }
+             }
+            },
+            "guest-epa": {
+             "leaf": {
+              "trusted-execution": {
+               "description": "This VM should be allocated from trusted pool",
+               "type": "boolean"
+              },
+              "mempage-size": {
+               "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "LARGE": {
+                   "value": 0
+                  },
+                  "SMALL": {
+                   "value": 1
+                  },
+                  "SIZE_2MB": {
+                   "value": 2
+                  },
+                  "SIZE_1GB": {
+                   "value": 3
+                  },
+                  "PREFER_LARGE": {
+                   "value": 4
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-pinning-policy": {
+               "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "DEDICATED": {
+                   "value": 0
+                  },
+                  "SHARED": {
+                   "value": 1
+                  },
+                  "ANY": {
+                   "value": 2
+                  }
+                 }
+                }
+               },
+               "default": "ANY"
+              },
+              "cpu-thread-pinning-policy": {
+               "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "AVOID": {
+                   "value": 0
+                  },
+                  "SEPARATE": {
+                   "value": 1
+                  },
+                  "ISOLATE": {
+                   "value": 2
+                  },
+                  "PREFER": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              }
+             },
+             "list": {
+              "pcie-device": {
+               "description": "List of pcie passthrough devices.",
+               "key": "device-id",
+               "leaf": {
+                "device-id": {
+                 "description": "Device identifier.",
+                 "type": "string"
+                },
+                "count": {
+                 "description": "Number of devices to attach to the VM.",
+                 "type": "uint64"
+                }
+               }
+              }
+             },
+             "choice": {
+              "numa-policy": {
+               "case": {
+                "numa-unware": {
+                 "leaf": {
+                  "numa-unware": {
+                   "type": "empty"
+                  }
+                 }
+                },
+                "numa-aware": {
+                 "container": {
+                  "numa-node-policy": {
+                   "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+                   "leaf": {
+                    "node-cnt": {
+                     "description": "The number of numa nodes to expose to the VM.",
+                     "type": "uint16"
+                    },
+                    "mem-policy": {
+                     "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                     "type": {
+                      "enumeration": {
+                       "enum": {
+                        "STRICT": {
+                         "value": 0
+                        },
+                        "PREFERRED": {
+                         "value": 1
+                        }
+                       }
+                      }
+                     }
+                    }
+                   },
+                   "list": {
+                    "node": {
+                     "key": "id",
+                     "leaf": {
+                      "id": {
+                       "description": "NUMA node identification. Typically\nit's 0 or 1",
+                       "type": "uint64"
+                      },
+                      "memory-mb": {
+                       "description": "Memory size expressed in MB\nfor this NUMA node.",
+                       "type": "uint64"
+                      }
+                     },
+                     "leaf-list": {
+                      "vcpu": {
+                       "description": "List of vcpus to allocate on\nthis numa node.",
+                       "type": "uint64"
+                      }
+                     },
+                     "choice": {
+                      "om-numa-type": {
+                       "description": "Openmano Numa type selection",
+                       "case": {
+                        "cores": {
+                         "leaf": {
+                          "num-cores": {
+                           "type": "uint8"
+                          }
+                         }
+                        },
+                        "paired-threads": {
+                         "container": {
+                          "paired-threads": {
+                           "leaf": {
+                            "num-paired-threads": {
+                             "type": "uint8"
+                            }
+                           },
+                           "list": {
+                            "paired-thread-ids": {
+                             "description": "List of thread pairs to use in case of paired-thread numa",
+                             "max-elements": 16,
+                             "key": "thread-a",
+                             "leaf": {
+                              "thread-a": {
+                               "type": "uint8"
+                              },
+                              "thread-b": {
+                               "type": "uint8"
+                              }
+                             }
+                            }
+                           }
+                          }
+                         }
+                        },
+                        "threads": {
+                         "leaf": {
+                          "num-threads": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "vswitch-epa": {
+             "leaf": {
+              "ovs-acceleration": {
+               "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "MANDATORY": {
+                   "value": 0
+                  },
+                  "PREFERRED": {
+                   "value": 1
+                  },
+                  "DISABLED": {
+                   "value": 2
+                  }
+                 }
+                }
+               }
+              },
+              "ovs-offload": {
+               "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "MANDATORY": {
+                   "value": 0
+                  },
+                  "PREFERRED": {
+                   "value": 1
+                  },
+                  "DISABLED": {
+                   "value": 2
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "hypervisor-epa": {
+             "leaf": {
+              "type": {
+               "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_KVM": {
+                   "value": 0
+                  },
+                  "REQUIRE_KVM": {
+                   "value": 1
+                  }
+                 }
+                }
+               }
+              },
+              "version": {
+               "type": "string"
+              }
+             }
+            },
+            "host-epa": {
+             "description": "Specifies the host level EPA attributes.",
+             "leaf": {
+              "cpu-model": {
+               "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_WESTMERE": {
+                   "value": 0
+                  },
+                  "REQUIRE_WESTMERE": {
+                   "value": 1
+                  },
+                  "PREFER_SANDYBRIDGE": {
+                   "value": 2
+                  },
+                  "REQUIRE_SANDYBRIDGE": {
+                   "value": 3
+                  },
+                  "PREFER_IVYBRIDGE": {
+                   "value": 4
+                  },
+                  "REQUIRE_IVYBRIDGE": {
+                   "value": 5
+                  },
+                  "PREFER_HASWELL": {
+                   "value": 6
+                  },
+                  "REQUIRE_HASWELL": {
+                   "value": 7
+                  },
+                  "PREFER_BROADWELL": {
+                   "value": 8
+                  },
+                  "REQUIRE_BROADWELL": {
+                   "value": 9
+                  },
+                  "PREFER_NEHALEM": {
+                   "value": 10
+                  },
+                  "REQUIRE_NEHALEM": {
+                   "value": 11
+                  },
+                  "PREFER_PENRYN": {
+                   "value": 12
+                  },
+                  "REQUIRE_PENRYN": {
+                   "value": 13
+                  },
+                  "PREFER_CONROE": {
+                   "value": 14
+                  },
+                  "REQUIRE_CONROE": {
+                   "value": 15
+                  },
+                  "PREFER_CORE2DUO": {
+                   "value": 16
+                  },
+                  "REQUIRE_CORE2DUO": {
+                   "value": 17
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-arch": {
+               "description": "Host CPU architecture.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_X86": {
+                   "value": 0
+                  },
+                  "REQUIRE_X86": {
+                   "value": 1
+                  },
+                  "PREFER_X86_64": {
+                   "value": 2
+                  },
+                  "REQUIRE_X86_64": {
+                   "value": 3
+                  },
+                  "PREFER_I686": {
+                   "value": 4
+                  },
+                  "REQUIRE_I686": {
+                   "value": 5
+                  },
+                  "PREFER_IA64": {
+                   "value": 6
+                  },
+                  "REQUIRE_IA64": {
+                   "value": 7
+                  },
+                  "PREFER_ARMV7": {
+                   "value": 8
+                  },
+                  "REQUIRE_ARMV7": {
+                   "value": 9
+                  },
+                  "PREFER_ARMV8": {
+                   "value": 10
+                  },
+                  "REQUIRE_ARMV8": {
+                   "value": 11
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-vendor": {
+               "description": "Host CPU Vendor.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_INTEL": {
+                   "value": 0
+                  },
+                  "REQUIRE_INTEL": {
+                   "value": 1
+                  },
+                  "PREFER_AMD": {
+                   "value": 2
+                  },
+                  "REQUIRE_AMD": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-socket-count": {
+               "description": "Number of sockets on the host.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_ONE": {
+                   "value": 0
+                  },
+                  "PREFER_TWO": {
+                   "value": 1
+                  },
+                  "REQUIRE_ONE": {
+                   "value": 2
+                  },
+                  "REQUIRE_TWO": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-core-count": {
+               "description": "Number of cores on the host.",
+               "type": "uint64"
+              },
+              "om-cpu-model-string": {
+               "description": "Openmano CPU model string",
+               "type": "string"
+              }
+             },
+             "leaf-list": {
+              "cpu-feature": {
+               "description": "List of CPU features.",
+               "type": "manotypes:cpu-feature-type"
+              },
+              "om-cpu-feature": {
+               "description": "Openmano CPU features",
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "vdu-dependency": {
+           "description": "List of VDU dependencies.",
+           "key": "vdu-source-ref",
+           "leaf": {
+            "vdu-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            },
+            "vdu-depends-on-ref": {
+             "description": "Reference to the VDU that\nsource VDU depends.",
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            }
+           }
+          },
+          "http-endpoint": {
+           "description": "List of http endpoints to be used by monitoring params",
+           "key": "path",
+           "leaf": {
+            "path": {
+             "description": "The HTTP path on the management server",
+             "type": "string"
+            },
+            "https": {
+             "description": "Pick HTTPS instead of HTTP , Default is false",
+             "type": "boolean",
+             "default": "false"
+            },
+            "port": {
+             "description": "The HTTP port to connect to",
+             "type": "inet:port-number"
+            },
+            "username": {
+             "description": "The HTTP basic auth username",
+             "type": "string"
+            },
+            "password": {
+             "description": "The HTTP basic auth password",
+             "type": "string"
+            },
+            "polling_interval_secs": {
+             "description": "The HTTP polling interval in seconds",
+             "type": "uint8",
+             "default": "2"
+            },
+            "method": {
+             "description": "This is the method to be performed at the uri.\nGET by default for action",
+             "type": "manotypes:http-method",
+             "default": "GET"
+            }
+           },
+           "list": {
+            "headers": {
+             "description": "Custom HTTP headers to put on HTTP request",
+             "key": "key",
+             "leaf": {
+              "key": {
+               "description": "HTTP header key",
+               "type": "string"
+              },
+              "value": {
+               "description": "HTTP header value",
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "monitoring-param": {
+           "description": "List of monitoring parameters at the NS level",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "type": "string"
+            },
+            "name": {
+             "type": "string"
+            },
+            "http-endpoint-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../http-endpoint/path"
+              }
+             }
+            },
+            "json-query-method": {
+             "type": "manotypes:json-query-method",
+             "default": "NAMEKEY"
+            },
+            "description": {
+             "type": "string"
+            },
+            "group-tag": {
+             "description": "A simple tag to group monitoring parameters",
+             "type": "string"
+            },
+            "value-type": {
+             "type": "manotypes:param-value-type",
+             "default": "INT"
+            },
+            "value-integer": {
+             "description": "Current value for an integer parameter",
+             "type": "int64"
+            },
+            "value-decimal": {
+             "description": "Current value for a decimal parameter",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "4"
+              }
+             }
+            },
+            "value-string": {
+             "description": "Current value for a string parameter",
+             "type": "string"
+            },
+            "widget-type": {
+             "type": "manotypes:widget-type"
+            },
+            "units": {
+             "type": "string"
+            }
+           },
+           "container": {
+            "json-query-params": {
+             "leaf": {
+              "json-path": {
+               "description": "The jsonpath to use to extract value from JSON structure",
+               "type": "string"
+              },
+              "object-path": {
+               "description": "The objectpath to use to extract value from JSON structure",
+               "type": "string"
+              }
+             }
+            },
+            "numeric-constraints": {
+             "leaf": {
+              "min-value": {
+               "description": "Minimum value for the parameter",
+               "type": "uint64"
+              },
+              "max-value": {
+               "description": "Maxium value for the parameter",
+               "type": "uint64"
+              }
+             }
+            },
+            "text-constraints": {
+             "leaf": {
+              "min-length": {
+               "description": "Minimum string length for the parameter",
+               "type": "uint8"
+              },
+              "max-length": {
+               "description": "Maximum string length for the parameter",
+               "type": "uint8"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "mano-types": {
+   "module": {
+    "mano-types": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:mano-types",
+     "prefix": "manotypes",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-04-23": {
+       "description": "Initial revision. This YANG file defines\nthe reusable base types for VNF Management\nand Orchestration (MANO).",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "virtual-link-type": {
+       "description": "Type of virtual link\nELAN: A multipoint service connecting a set of VNFs\n// ELINE: For a simple point to point connection\n//        between a VNF and the existing network.\n// ETREE: A multipoint service connecting one or\n//        more roots and a set of leaves, but\n//        preventing inter-leaf communication.",
+       "type": {
+        "enumeration": {
+         "enum": "ELAN"
+        }
+       }
+      },
+      "http-method": {
+       "description": "Type of HTTP operation",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "POST": {
+           "value": 0
+          },
+          "PUT": {
+           "value": 1
+          },
+          "GET": {
+           "value": 2
+          },
+          "DELETE": {
+           "value": 3
+          },
+          "OPTIONS": {
+           "value": 4
+          },
+          "PATCH": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "api-type": {
+       "description": "Type of API to fetch monitoring params",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HTTP": {
+           "value": 0
+          },
+          "NETCONF": {
+           "value": 1
+          },
+          "SOAP": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "json-query-method": {
+       "description": "The method to extract a value from a JSON response\n\nNAMEKEY - Use the name as the key for a non-nested value.\nJSONPATH - Use jsonpath-rw implemenation to extract a value.\nOBJECTPATH - Use objectpath implemenation to extract a value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NAMEKEY": {
+           "value": 0
+          },
+          "JSONPATH": {
+           "value": 1
+          },
+          "OBJECTPATH": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "param-value-type": {
+       "description": "The type of the parameter value",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "INT": {
+           "value": 0
+          },
+          "DECIMAL": {
+           "value": 1
+          },
+          "STRING": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "connection-point-type": {
+       "description": "Type of connection point\nVPORT: Virtual Port\n// VNIC_ADDR: Virtual NIC Address\n// PNIC_ADDR: Physical NIC Address\n// PPORT: Phsical Port.",
+       "type": {
+        "enumeration": {
+         "enum": "VPORT"
+        }
+       }
+      },
+      "widget-type": {
+       "description": "Type of the widget, typically used by the UI.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HISTOGRAM": {
+           "value": 0
+          },
+          "BAR": {
+           "value": 1
+          },
+          "GAUGE": {
+           "value": 2
+          },
+          "SLIDER": {
+           "value": 3
+          },
+          "COUNTER": {
+           "value": 4
+          },
+          "TEXTBOX": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "cpu-feature-type": {
+       "description": "Enumeration for CPU features.\n\nAES: CPU supports advanced instruction set for\nAES (Advanced Encryption Standard).\n\nCAT: Cache Allocation Technology (CAT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to specify the amount\nof L3 cache (currently the last-level cache\nin most server and client platforms) space an\napplication can fill (as a hint to hardware\nfunctionality, certain features such as power\nmanagement may override CAT settings).\n\nCMT: Cache Monitoring Technology (CMT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to determine the\nusage of cache based on applications running\non the platform. The implementation is\ndirected at L3 cache monitoring (currently\nthe last-level cache in most server and\nclient platforms).\n\nDDIO: Intel Data Direct I/O (DDIO) enables\nEthernet server NICs and controllers talk\ndirectly to the processor cache without a\ndetour via system memory. This enumeration\nspecifies if the VM requires a DDIO\ncapable host.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "PREFER_AES": {
+           "value": 0
+          },
+          "REQUIRE_AES": {
+           "value": 1
+          },
+          "PREFER_CAT": {
+           "value": 2
+          },
+          "REQUIRE_CAT": {
+           "value": 3
+          },
+          "PREFER_CMT": {
+           "value": 4
+          },
+          "REQUIRE_CMT": {
+           "value": 5
+          },
+          "PREFER_DDIO": {
+           "value": 6
+          },
+          "REQUIRE_DDIO": {
+           "value": 7
+          }
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "named-value": {
+       "leaf": {
+        "name": {
+         "type": "string"
+        },
+        "value": {
+         "type": "string"
+        }
+       }
+      },
+      "vm-flavor": {
+       "container": {
+        "vm-flavor": {
+         "leaf": {
+          "vcpu-count": {
+           "description": "Number of vcpus for the VM.",
+           "type": "uint16"
+          },
+          "memory-mb": {
+           "description": "Amount of memory in MB.",
+           "type": "uint64"
+          },
+          "storage-gb": {
+           "description": "Amount of disk space in GB.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      },
+      "vswitch-epa": {
+       "container": {
+        "vswitch-epa": {
+         "leaf": {
+          "ovs-acceleration": {
+           "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          },
+          "ovs-offload": {
+           "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "hypervisor-epa": {
+       "container": {
+        "hypervisor-epa": {
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_KVM": {
+               "value": 0
+              },
+              "REQUIRE_KVM": {
+               "value": 1
+              }
+             }
+            }
+           }
+          },
+          "version": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "host-epa": {
+       "container": {
+        "host-epa": {
+         "description": "Specifies the host level EPA attributes.",
+         "leaf": {
+          "cpu-model": {
+           "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_WESTMERE": {
+               "value": 0
+              },
+              "REQUIRE_WESTMERE": {
+               "value": 1
+              },
+              "PREFER_SANDYBRIDGE": {
+               "value": 2
+              },
+              "REQUIRE_SANDYBRIDGE": {
+               "value": 3
+              },
+              "PREFER_IVYBRIDGE": {
+               "value": 4
+              },
+              "REQUIRE_IVYBRIDGE": {
+               "value": 5
+              },
+              "PREFER_HASWELL": {
+               "value": 6
+              },
+              "REQUIRE_HASWELL": {
+               "value": 7
+              },
+              "PREFER_BROADWELL": {
+               "value": 8
+              },
+              "REQUIRE_BROADWELL": {
+               "value": 9
+              },
+              "PREFER_NEHALEM": {
+               "value": 10
+              },
+              "REQUIRE_NEHALEM": {
+               "value": 11
+              },
+              "PREFER_PENRYN": {
+               "value": 12
+              },
+              "REQUIRE_PENRYN": {
+               "value": 13
+              },
+              "PREFER_CONROE": {
+               "value": 14
+              },
+              "REQUIRE_CONROE": {
+               "value": 15
+              },
+              "PREFER_CORE2DUO": {
+               "value": 16
+              },
+              "REQUIRE_CORE2DUO": {
+               "value": 17
+              }
+             }
+            }
+           }
+          },
+          "cpu-arch": {
+           "description": "Host CPU architecture.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_X86": {
+               "value": 0
+              },
+              "REQUIRE_X86": {
+               "value": 1
+              },
+              "PREFER_X86_64": {
+               "value": 2
+              },
+              "REQUIRE_X86_64": {
+               "value": 3
+              },
+              "PREFER_I686": {
+               "value": 4
+              },
+              "REQUIRE_I686": {
+               "value": 5
+              },
+              "PREFER_IA64": {
+               "value": 6
+              },
+              "REQUIRE_IA64": {
+               "value": 7
+              },
+              "PREFER_ARMV7": {
+               "value": 8
+              },
+              "REQUIRE_ARMV7": {
+               "value": 9
+              },
+              "PREFER_ARMV8": {
+               "value": 10
+              },
+              "REQUIRE_ARMV8": {
+               "value": 11
+              }
+             }
+            }
+           }
+          },
+          "cpu-vendor": {
+           "description": "Host CPU Vendor.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_INTEL": {
+               "value": 0
+              },
+              "REQUIRE_INTEL": {
+               "value": 1
+              },
+              "PREFER_AMD": {
+               "value": 2
+              },
+              "REQUIRE_AMD": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-socket-count": {
+           "description": "Number of sockets on the host.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_ONE": {
+               "value": 0
+              },
+              "PREFER_TWO": {
+               "value": 1
+              },
+              "REQUIRE_ONE": {
+               "value": 2
+              },
+              "REQUIRE_TWO": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-core-count": {
+           "description": "Number of cores on the host.",
+           "type": "uint64"
+          },
+          "om-cpu-model-string": {
+           "description": "Openmano CPU model string",
+           "type": "string"
+          }
+         },
+         "leaf-list": {
+          "cpu-feature": {
+           "description": "List of CPU features.",
+           "type": "manotypes:cpu-feature-type"
+          },
+          "om-cpu-feature": {
+           "description": "Openmano CPU features",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "guest-epa": {
+       "description": "EPA attributes for the guest",
+       "container": {
+        "guest-epa": {
+         "leaf": {
+          "trusted-execution": {
+           "description": "This VM should be allocated from trusted pool",
+           "type": "boolean"
+          },
+          "mempage-size": {
+           "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LARGE": {
+               "value": 0
+              },
+              "SMALL": {
+               "value": 1
+              },
+              "SIZE_2MB": {
+               "value": 2
+              },
+              "SIZE_1GB": {
+               "value": 3
+              },
+              "PREFER_LARGE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "cpu-pinning-policy": {
+           "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "DEDICATED": {
+               "value": 0
+              },
+              "SHARED": {
+               "value": 1
+              },
+              "ANY": {
+               "value": 2
+              }
+             }
+            }
+           },
+           "default": "ANY"
+          },
+          "cpu-thread-pinning-policy": {
+           "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "AVOID": {
+               "value": 0
+              },
+              "SEPARATE": {
+               "value": 1
+              },
+              "ISOLATE": {
+               "value": 2
+              },
+              "PREFER": {
+               "value": 3
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "pcie-device": {
+           "description": "List of pcie passthrough devices.",
+           "key": "device-id",
+           "leaf": {
+            "device-id": {
+             "description": "Device identifier.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of devices to attach to the VM.",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "choice": {
+          "numa-policy": {
+           "case": {
+            "numa-unware": {
+             "leaf": {
+              "numa-unware": {
+               "type": "empty"
+              }
+             }
+            },
+            "numa-aware": {
+             "container": {
+              "numa-node-policy": {
+               "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+               "leaf": {
+                "node-cnt": {
+                 "description": "The number of numa nodes to expose to the VM.",
+                 "type": "uint16"
+                },
+                "mem-policy": {
+                 "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "STRICT": {
+                     "value": 0
+                    },
+                    "PREFERRED": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               },
+               "list": {
+                "node": {
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "NUMA node identification. Typically\nit's 0 or 1",
+                   "type": "uint64"
+                  },
+                  "memory-mb": {
+                   "description": "Memory size expressed in MB\nfor this NUMA node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "leaf-list": {
+                  "vcpu": {
+                   "description": "List of vcpus to allocate on\nthis numa node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "choice": {
+                  "om-numa-type": {
+                   "description": "Openmano Numa type selection",
+                   "case": {
+                    "cores": {
+                     "leaf": {
+                      "num-cores": {
+                       "type": "uint8"
+                      }
+                     }
+                    },
+                    "paired-threads": {
+                     "container": {
+                      "paired-threads": {
+                       "leaf": {
+                        "num-paired-threads": {
+                         "type": "uint8"
+                        }
+                       },
+                       "list": {
+                        "paired-thread-ids": {
+                         "description": "List of thread pairs to use in case of paired-thread numa",
+                         "max-elements": 16,
+                         "key": "thread-a",
+                         "leaf": {
+                          "thread-a": {
+                           "type": "uint8"
+                          },
+                          "thread-b": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "threads": {
+                     "leaf": {
+                      "num-threads": {
+                       "type": "uint8"
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "provider-network": {
+       "container": {
+        "provider-network": {
+         "description": "Container for the provider network.",
+         "leaf": {
+          "physical-network": {
+           "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+           "type": "string"
+          },
+          "overlay-type": {
+           "description": "Type of the overlay network.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LOCAL": {
+               "value": 0
+              },
+              "FLAT": {
+               "value": 1
+              },
+              "VLAN": {
+               "value": 2
+              },
+              "VXLAN": {
+               "value": 3
+              },
+              "GRE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "segmentation_id": {
+           "description": "Segmentation ID",
+           "type": "uint32"
+          }
+         }
+        }
+       }
+      },
+      "monitoring-param": {
+       "list": {
+        "http-endpoint": {
+         "description": "List of http endpoints to be used by monitoring params",
+         "key": "path",
+         "leaf": {
+          "path": {
+           "description": "The HTTP path on the management server",
+           "type": "string"
+          },
+          "https": {
+           "description": "Pick HTTPS instead of HTTP , Default is false",
+           "type": "boolean",
+           "default": "false"
+          },
+          "port": {
+           "description": "The HTTP port to connect to",
+           "type": "inet:port-number"
+          },
+          "username": {
+           "description": "The HTTP basic auth username",
+           "type": "string"
+          },
+          "password": {
+           "description": "The HTTP basic auth password",
+           "type": "string"
+          },
+          "polling_interval_secs": {
+           "description": "The HTTP polling interval in seconds",
+           "type": "uint8",
+           "default": "2"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nGET by default for action",
+           "type": "manotypes:http-method",
+           "default": "GET"
+          }
+         },
+         "list": {
+          "headers": {
+           "description": "Custom HTTP headers to put on HTTP request",
+           "key": "key",
+           "leaf": {
+            "key": {
+             "description": "HTTP header key",
+             "type": "string"
+            },
+            "value": {
+             "description": "HTTP header value",
+             "type": "string"
+            }
+           }
+          }
+         }
+        },
+        "monitoring-param": {
+         "description": "List of monitoring parameters at the NS level",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "http-endpoint-ref": {
+           "type": {
+            "leafref": {
+             "path": "../../http-endpoint/path"
+            }
+           }
+          },
+          "json-query-method": {
+           "type": "manotypes:json-query-method",
+           "default": "NAMEKEY"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameters",
+           "type": "string"
+          },
+          "value-type": {
+           "type": "manotypes:param-value-type",
+           "default": "INT"
+          },
+          "value-integer": {
+           "description": "Current value for an integer parameter",
+           "type": "int64"
+          },
+          "value-decimal": {
+           "description": "Current value for a decimal parameter",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "4"
+            }
+           }
+          },
+          "value-string": {
+           "description": "Current value for a string parameter",
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "units": {
+           "type": "string"
+          }
+         },
+         "container": {
+          "json-query-params": {
+           "leaf": {
+            "json-path": {
+             "description": "The jsonpath to use to extract value from JSON structure",
+             "type": "string"
+            },
+            "object-path": {
+             "description": "The objectpath to use to extract value from JSON structure",
+             "type": "string"
+            }
+           }
+          },
+          "numeric-constraints": {
+           "leaf": {
+            "min-value": {
+             "description": "Minimum value for the parameter",
+             "type": "uint64"
+            },
+            "max-value": {
+             "description": "Maxium value for the parameter",
+             "type": "uint64"
+            }
+           }
+          },
+          "text-constraints": {
+           "leaf": {
+            "min-length": {
+             "description": "Minimum string length for the parameter",
+             "type": "uint8"
+            },
+            "max-length": {
+             "description": "Maximum string length for the parameter",
+             "type": "uint8"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "control-param": {
+       "list": {
+        "control-param": {
+         "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group control parameters",
+           "type": "string"
+          },
+          "min-value": {
+           "description": "Minimum value for the parameter",
+           "type": "uint64"
+          },
+          "max-value": {
+           "description": "Maxium value for the parameter",
+           "type": "uint64"
+          },
+          "current-value": {
+           "description": "Current value for the parameter",
+           "type": "uint64"
+          },
+          "step-value": {
+           "description": "Step value for the parameter",
+           "type": "uint64"
+          },
+          "units": {
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-param": {
+       "list": {
+        "action-param": {
+         "description": "List of action parameters to\ncontrol VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameter",
+           "type": "string"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter": {
+       "description": "",
+       "list": {
+        "input-parameter": {
+         "description": "List of input parameters",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          },
+          "value": {
+           "description": "The value that the element specified by the xpath should take when a\nrecord is created.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter-xpath": {
+       "list": {
+        "input-parameter-xpath": {
+         "description": "List of xpaths to parameters inside the NSD\nthe can be customized during the instantiation.",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "An xpath that specifies the element in a descriptor.",
+           "type": "string"
+          },
+          "label": {
+           "description": "A descriptive string",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "nfvi-metrics": {
+       "container": {
+        "vcpu": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "VCPU"
+          },
+          "total": {
+           "description": "The total number of VCPUs available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The VCPU utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "memory": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "MEMORY"
+          },
+          "used": {
+           "description": "The amount of memory (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of memory (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The memory utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "storage": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "STORAGE"
+          },
+          "used": {
+           "description": "The amount of storage (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of storage (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The storage utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "external-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "EXTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of external ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "internal-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "INTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of internal ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "network": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "NETWORK TRAFFIC"
+          }
+         },
+         "container": {
+          "incoming": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "INCOMING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of incoming bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of incoming packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current incoming byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current incoming packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          },
+          "outgoing": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "OUTGOING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of outgoing bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of outgoing packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current outgoing byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current outgoing packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "pkgdir": "/Users/onvelocity/rift-composer/webapp/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw.vld-yang.json b/skyquake/plugins/composer/src/schemas/yang/rw.vld-yang.json
new file mode 100644 (file)
index 0000000..6cc4bd3
--- /dev/null
@@ -0,0 +1,2936 @@
+{
+ "synth": "source",
+ "name": "rw-vld",
+ "schema": {
+  "module": {
+   "rw-vld": {
+    "namespace": "http://riftio.com/ns/riftware-1.0/rw-vld",
+    "prefix": "rw-vld",
+    "import": {
+     "vld": {
+      "prefix": "vld"
+     }
+    },
+    "revision": {
+     "2015-09-10": {
+      "description": "Initial revision. This YANG file augments\nthe base MANO VLD",
+      "reference": "Derived from earlier versions of base YANG files"
+     }
+    }
+   }
+  }
+ },
+ "dependencies": {
+  "vld": {
+   "module": {
+    "vld": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vld",
+     "prefix": "vld",
+     "import": {
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "vnfd": {
+       "prefix": "vnfd"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "mano-types": {
+       "prefix": "manotypes"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Link Descriptor (VLD)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "container": {
+      "vld-catalog": {
+       "list": {
+        "vld": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VLD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "Virtual Link Descriptor (VLD) name.",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "Short name for VLD for UI",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Provider of the VLD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VLD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VLD",
+           "type": "string"
+          },
+          "type": {
+           "type": "manotypes:virtual-link-type"
+          },
+          "root-bandwidth": {
+           "description": "For ELAN this is the aggregate bandwidth.",
+           "type": "uint64"
+          },
+          "leaf-bandwidth": {
+           "description": "For ELAN this is the bandwidth of branches.",
+           "type": "uint64"
+          }
+         },
+         "list": {
+          "vnfd-connection-point-ref": {
+           "description": "A list of references to connection points.",
+           "key": "vnfd-ref member-vnf-index-ref",
+           "leaf": {
+            "vnfd-ref": {
+             "description": "A reference to a vnfd",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+              }
+             }
+            },
+            "member-vnf-index-ref": {
+             "description": "A reference to the consituent-vnfd id in nsd.\nShould have been a leafref to:\n '/nsd:nsd-catalog:/nsd:nsd/constituent-vnfd/member-vnf-index-ref'.\nInstead using direct leaf to avoid circular reference.",
+             "type": "uint64"
+            },
+            "vnfd-connection-point-ref": {
+             "description": "A reference to a connection point name in a vnfd",
+             "type": {
+              "leafref": {
+               "path": "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id = current()/../vld:vnfd-ref]/vnfd:connection-point/vnfd:name"
+              }
+             }
+            }
+           }
+          }
+         },
+         "uses": "manotypes:provider-network"
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "rw-pb-ext": {
+   "module": {
+    "rw-pb-ext": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-pb-ext",
+     "prefix": "rwpb",
+     "revision": {
+      "2014-03-28": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang extensions for converting yang files to Google\nProtocol Buffers (protobuf) using rift protoc-c extensions."
+      }
+     }
+    }
+   }
+  },
+  "vnfd": {
+   "module": {
+    "vnfd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vnfd",
+     "prefix": "vnfd",
+     "import": {
+      "mano-types": {
+       "prefix": "manotypes"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Network Function (VNF)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "grouping": {
+      "virtual-interface": {
+       "container": {
+        "virtual-interface": {
+         "description": "Container for the virtual interface properties",
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "OM-MGMT": {
+               "value": 0
+              },
+              "PCI-PASSTHROUGH": {
+               "value": 1
+              },
+              "SR-IOV": {
+               "value": 2
+              },
+              "VIRTIO": {
+               "value": 3
+              }
+             }
+            }
+           },
+           "default": "VIRTIO"
+          },
+          "vpci": {
+           "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+           "type": "string"
+          },
+          "bandwidth": {
+           "description": "Aggregate bandwidth of the NIC.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "vnfd-catalog": {
+       "description": "Virtual Network Function Descriptor (VNFD).",
+       "list": {
+        "vnfd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VNFD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "VNFD name.",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "VNFD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the VNFD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VNFD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VNFD",
+           "type": "string"
+          }
+         },
+         "container": {
+          "mgmt-interface": {
+           "description": "Interface over which the VNF is managed.",
+           "choice": {
+            "endpoint-type": {
+             "description": "Indicates the type of management endpoint.",
+             "case": {
+              "ip": {
+               "description": "Specifies the static IP address for managing the VNF.",
+               "leaf": {
+                "ip-address": {
+                 "type": "inet:ip-address"
+                }
+               }
+              },
+              "vdu-id": {
+               "description": "Use the default management interface on this VDU.",
+               "leaf": {
+                "vdu-id": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                  }
+                 }
+                }
+               }
+              },
+              "cp": {
+               "description": "Use the ip address associated with this connection point.",
+               "leaf": {
+                "cp": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "interface-type": {
+             "case": {
+              "netconf": {
+               "leaf": {
+                "netconf": {
+                 "type": "empty"
+                }
+               }
+              }
+             }
+            }
+           },
+           "leaf": {
+            "port": {
+             "description": "Port for the management interface.",
+             "type": "inet:port-number"
+            }
+           },
+           "container": {
+            "dashboard-params": {
+             "description": "Parameters for the VNF dashboard",
+             "leaf": {
+              "path": {
+               "description": "The HTTP path for the dashboard",
+               "type": "string"
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "internal-vld": {
+           "key": "id",
+           "description": "List of Internal Virtual Link Descriptors (VLD).\nThe internal VLD describes the basic topology of\nthe connectivity (e.g. E-LAN, E-Line, E-Tree)\nbetween internal VNF components of the system.",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Name of the internal VLD",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the internal VLD",
+             "type": "string"
+            },
+            "description": {
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "leaf-list": {
+            "internal-connection-point-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/internal-connection-point/id"
+              }
+             }
+            }
+           },
+           "container": {
+            "provider-network": {
+             "description": "Container for the provider network.",
+             "leaf": {
+              "name": {
+               "description": "Name of the provider network.",
+               "type": "string"
+              },
+              "physical-network": {
+               "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+               "type": "string"
+              },
+              "overlay-type": {
+               "description": "Type of the overlay network.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "LOCAL": {
+                   "value": 0
+                  },
+                  "FLAT": {
+                   "value": 1
+                  },
+                  "VLAN": {
+                   "value": 2
+                  },
+                  "VXLAN": {
+                   "value": 3
+                  },
+                  "GRE": {
+                   "value": 4
+                  }
+                 }
+                }
+               }
+              },
+              "segmentation_id": {
+               "description": "Segmentation ID",
+               "type": "uint32"
+              }
+             }
+            }
+           }
+          },
+          "connection-point": {
+           "key": "name",
+           "description": "List for external connection points. Each VNF has one\nor more external connection points. As the name\nimplies that external connection points are used for\nconnecting the VNF to other VNFs or to external networks.\nEach VNF exposes these connection points to the\norchestrator. The orchestrator can construct network\nservices by connecting the connection points between\ndifferent VNFs. The NFVO will use VLDs and VNFFGs at\nthe network service level to construct network services.",
+           "leaf": {
+            "name": {
+             "description": "Name of the connection point",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the connection point",
+             "type": "string"
+            },
+            "type": {
+             "description": "Type of the connection point.",
+             "type": "manotypes:connection-point-type"
+            }
+           }
+          },
+          "vdu": {
+           "description": "List of Virtual Deployment Units",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Unique id for the VDU",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Unique name for the VDU",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VDU.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of instances of VDU",
+             "type": "uint64"
+            },
+            "mgmt-vpci": {
+             "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+             "type": "string"
+            },
+            "image": {
+             "description": "File/URL path to the software image",
+             "type": "string"
+            },
+            "cloud-init": {
+             "description": "Content of cloud-init script",
+             "type": "string"
+            }
+           },
+           "uses": {},
+           "list": {
+            "internal-connection-point": {
+             "key": "id",
+             "description": "List for internal connection points. Each VNFC\nhas zero or more internal connection points.\nInternal connection points are used for connecting\nthe VNF components internal to the VNF. If a VNF\nhas only one VNFC, it may not have any internal\nconnection points.",
+             "leaf": {
+              "id": {
+               "description": "Identifier for the internal connection points",
+               "type": "yang:uuid"
+              },
+              "type": {
+               "description": "Type of the connection point.",
+               "type": "manotypes:connection-point-type"
+              },
+              "internal-vld-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../internal-vld/id"
+                }
+               }
+              }
+             }
+            },
+            "internal-interface": {
+             "description": "List of internal interfaces for the VNF",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of internal interface. Note that this\nname has only local significance to the VDU.",
+               "type": "string"
+              },
+              "vdu-internal-connection-point-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../internal-connection-point/id"
+                }
+               }
+              }
+             },
+             "container": {
+              "virtual-interface": {
+               "description": "Container for the virtual interface properties",
+               "leaf": {
+                "type": {
+                 "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "OM-MGMT": {
+                     "value": 0
+                    },
+                    "PCI-PASSTHROUGH": {
+                     "value": 1
+                    },
+                    "SR-IOV": {
+                     "value": 2
+                    },
+                    "VIRTIO": {
+                     "value": 3
+                    }
+                   }
+                  }
+                 },
+                 "default": "VIRTIO"
+                },
+                "vpci": {
+                 "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+                 "type": "string"
+                },
+                "bandwidth": {
+                 "description": "Aggregate bandwidth of the NIC.",
+                 "type": "uint64"
+                }
+               }
+              }
+             }
+            },
+            "external-interface": {
+             "description": "List of external interfaces for the VNF.\nThe external interfaces enable sending\ntraffic to and from VNF.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the external interface. Note that\nthis name has only local significance.",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "Name of the external connection point.",
+               "type": {
+                "leafref": {
+                 "path": "../../../connection-point/name"
+                }
+               }
+              }
+             },
+             "container": {
+              "virtual-interface": {
+               "description": "Container for the virtual interface properties",
+               "leaf": {
+                "type": {
+                 "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "OM-MGMT": {
+                     "value": 0
+                    },
+                    "PCI-PASSTHROUGH": {
+                     "value": 1
+                    },
+                    "SR-IOV": {
+                     "value": 2
+                    },
+                    "VIRTIO": {
+                     "value": 3
+                    }
+                   }
+                  }
+                 },
+                 "default": "VIRTIO"
+                },
+                "vpci": {
+                 "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+                 "type": "string"
+                },
+                "bandwidth": {
+                 "description": "Aggregate bandwidth of the NIC.",
+                 "type": "uint64"
+                }
+               }
+              }
+             }
+            }
+           },
+           "container": {
+            "vm-flavor": {
+             "leaf": {
+              "vcpu-count": {
+               "description": "Number of vcpus for the VM.",
+               "type": "uint16"
+              },
+              "memory-mb": {
+               "description": "Amount of memory in MB.",
+               "type": "uint64"
+              },
+              "storage-gb": {
+               "description": "Amount of disk space in GB.",
+               "type": "uint64"
+              }
+             }
+            },
+            "guest-epa": {
+             "leaf": {
+              "trusted-execution": {
+               "description": "This VM should be allocated from trusted pool",
+               "type": "boolean"
+              },
+              "mempage-size": {
+               "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "LARGE": {
+                   "value": 0
+                  },
+                  "SMALL": {
+                   "value": 1
+                  },
+                  "SIZE_2MB": {
+                   "value": 2
+                  },
+                  "SIZE_1GB": {
+                   "value": 3
+                  },
+                  "PREFER_LARGE": {
+                   "value": 4
+                  }
+                 }
+                }
+               },
+               "default": "SMALL"
+              },
+              "cpu-pinning-policy": {
+               "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "DEDICATED": {
+                   "value": 0
+                  },
+                  "SHARED": {
+                   "value": 1
+                  },
+                  "ANY": {
+                   "value": 2
+                  }
+                 }
+                }
+               },
+               "default": "ANY"
+              },
+              "cpu-thread-pinning-policy": {
+               "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "AVOID": {
+                   "value": 0
+                  },
+                  "SEPARATE": {
+                   "value": 1
+                  },
+                  "ISOLATE": {
+                   "value": 2
+                  },
+                  "PREFER": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              }
+             },
+             "list": {
+              "pcie-device": {
+               "description": "List of pcie passthrough devices.",
+               "key": "device-id",
+               "leaf": {
+                "device-id": {
+                 "description": "Device identifier.",
+                 "type": "string"
+                },
+                "count": {
+                 "description": "Number of devices to attach to the VM.",
+                 "type": "uint64"
+                }
+               }
+              }
+             },
+             "choice": {
+              "numa-policy": {
+               "case": {
+                "numa-unware": {
+                 "leaf": {
+                  "numa-unware": {
+                   "type": "empty"
+                  }
+                 }
+                },
+                "numa-aware": {
+                 "container": {
+                  "numa-node-policy": {
+                   "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+                   "leaf": {
+                    "node-cnt": {
+                     "description": "The number of numa nodes to expose to the VM.",
+                     "type": "uint16"
+                    },
+                    "mem-policy": {
+                     "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                     "type": {
+                      "enumeration": {
+                       "enum": {
+                        "STRICT": {
+                         "value": 0
+                        },
+                        "PREFERRED": {
+                         "value": 1
+                        }
+                       }
+                      }
+                     }
+                    }
+                   },
+                   "list": {
+                    "node": {
+                     "key": "id",
+                     "leaf": {
+                      "id": {
+                       "description": "NUMA node identification. Typically\nit's 0 or 1",
+                       "type": "uint64"
+                      },
+                      "memory-mb": {
+                       "description": "Memory size expressed in MB\nfor this NUMA node.",
+                       "type": "uint64"
+                      }
+                     },
+                     "leaf-list": {
+                      "vcpu": {
+                       "description": "List of vcpus to allocate on\nthis numa node.",
+                       "type": "uint64"
+                      }
+                     },
+                     "choice": {
+                      "om-numa-type": {
+                       "description": "Openmano Numa type selection",
+                       "case": {
+                        "cores": {
+                         "leaf": {
+                          "num-cores": {
+                           "type": "uint8"
+                          }
+                         }
+                        },
+                        "paired-threads": {
+                         "container": {
+                          "paired-threads": {
+                           "leaf": {
+                            "num-paired-threads": {
+                             "type": "uint8"
+                            }
+                           },
+                           "list": {
+                            "paired-thread-ids": {
+                             "description": "List of thread pairs to use in case of paired-thread numa",
+                             "key": "thread-a",
+                             "leaf": {
+                              "thread-a": {
+                               "type": "uint8"
+                              },
+                              "thread-b": {
+                               "type": "uint8"
+                              }
+                             }
+                            }
+                           }
+                          }
+                         }
+                        },
+                        "threads": {
+                         "leaf": {
+                          "num-threads": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "vswitch-epa": {
+             "leaf": {
+              "ovs-acceleration": {
+               "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "MANDATORY": {
+                   "value": 0
+                  },
+                  "PREFERRED": {
+                   "value": 1
+                  },
+                  "DISABLED": {
+                   "value": 2
+                  }
+                 }
+                }
+               }
+              },
+              "ovs-offload": {
+               "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "MANDATORY": {
+                   "value": 0
+                  },
+                  "PREFERRED": {
+                   "value": 1
+                  },
+                  "DISABLED": {
+                   "value": 2
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "hypervisor-epa": {
+             "leaf": {
+              "type": {
+               "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_KVM": {
+                   "value": 0
+                  },
+                  "REQUIRE_KVM": {
+                   "value": 1
+                  }
+                 }
+                }
+               }
+              },
+              "version": {
+               "type": "string"
+              }
+             }
+            },
+            "host-epa": {
+             "description": "Specifies the host level EPA attributes.",
+             "leaf": {
+              "cpu-model": {
+               "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_WESTMERE": {
+                   "value": 0
+                  },
+                  "REQUIRE_WESTMERE": {
+                   "value": 1
+                  },
+                  "PREFER_SANDYBRIDGE": {
+                   "value": 2
+                  },
+                  "REQUIRE_SANDYBRIDGE": {
+                   "value": 3
+                  },
+                  "PREFER_IVYBRIDGE": {
+                   "value": 4
+                  },
+                  "REQUIRE_IVYBRIDGE": {
+                   "value": 5
+                  },
+                  "PREFER_HASWELL": {
+                   "value": 6
+                  },
+                  "REQUIRE_HASWELL": {
+                   "value": 7
+                  },
+                  "PREFER_BROADWELL": {
+                   "value": 8
+                  },
+                  "REQUIRE_BROADWELL": {
+                   "value": 9
+                  },
+                  "PREFER_NEHALEM": {
+                   "value": 10
+                  },
+                  "REQUIRE_NEHALEM": {
+                   "value": 11
+                  },
+                  "PREFER_PENRYN": {
+                   "value": 12
+                  },
+                  "REQUIRE_PENRYN": {
+                   "value": 13
+                  },
+                  "PREFER_CONROE": {
+                   "value": 14
+                  },
+                  "REQUIRE_CONROE": {
+                   "value": 15
+                  },
+                  "PREFER_CORE2DUO": {
+                   "value": 16
+                  },
+                  "REQUIRE_CORE2DUO": {
+                   "value": 17
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-arch": {
+               "description": "Host CPU architecture.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_X86": {
+                   "value": 0
+                  },
+                  "REQUIRE_X86": {
+                   "value": 1
+                  },
+                  "PREFER_X86_64": {
+                   "value": 2
+                  },
+                  "REQUIRE_X86_64": {
+                   "value": 3
+                  },
+                  "PREFER_I686": {
+                   "value": 4
+                  },
+                  "REQUIRE_I686": {
+                   "value": 5
+                  },
+                  "PREFER_IA64": {
+                   "value": 6
+                  },
+                  "REQUIRE_IA64": {
+                   "value": 7
+                  },
+                  "PREFER_ARMV7": {
+                   "value": 8
+                  },
+                  "REQUIRE_ARMV7": {
+                   "value": 9
+                  },
+                  "PREFER_ARMV8": {
+                   "value": 10
+                  },
+                  "REQUIRE_ARMV8": {
+                   "value": 11
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-vendor": {
+               "description": "Host CPU Vendor.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_INTEL": {
+                   "value": 0
+                  },
+                  "REQUIRE_INTEL": {
+                   "value": 1
+                  },
+                  "PREFER_AMD": {
+                   "value": 2
+                  },
+                  "REQUIRE_AMD": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-socket-count": {
+               "description": "Number of sockets on the host.",
+               "type": {
+                "enumeration": {
+                 "enum": {
+                  "PREFER_ONE": {
+                   "value": 0
+                  },
+                  "PREFER_TWO": {
+                   "value": 1
+                  },
+                  "REQUIRE_ONE": {
+                   "value": 2
+                  },
+                  "REQUIRE_TWO": {
+                   "value": 3
+                  }
+                 }
+                }
+               }
+              },
+              "cpu-core-count": {
+               "description": "Number of cores on the host.",
+               "type": "uint64"
+              }
+             },
+             "leaf-list": {
+              "cpu-feature": {
+               "description": "List of CPU features.",
+               "type": "manotypes:cpu-feature-type"
+              }
+             }
+            }
+           }
+          },
+          "vdu-dependency": {
+           "description": "List of VDU dependencies.",
+           "key": "vdu-source-ref",
+           "leaf": {
+            "vdu-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            },
+            "vdu-depends-on-ref": {
+             "description": "Reference to the VDU that\nsource VDU depends.",
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            }
+           }
+          },
+          "http-endpoint": {
+           "description": "List of http endpoints to be used by monitoring params",
+           "key": "path",
+           "leaf": {
+            "path": {
+             "description": "The HTTP path on the management server",
+             "type": "string"
+            },
+            "https": {
+             "description": "Pick HTTPS instead of HTTP , Default is false",
+             "type": "boolean",
+             "default": "false"
+            },
+            "port": {
+             "description": "The HTTP port to connect to",
+             "type": "inet:port-number"
+            },
+            "username": {
+             "description": "The HTTP basic auth username",
+             "type": "string"
+            },
+            "password": {
+             "description": "The HTTP basic auth password",
+             "type": "string"
+            },
+            "polling_interval_secs": {
+             "description": "The HTTP polling interval in seconds",
+             "type": "uint8",
+             "default": "2"
+            },
+            "method": {
+             "description": "This is the method to be performed at the uri.\nGET by default for action",
+             "type": "manotypes:http-method",
+             "default": "GET"
+            }
+           },
+           "list": {
+            "headers": {
+             "description": "Custom HTTP headers to put on HTTP request",
+             "key": "key",
+             "leaf": {
+              "key": {
+               "description": "HTTP header key",
+               "type": "string"
+              },
+              "value": {
+               "description": "HTTP header value",
+               "type": "string"
+              }
+             }
+            }
+           }
+          },
+          "monitoring-param": {
+           "description": "List of monitoring parameters at the NS level",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "type": "string"
+            },
+            "name": {
+             "type": "string"
+            },
+            "http-endpoint-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../http-endpoint/path"
+              }
+             }
+            },
+            "json-query-method": {
+             "type": "manotypes:json-query-method",
+             "default": "NAMEKEY"
+            },
+            "description": {
+             "type": "string"
+            },
+            "group-tag": {
+             "description": "A simple tag to group monitoring parameters",
+             "type": "string"
+            },
+            "value-type": {
+             "type": "manotypes:param-value-type",
+             "default": "INT"
+            },
+            "value-integer": {
+             "description": "Current value for an integer parameter",
+             "type": "int64"
+            },
+            "value-decimal": {
+             "description": "Current value for a decimal parameter",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "4"
+              }
+             }
+            },
+            "value-string": {
+             "description": "Current value for a string parameter",
+             "type": "string"
+            },
+            "widget-type": {
+             "type": "manotypes:widget-type"
+            },
+            "units": {
+             "type": "string"
+            }
+           },
+           "container": {
+            "json-query-params": {
+             "leaf": {
+              "json-path": {
+               "description": "The jsonpath to use to extract value from JSON structure",
+               "type": "string"
+              },
+              "object-path": {
+               "description": "The objectpath to use to extract value from JSON structure",
+               "type": "string"
+              }
+             }
+            },
+            "numeric-constraints": {
+             "leaf": {
+              "min-value": {
+               "description": "Minimum value for the parameter",
+               "type": "uint64"
+              },
+              "max-value": {
+               "description": "Maxium value for the parameter",
+               "type": "uint64"
+              }
+             }
+            },
+            "text-constraints": {
+             "leaf": {
+              "min-length": {
+               "description": "Minimum string length for the parameter",
+               "type": "uint8"
+              },
+              "max-length": {
+               "description": "Maximum string length for the parameter",
+               "type": "uint8"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "mano-types": {
+   "module": {
+    "mano-types": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:mano-types",
+     "prefix": "manotypes",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-04-23": {
+       "description": "Initial revision. This YANG file defines\nthe reusable base types for VNF Management\nand Orchestration (MANO).",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "virtual-link-type": {
+       "description": "Type of virtual link\nELAN: A multipoint service connecting a set of VNFs\n// ELINE: For a simple point to point connection\n//        between a VNF and the existing network.\n// ETREE: A multipoint service connecting one or\n//        more roots and a set of leaves, but\n//        preventing inter-leaf communication.",
+       "type": {
+        "enumeration": {
+         "enum": "ELAN"
+        }
+       }
+      },
+      "http-method": {
+       "description": "Type of HTTP operation",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "POST": {
+           "value": 0
+          },
+          "PUT": {
+           "value": 1
+          },
+          "GET": {
+           "value": 2
+          },
+          "DELETE": {
+           "value": 3
+          },
+          "OPTIONS": {
+           "value": 4
+          },
+          "PATCH": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "api-type": {
+       "description": "Type of API to fetch monitoring params",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HTTP": {
+           "value": 0
+          },
+          "NETCONF": {
+           "value": 1
+          },
+          "SOAP": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "json-query-method": {
+       "description": "The method to extract a value from a JSON response\n\nNAMEKEY - Use the name as the key for a non-nested value.\nJSONPATH - Use jsonpath-rw implemenation to extract a value.\nOBJECTPATH - Use objectpath implemenation to extract a value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NAMEKEY": {
+           "value": 0
+          },
+          "JSONPATH": {
+           "value": 1
+          },
+          "OBJECTPATH": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "param-value-type": {
+       "description": "The type of the parameter value",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "INT": {
+           "value": 0
+          },
+          "DECIMAL": {
+           "value": 1
+          },
+          "STRING": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "connection-point-type": {
+       "description": "Type of connection point\nVPORT: Virtual Port\n// VNIC_ADDR: Virtual NIC Address\n// PNIC_ADDR: Physical NIC Address\n// PPORT: Phsical Port.",
+       "type": {
+        "enumeration": {
+         "enum": "VPORT"
+        }
+       }
+      },
+      "widget-type": {
+       "description": "Type of the widget, typically used by the UI.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HISTOGRAM": {
+           "value": 0
+          },
+          "BAR": {
+           "value": 1
+          },
+          "GAUGE": {
+           "value": 2
+          },
+          "SLIDER": {
+           "value": 3
+          },
+          "COUNTER": {
+           "value": 4
+          },
+          "TEXTBOX": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "cpu-feature-type": {
+       "description": "Enumeration for CPU features.\n\nAES: CPU supports advanced instruction set for\nAES (Advanced Encryption Standard).\n\nCAT: Cache Allocation Technology (CAT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to specify the amount\nof L3 cache (currently the last-level cache\nin most server and client platforms) space an\napplication can fill (as a hint to hardware\nfunctionality, certain features such as power\nmanagement may override CAT settings).\n\nCMT: Cache Monitoring Technology (CMT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to determine the\nusage of cache based on applications running\non the platform. The implementation is\ndirected at L3 cache monitoring (currently\nthe last-level cache in most server and\nclient platforms).\n\nDDIO: Intel Data Direct I/O (DDIO) enables\nEthernet server NICs and controllers talk\ndirectly to the processor cache without a\ndetour via system memory. This enumeration\nspecifies if the VM requires a DDIO\ncapable host.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "PREFER_AES": {
+           "value": 0
+          },
+          "REQUIRE_AES": {
+           "value": 1
+          },
+          "PREFER_CAT": {
+           "value": 2
+          },
+          "REQUIRE_CAT": {
+           "value": 3
+          },
+          "PREFER_CMT": {
+           "value": 4
+          },
+          "REQUIRE_CMT": {
+           "value": 5
+          },
+          "PREFER_DDIO": {
+           "value": 6
+          },
+          "REQUIRE_DDIO": {
+           "value": 7
+          }
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "named-value": {
+       "leaf": {
+        "name": {
+         "type": "string"
+        },
+        "value": {
+         "type": "string"
+        }
+       }
+      },
+      "vm-flavor": {
+       "container": {
+        "vm-flavor": {
+         "leaf": {
+          "vcpu-count": {
+           "description": "Number of vcpus for the VM.",
+           "type": "uint16"
+          },
+          "memory-mb": {
+           "description": "Amount of memory in MB.",
+           "type": "uint64"
+          },
+          "storage-gb": {
+           "description": "Amount of disk space in GB.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      },
+      "vswitch-epa": {
+       "container": {
+        "vswitch-epa": {
+         "leaf": {
+          "ovs-acceleration": {
+           "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          },
+          "ovs-offload": {
+           "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "hypervisor-epa": {
+       "container": {
+        "hypervisor-epa": {
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_KVM": {
+               "value": 0
+              },
+              "REQUIRE_KVM": {
+               "value": 1
+              }
+             }
+            }
+           }
+          },
+          "version": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "host-epa": {
+       "container": {
+        "host-epa": {
+         "description": "Specifies the host level EPA attributes.",
+         "leaf": {
+          "cpu-model": {
+           "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_WESTMERE": {
+               "value": 0
+              },
+              "REQUIRE_WESTMERE": {
+               "value": 1
+              },
+              "PREFER_SANDYBRIDGE": {
+               "value": 2
+              },
+              "REQUIRE_SANDYBRIDGE": {
+               "value": 3
+              },
+              "PREFER_IVYBRIDGE": {
+               "value": 4
+              },
+              "REQUIRE_IVYBRIDGE": {
+               "value": 5
+              },
+              "PREFER_HASWELL": {
+               "value": 6
+              },
+              "REQUIRE_HASWELL": {
+               "value": 7
+              },
+              "PREFER_BROADWELL": {
+               "value": 8
+              },
+              "REQUIRE_BROADWELL": {
+               "value": 9
+              },
+              "PREFER_NEHALEM": {
+               "value": 10
+              },
+              "REQUIRE_NEHALEM": {
+               "value": 11
+              },
+              "PREFER_PENRYN": {
+               "value": 12
+              },
+              "REQUIRE_PENRYN": {
+               "value": 13
+              },
+              "PREFER_CONROE": {
+               "value": 14
+              },
+              "REQUIRE_CONROE": {
+               "value": 15
+              },
+              "PREFER_CORE2DUO": {
+               "value": 16
+              },
+              "REQUIRE_CORE2DUO": {
+               "value": 17
+              }
+             }
+            }
+           }
+          },
+          "cpu-arch": {
+           "description": "Host CPU architecture.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_X86": {
+               "value": 0
+              },
+              "REQUIRE_X86": {
+               "value": 1
+              },
+              "PREFER_X86_64": {
+               "value": 2
+              },
+              "REQUIRE_X86_64": {
+               "value": 3
+              },
+              "PREFER_I686": {
+               "value": 4
+              },
+              "REQUIRE_I686": {
+               "value": 5
+              },
+              "PREFER_IA64": {
+               "value": 6
+              },
+              "REQUIRE_IA64": {
+               "value": 7
+              },
+              "PREFER_ARMV7": {
+               "value": 8
+              },
+              "REQUIRE_ARMV7": {
+               "value": 9
+              },
+              "PREFER_ARMV8": {
+               "value": 10
+              },
+              "REQUIRE_ARMV8": {
+               "value": 11
+              }
+             }
+            }
+           }
+          },
+          "cpu-vendor": {
+           "description": "Host CPU Vendor.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_INTEL": {
+               "value": 0
+              },
+              "REQUIRE_INTEL": {
+               "value": 1
+              },
+              "PREFER_AMD": {
+               "value": 2
+              },
+              "REQUIRE_AMD": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-socket-count": {
+           "description": "Number of sockets on the host.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_ONE": {
+               "value": 0
+              },
+              "PREFER_TWO": {
+               "value": 1
+              },
+              "REQUIRE_ONE": {
+               "value": 2
+              },
+              "REQUIRE_TWO": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-core-count": {
+           "description": "Number of cores on the host.",
+           "type": "uint64"
+          }
+         },
+         "leaf-list": {
+          "cpu-feature": {
+           "description": "List of CPU features.",
+           "type": "manotypes:cpu-feature-type"
+          }
+         }
+        }
+       }
+      },
+      "guest-epa": {
+       "description": "EPA attributes for the guest",
+       "container": {
+        "guest-epa": {
+         "leaf": {
+          "trusted-execution": {
+           "description": "This VM should be allocated from trusted pool",
+           "type": "boolean"
+          },
+          "mempage-size": {
+           "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LARGE": {
+               "value": 0
+              },
+              "SMALL": {
+               "value": 1
+              },
+              "SIZE_2MB": {
+               "value": 2
+              },
+              "SIZE_1GB": {
+               "value": 3
+              },
+              "PREFER_LARGE": {
+               "value": 4
+              }
+             }
+            }
+           },
+           "default": "SMALL"
+          },
+          "cpu-pinning-policy": {
+           "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "DEDICATED": {
+               "value": 0
+              },
+              "SHARED": {
+               "value": 1
+              },
+              "ANY": {
+               "value": 2
+              }
+             }
+            }
+           },
+           "default": "ANY"
+          },
+          "cpu-thread-pinning-policy": {
+           "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "AVOID": {
+               "value": 0
+              },
+              "SEPARATE": {
+               "value": 1
+              },
+              "ISOLATE": {
+               "value": 2
+              },
+              "PREFER": {
+               "value": 3
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "pcie-device": {
+           "description": "List of pcie passthrough devices.",
+           "key": "device-id",
+           "leaf": {
+            "device-id": {
+             "description": "Device identifier.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of devices to attach to the VM.",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "choice": {
+          "numa-policy": {
+           "case": {
+            "numa-unware": {
+             "leaf": {
+              "numa-unware": {
+               "type": "empty"
+              }
+             }
+            },
+            "numa-aware": {
+             "container": {
+              "numa-node-policy": {
+               "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+               "leaf": {
+                "node-cnt": {
+                 "description": "The number of numa nodes to expose to the VM.",
+                 "type": "uint16"
+                },
+                "mem-policy": {
+                 "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "STRICT": {
+                     "value": 0
+                    },
+                    "PREFERRED": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               },
+               "list": {
+                "node": {
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "NUMA node identification. Typically\nit's 0 or 1",
+                   "type": "uint64"
+                  },
+                  "memory-mb": {
+                   "description": "Memory size expressed in MB\nfor this NUMA node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "leaf-list": {
+                  "vcpu": {
+                   "description": "List of vcpus to allocate on\nthis numa node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "choice": {
+                  "om-numa-type": {
+                   "description": "Openmano Numa type selection",
+                   "case": {
+                    "cores": {
+                     "leaf": {
+                      "num-cores": {
+                       "type": "uint8"
+                      }
+                     }
+                    },
+                    "paired-threads": {
+                     "container": {
+                      "paired-threads": {
+                       "leaf": {
+                        "num-paired-threads": {
+                         "type": "uint8"
+                        }
+                       },
+                       "list": {
+                        "paired-thread-ids": {
+                         "description": "List of thread pairs to use in case of paired-thread numa",
+                         "key": "thread-a",
+                         "leaf": {
+                          "thread-a": {
+                           "type": "uint8"
+                          },
+                          "thread-b": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "threads": {
+                     "leaf": {
+                      "num-threads": {
+                       "type": "uint8"
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "provider-network": {
+       "container": {
+        "provider-network": {
+         "description": "Container for the provider network.",
+         "leaf": {
+          "name": {
+           "description": "Name of the provider network.",
+           "type": "string"
+          },
+          "physical-network": {
+           "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+           "type": "string"
+          },
+          "overlay-type": {
+           "description": "Type of the overlay network.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LOCAL": {
+               "value": 0
+              },
+              "FLAT": {
+               "value": 1
+              },
+              "VLAN": {
+               "value": 2
+              },
+              "VXLAN": {
+               "value": 3
+              },
+              "GRE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "segmentation_id": {
+           "description": "Segmentation ID",
+           "type": "uint32"
+          }
+         }
+        }
+       }
+      },
+      "monitoring-param": {
+       "list": {
+        "http-endpoint": {
+         "description": "List of http endpoints to be used by monitoring params",
+         "key": "path",
+         "leaf": {
+          "path": {
+           "description": "The HTTP path on the management server",
+           "type": "string"
+          },
+          "https": {
+           "description": "Pick HTTPS instead of HTTP , Default is false",
+           "type": "boolean",
+           "default": "false"
+          },
+          "port": {
+           "description": "The HTTP port to connect to",
+           "type": "inet:port-number"
+          },
+          "username": {
+           "description": "The HTTP basic auth username",
+           "type": "string"
+          },
+          "password": {
+           "description": "The HTTP basic auth password",
+           "type": "string"
+          },
+          "polling_interval_secs": {
+           "description": "The HTTP polling interval in seconds",
+           "type": "uint8",
+           "default": "2"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nGET by default for action",
+           "type": "manotypes:http-method",
+           "default": "GET"
+          }
+         },
+         "list": {
+          "headers": {
+           "description": "Custom HTTP headers to put on HTTP request",
+           "key": "key",
+           "leaf": {
+            "key": {
+             "description": "HTTP header key",
+             "type": "string"
+            },
+            "value": {
+             "description": "HTTP header value",
+             "type": "string"
+            }
+           }
+          }
+         }
+        },
+        "monitoring-param": {
+         "description": "List of monitoring parameters at the NS level",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "http-endpoint-ref": {
+           "type": {
+            "leafref": {
+             "path": "../../http-endpoint/path"
+            }
+           }
+          },
+          "json-query-method": {
+           "type": "manotypes:json-query-method",
+           "default": "NAMEKEY"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameters",
+           "type": "string"
+          },
+          "value-type": {
+           "type": "manotypes:param-value-type",
+           "default": "INT"
+          },
+          "value-integer": {
+           "description": "Current value for an integer parameter",
+           "type": "int64"
+          },
+          "value-decimal": {
+           "description": "Current value for a decimal parameter",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "4"
+            }
+           }
+          },
+          "value-string": {
+           "description": "Current value for a string parameter",
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "units": {
+           "type": "string"
+          }
+         },
+         "container": {
+          "json-query-params": {
+           "leaf": {
+            "json-path": {
+             "description": "The jsonpath to use to extract value from JSON structure",
+             "type": "string"
+            },
+            "object-path": {
+             "description": "The objectpath to use to extract value from JSON structure",
+             "type": "string"
+            }
+           }
+          },
+          "numeric-constraints": {
+           "leaf": {
+            "min-value": {
+             "description": "Minimum value for the parameter",
+             "type": "uint64"
+            },
+            "max-value": {
+             "description": "Maxium value for the parameter",
+             "type": "uint64"
+            }
+           }
+          },
+          "text-constraints": {
+           "leaf": {
+            "min-length": {
+             "description": "Minimum string length for the parameter",
+             "type": "uint8"
+            },
+            "max-length": {
+             "description": "Maximum string length for the parameter",
+             "type": "uint8"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "control-param": {
+       "list": {
+        "control-param": {
+         "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group control parameters",
+           "type": "string"
+          },
+          "min-value": {
+           "description": "Minimum value for the parameter",
+           "type": "uint64"
+          },
+          "max-value": {
+           "description": "Maxium value for the parameter",
+           "type": "uint64"
+          },
+          "current-value": {
+           "description": "Current value for the parameter",
+           "type": "uint64"
+          },
+          "step-value": {
+           "description": "Step value for the parameter",
+           "type": "uint64"
+          },
+          "units": {
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-param": {
+       "list": {
+        "action-param": {
+         "description": "List of action parameters to\ncontrol VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameter",
+           "type": "string"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameters": {
+       "description": "",
+       "list": {
+        "input-parameters": {
+         "description": "List of input parameters",
+         "key": "uuid",
+         "leaf": {
+          "uuid": {
+           "description": "An identifier that uniquely identifies an input parameter",
+           "type": "string"
+          },
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          },
+          "value": {
+           "description": "The value that the element specified by the xpath should take when a\nrecord is created.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "nfvi-metrics": {
+       "container": {
+        "vcpu": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "VCPU"
+          },
+          "total": {
+           "description": "The total number of VCPUs available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The VCPU utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "memory": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "MEMORY"
+          },
+          "used": {
+           "description": "The amount of memory (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of memory (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The memory utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "storage": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "STORAGE"
+          },
+          "used": {
+           "description": "The amount of storage (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of storage (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The storage utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "external-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "EXTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of external ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "internal-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "INTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of internal ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "network": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "NETWORK TRAFFIC"
+          }
+         },
+         "container": {
+          "incoming": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "INCOMING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of incoming bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of incoming packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current incoming byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current incoming packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          },
+          "outgoing": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "OUTGOING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of outgoing bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of outgoing packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current outgoing byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current outgoing packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "pkgdir": "/Users/onvelocity/rift-composer/webapp/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw.vnfd-yang.json b/skyquake/plugins/composer/src/schemas/yang/rw.vnfd-yang.json
new file mode 100644 (file)
index 0000000..5e6ad13
--- /dev/null
@@ -0,0 +1,2328 @@
+{
+ "synth": "source",
+ "name": "rw-vnfd",
+ "schema": {
+  "module": {
+   "rw-vnfd": {
+    "namespace": "http://riftio.com/ns/riftware-1.0/rw-vnfd",
+    "prefix": "rw-vnfd",
+    "import": {
+     "vnfd": {
+      "prefix": "vnfd"
+     },
+     "rwvcs-types": {
+      "prefix": "rwvcstypes"
+     },
+     "rw-pb-ext": {
+      "prefix": "rwpb"
+     },
+     "ietf-yang-types": {
+      "prefix": "yang"
+     },
+     "mano-types": {
+      "prefix": "manotypes"
+     }
+    },
+    "revision": {
+     "2015-09-10": {
+      "description": "Initial revision. This YANG file augments\nthe base MANO VNFD",
+      "reference": "Derived from earlier versions of base YANG files"
+     }
+    },
+    "augment": {
+     "/vnfd:vnfd-catalog/vnfd:vnfd": {
+      "uses": {},
+      "list": {
+       "component": {
+        "description": "This section defines the RIFT.ware\nvirtual components",
+        "key": "component-name",
+        "leaf": {
+         "component-name": {
+          "description": "",
+          "type": "string"
+         },
+         "component-type": {
+          "description": "",
+          "type": "rwvcstypes:component_type",
+          "mandatory": true
+         }
+        },
+        "choice": {
+         "component": {
+          "case": {
+           "rwvcs-rwcollection": {},
+           "rwvcs-rwvm": {},
+           "rwvcs-rwproc": {},
+           "native-proc": {},
+           "rwvcs-rwtasklet": {}
+          }
+         }
+        }
+       },
+       "control-param": {
+        "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group control parameters",
+          "type": "string"
+         },
+         "min-value": {
+          "description": "Minimum value for the parameter",
+          "type": "uint64"
+         },
+         "max-value": {
+          "description": "Maxium value for the parameter",
+          "type": "uint64"
+         },
+         "current-value": {
+          "description": "Current value for the parameter",
+          "type": "uint64"
+         },
+         "step-value": {
+          "description": "Step value for the parameter",
+          "type": "uint64"
+         },
+         "units": {
+          "type": "string"
+         },
+         "widget-type": {
+          "type": "manotypes:widget-type"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+          "type": "string"
+         }
+        }
+       },
+       "action-param": {
+        "description": "List of action parameters to\ncontrol VNF",
+        "key": "id",
+        "leaf": {
+         "id": {
+          "type": "string"
+         },
+         "name": {
+          "type": "string"
+         },
+         "description": {
+          "type": "string"
+         },
+         "group-tag": {
+          "description": "A simple tag to group monitoring parameter",
+          "type": "string"
+         },
+         "url": {
+          "description": "This is the URL where to perform the operation",
+          "type": "inet:uri"
+         },
+         "method": {
+          "description": "This is the method to be performed at the uri.\nPOST by default for action",
+          "type": "manotypes:http-method",
+          "default": "POST"
+         },
+         "payload": {
+          "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+          "type": "string"
+         }
+        }
+       }
+      }
+     },
+     "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu": {
+      "leaf": {
+       "vcs-component-ref": {
+        "description": "This defines the software components using the\nRIFT.ware Virtual Component System (VCS). This\nalso allows specifying a state machine during\nthe VM startup.\nNOTE: This is an significant addition to MANO,\nsince MANO doesn't clearly specify a method to\nidentify various software components in a VM.\nAlso using a state machine is not something that\nis well described in MANO.",
+        "type": {
+         "leafref": {
+          "path": "/vnfd:vnfd-catalog/vnfd:vnfd/rw-vnfd:component/rw-vnfd:component-name"
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "dependencies": {
+  "vnfd": {
+   "module": {
+    "vnfd": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vnfd",
+     "prefix": "vnfd",
+     "import": {
+      "mano-types": {
+       "prefix": "manotypes"
+      },
+      "rw-pb-ext": {
+       "prefix": "rwpb"
+      },
+      "ietf-yang-types": {
+       "prefix": "yang"
+      },
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-09-10": {
+       "description": "Initial revision. This YANG file defines\nthe Virtual Network Function (VNF)",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "grouping": {
+      "virtual-interface": {
+       "container": {
+        "virtual-interface": {
+         "description": "Container for the virtual interface properties",
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of virtual interface\nbetween VM and host.\nVIRTIO          : Use the traditional VIRTIO interface.\nPCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.\nSR-IOV          : Use SR-IOV interface.\nOM-MGMT         : Used to specify openmano mgmt external-connection type",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "OM-MGMT": null,
+              "PCI-PASSTHROUGH": null,
+              "SR-IOV": null,
+              "VIRTIO": null
+             }
+            }
+           },
+           "default": "VIRTIO"
+          },
+          "vpci": {
+           "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+           "type": "string"
+          },
+          "bandwidth": {
+           "description": "Aggregate bandwidth of the NIC.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      }
+     },
+     "container": {
+      "vnfd-catalog": {
+       "description": "Virtual Network Function Descriptor (VNFD).",
+       "list": {
+        "vnfd": {
+         "key": "id",
+         "leaf": {
+          "id": {
+           "description": "Identifier for the VNFD.",
+           "type": "yang:uuid"
+          },
+          "name": {
+           "description": "VNFD name.",
+           "mandatory": "true",
+           "type": "string"
+          },
+          "short-name": {
+           "description": "VNFD short name.",
+           "type": "string"
+          },
+          "vendor": {
+           "description": "Vendor of the VNFD.",
+           "type": "string"
+          },
+          "description": {
+           "description": "Description of the VNFD.",
+           "type": "string"
+          },
+          "version": {
+           "description": "Version of the VNFD",
+           "type": "string"
+          }
+         },
+         "container": {
+          "mgmt-interface": {
+           "description": "Interface over which the VNF is managed.",
+           "choice": {
+            "endpoint-type": {
+             "description": "Indicates the type of management endpoint.",
+             "case": {
+              "ip": {
+               "description": "Specifies the static IP address for managing the VNF.",
+               "leaf": {
+                "ip-address": {
+                 "type": "inet:ip-address"
+                }
+               }
+              },
+              "vdu-id": {
+               "description": "Use the default management interface on this VDU.",
+               "leaf": {
+                "vdu-id": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                  }
+                 }
+                }
+               }
+              },
+              "cp": {
+               "description": "Use the ip address associated with this connection point.",
+               "leaf": {
+                "cp": {
+                 "type": {
+                  "leafref": {
+                   "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                  }
+                 }
+                }
+               }
+              }
+             }
+            },
+            "interface-type": {
+             "case": {
+              "netconf": {
+               "leaf": {
+                "netconf": {
+                 "type": "empty"
+                }
+               }
+              }
+             }
+            }
+           },
+           "leaf": {
+            "port": {
+             "description": "Port for the management interface.",
+             "type": "inet:port-number"
+            }
+           },
+           "container": {
+            "dashboard-params": {
+             "description": "Parameters for the VNF dashboard",
+             "leaf": {
+              "path": {
+               "description": "The HTTP path for the dashboard",
+               "type": "string"
+              },
+              "https": {
+               "description": "Pick HTTPS instead of HTTP , Default is false",
+               "type": "boolean"
+              },
+              "port": {
+               "description": "The HTTP port for the dashboard",
+               "type": "inet:port-number"
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "internal-vld": {
+           "key": "id",
+           "description": "List of Internal Virtual Link Descriptors (VLD).\nThe internal VLD describes the basic topology of\nthe connectivity (e.g. E-LAN, E-Line, E-Tree)\nbetween internal VNF components of the system.",
+           "leaf": {
+            "id": {
+             "description": "Identifier for the VLD",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Name of the internal VLD",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the internal VLD",
+             "type": "string"
+            },
+            "description": {
+             "type": "string"
+            },
+            "type": {
+             "type": "manotypes:virtual-link-type"
+            },
+            "root-bandwidth": {
+             "description": "For ELAN this is the aggregate bandwidth.",
+             "type": "uint64"
+            },
+            "leaf-bandwidth": {
+             "description": "For ELAN this is the bandwidth of branches.",
+             "type": "uint64"
+            }
+           },
+           "leaf-list": {
+            "internal-connection-point-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/internal-connection-point/id"
+              }
+             }
+            }
+           },
+           "uses": "manotypes:provider-network"
+          },
+          "connection-point": {
+           "key": "name",
+           "description": "List for external connection points. Each VNF has one\nor more external connection points. As the name\nimplies that external connection points are used for\nconnecting the VNF to other VNFs or to external networks.\nEach VNF exposes these connection points to the\norchestrator. The orchestrator can construct network\nservices by connecting the connection points between\ndifferent VNFs. The NFVO will use VLDs and VNFFGs at\nthe network service level to construct network services.",
+           "leaf": {
+            "name": {
+             "description": "Name of the connection point",
+             "type": "string"
+            },
+            "short-name": {
+             "description": "Short name of the connection point",
+             "type": "string"
+            },
+            "type": {
+             "description": "Type of the connection point.",
+             "type": "manotypes:connection-point-type"
+            }
+           }
+          },
+          "vdu": {
+           "description": "List of Virtual Deployment Units",
+           "key": "id",
+           "leaf": {
+            "id": {
+             "description": "Unique id for the VDU",
+             "type": "yang:uuid"
+            },
+            "name": {
+             "description": "Unique name for the VDU",
+             "type": "string"
+            },
+            "description": {
+             "description": "Description of the VDU.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of instances of VDU",
+             "type": "uint64"
+            },
+            "mgmt-vpci": {
+             "description": "Specifies the virtual PCI address. Expressed in\nthe following format dddd:dd:dd.d. For example\n0000:00:12.0. This information can be used to\npass as metadata during the VM creation.",
+             "type": "string"
+            },
+            "image": {
+             "description": "Image name for the software image.\nIf the image name is found within the VNF packaage it will\nbe uploaded to all cloud accounts during onboarding process.\nOtherwise, the image must be added to the cloud account with\nthe same name as entered here.\n",
+             "mandatory": "true",
+             "type": "string"
+            },
+            "cloud-init": {
+             "description": "Content of cloud-init script",
+             "type": "string"
+            }
+           },
+           "uses": {
+            "manotypes:vm-flavor": null,
+            "manotypes:guest-epa": null,
+            "manotypes:vswitch-epa": null,
+            "manotypes:hypervisor-epa": null,
+            "manotypes:host-epa": null
+           },
+           "list": {
+            "internal-connection-point": {
+             "key": "id",
+             "description": "List for internal connection points. Each VNFC\nhas zero or more internal connection points.\nInternal connection points are used for connecting\nthe VNF components internal to the VNF. If a VNF\nhas only one VNFC, it may not have any internal\nconnection points.",
+             "leaf": {
+              "id": {
+               "description": "Identifier for the internal connection points",
+               "type": "yang:uuid"
+              },
+              "type": {
+               "description": "Type of the connection point.",
+               "type": "manotypes:connection-point-type"
+              },
+              "internal-vld-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../../internal-vld/id"
+                }
+               }
+              }
+             }
+            },
+            "internal-interface": {
+             "description": "List of internal interfaces for the VNF",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of internal interface. Note that this\nname has only local significance to the VDU.",
+               "type": "string"
+              },
+              "vdu-internal-connection-point-ref": {
+               "type": {
+                "leafref": {
+                 "path": "../../internal-connection-point/id"
+                }
+               }
+              }
+             },
+             "uses": "virtual-interface"
+            },
+            "external-interface": {
+             "description": "List of external interfaces for the VNF.\nThe external interfaces enable sending\ntraffic to and from VNF.",
+             "key": "name",
+             "leaf": {
+              "name": {
+               "description": "Name of the external interface. Note that\nthis name has only local significance.",
+               "type": "string"
+              },
+              "vnfd-connection-point-ref": {
+               "description": "Name of the external connection point.",
+               "type": {
+                "leafref": {
+                 "path": "../../../connection-point/name"
+                }
+               }
+              }
+             },
+             "uses": "virtual-interface"
+            }
+           }
+          },
+          "vdu-dependency": {
+           "description": "List of VDU dependencies.",
+           "key": "vdu-source-ref",
+           "leaf": {
+            "vdu-source-ref": {
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            },
+            "vdu-depends-on-ref": {
+             "description": "Reference to the VDU that\nsource VDU depends.",
+             "type": {
+              "leafref": {
+               "path": "../../vdu/id"
+              }
+             }
+            }
+           }
+          }
+         },
+         "uses": "manotypes:monitoring-param"
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "mano-types": {
+   "module": {
+    "mano-types": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:mano-types",
+     "prefix": "manotypes",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-04-23": {
+       "description": "Initial revision. This YANG file defines\nthe reusable base types for VNF Management\nand Orchestration (MANO).",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "virtual-link-type": {
+       "description": "Type of virtual link\nELAN: A multipoint service connecting a set of VNFs\n// ELINE: For a simple point to point connection\n//        between a VNF and the existing network.\n// ETREE: A multipoint service connecting one or\n//        more roots and a set of leaves, but\n//        preventing inter-leaf communication.",
+       "type": {
+        "enumeration": {
+         "enum": "ELAN"
+        }
+       }
+      },
+      "http-method": {
+       "description": "Type of HTTP operation",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "POST": {
+           "value": 0
+          },
+          "PUT": {
+           "value": 1
+          },
+          "GET": {
+           "value": 2
+          },
+          "DELETE": {
+           "value": 3
+          },
+          "OPTIONS": {
+           "value": 4
+          },
+          "PATCH": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "api-type": {
+       "description": "Type of API to fetch monitoring params",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HTTP": {
+           "value": 0
+          },
+          "NETCONF": {
+           "value": 1
+          },
+          "SOAP": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "json-query-method": {
+       "description": "The method to extract a value from a JSON response\n\nNAMEKEY - Use the name as the key for a non-nested value.\nJSONPATH - Use jsonpath-rw implemenation to extract a value.\nOBJECTPATH - Use objectpath implemenation to extract a value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NAMEKEY": {
+           "value": 0
+          },
+          "JSONPATH": {
+           "value": 1
+          },
+          "OBJECTPATH": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "param-value-type": {
+       "description": "The type of the parameter value",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "INT": {
+           "value": 0
+          },
+          "DECIMAL": {
+           "value": 1
+          },
+          "STRING": {
+           "value": 2
+          }
+         }
+        }
+       }
+      },
+      "connection-point-type": {
+       "description": "Type of connection point\nVPORT: Virtual Port\n// VNIC_ADDR: Virtual NIC Address\n// PNIC_ADDR: Physical NIC Address\n// PPORT: Phsical Port.",
+       "type": {
+        "enumeration": {
+         "enum": "VPORT"
+        }
+       }
+      },
+      "widget-type": {
+       "description": "Type of the widget, typically used by the UI.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HISTOGRAM": {
+           "value": 0
+          },
+          "BAR": {
+           "value": 1
+          },
+          "GAUGE": {
+           "value": 2
+          },
+          "SLIDER": {
+           "value": 3
+          },
+          "COUNTER": {
+           "value": 4
+          },
+          "TEXTBOX": {
+           "value": 5
+          }
+         }
+        }
+       }
+      },
+      "cpu-feature-type": {
+       "description": "Enumeration for CPU features.\n\nAES: CPU supports advanced instruction set for\nAES (Advanced Encryption Standard).\n\nCAT: Cache Allocation Technology (CAT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to specify the amount\nof L3 cache (currently the last-level cache\nin most server and client platforms) space an\napplication can fill (as a hint to hardware\nfunctionality, certain features such as power\nmanagement may override CAT settings).\n\nCMT: Cache Monitoring Technology (CMT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to determine the\nusage of cache based on applications running\non the platform. The implementation is\ndirected at L3 cache monitoring (currently\nthe last-level cache in most server and\nclient platforms).\n\nDDIO: Intel Data Direct I/O (DDIO) enables\nEthernet server NICs and controllers talk\ndirectly to the processor cache without a\ndetour via system memory. This enumeration\nspecifies if the VM requires a DDIO\ncapable host.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "PREFER_AES": {
+           "value": 0
+          },
+          "REQUIRE_AES": {
+           "value": 1
+          },
+          "PREFER_CAT": {
+           "value": 2
+          },
+          "REQUIRE_CAT": {
+           "value": 3
+          },
+          "PREFER_CMT": {
+           "value": 4
+          },
+          "REQUIRE_CMT": {
+           "value": 5
+          },
+          "PREFER_DDIO": {
+           "value": 6
+          },
+          "REQUIRE_DDIO": {
+           "value": 7
+          }
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "named-value": {
+       "leaf": {
+        "name": {
+         "type": "string"
+        },
+        "value": {
+         "type": "string"
+        }
+       }
+      },
+      "vm-flavor": {
+       "container": {
+        "vm-flavor": {
+         "leaf": {
+          "vcpu-count": {
+           "description": "Number of vcpus for the VM.",
+           "type": "uint16"
+          },
+          "memory-mb": {
+           "description": "Amount of memory in MB.",
+           "type": "uint64"
+          },
+          "storage-gb": {
+           "description": "Amount of disk space in GB.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      },
+      "vswitch-epa": {
+       "container": {
+        "vswitch-epa": {
+         "leaf": {
+          "ovs-acceleration": {
+           "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          },
+          "ovs-offload": {
+           "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": {
+               "value": 0
+              },
+              "PREFERRED": {
+               "value": 1
+              },
+              "DISABLED": {
+               "value": 2
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "hypervisor-epa": {
+       "container": {
+        "hypervisor-epa": {
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_KVM": {
+               "value": 0
+              },
+              "REQUIRE_KVM": {
+               "value": 1
+              }
+             }
+            }
+           }
+          },
+          "version": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "host-epa": {
+       "container": {
+        "host-epa": {
+         "description": "Specifies the host level EPA attributes.",
+         "leaf": {
+          "cpu-model": {
+           "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_WESTMERE": {
+               "value": 0
+              },
+              "REQUIRE_WESTMERE": {
+               "value": 1
+              },
+              "PREFER_SANDYBRIDGE": {
+               "value": 2
+              },
+              "REQUIRE_SANDYBRIDGE": {
+               "value": 3
+              },
+              "PREFER_IVYBRIDGE": {
+               "value": 4
+              },
+              "REQUIRE_IVYBRIDGE": {
+               "value": 5
+              },
+              "PREFER_HASWELL": {
+               "value": 6
+              },
+              "REQUIRE_HASWELL": {
+               "value": 7
+              },
+              "PREFER_BROADWELL": {
+               "value": 8
+              },
+              "REQUIRE_BROADWELL": {
+               "value": 9
+              },
+              "PREFER_NEHALEM": {
+               "value": 10
+              },
+              "REQUIRE_NEHALEM": {
+               "value": 11
+              },
+              "PREFER_PENRYN": {
+               "value": 12
+              },
+              "REQUIRE_PENRYN": {
+               "value": 13
+              },
+              "PREFER_CONROE": {
+               "value": 14
+              },
+              "REQUIRE_CONROE": {
+               "value": 15
+              },
+              "PREFER_CORE2DUO": {
+               "value": 16
+              },
+              "REQUIRE_CORE2DUO": {
+               "value": 17
+              }
+             }
+            }
+           }
+          },
+          "cpu-arch": {
+           "description": "Host CPU architecture.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_X86": {
+               "value": 0
+              },
+              "REQUIRE_X86": {
+               "value": 1
+              },
+              "PREFER_X86_64": {
+               "value": 2
+              },
+              "REQUIRE_X86_64": {
+               "value": 3
+              },
+              "PREFER_I686": {
+               "value": 4
+              },
+              "REQUIRE_I686": {
+               "value": 5
+              },
+              "PREFER_IA64": {
+               "value": 6
+              },
+              "REQUIRE_IA64": {
+               "value": 7
+              },
+              "PREFER_ARMV7": {
+               "value": 8
+              },
+              "REQUIRE_ARMV7": {
+               "value": 9
+              },
+              "PREFER_ARMV8": {
+               "value": 10
+              },
+              "REQUIRE_ARMV8": {
+               "value": 11
+              }
+             }
+            }
+           }
+          },
+          "cpu-vendor": {
+           "description": "Host CPU Vendor.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_INTEL": {
+               "value": 0
+              },
+              "REQUIRE_INTEL": {
+               "value": 1
+              },
+              "PREFER_AMD": {
+               "value": 2
+              },
+              "REQUIRE_AMD": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-socket-count": {
+           "description": "Number of sockets on the host.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_ONE": {
+               "value": 0
+              },
+              "PREFER_TWO": {
+               "value": 1
+              },
+              "REQUIRE_ONE": {
+               "value": 2
+              },
+              "REQUIRE_TWO": {
+               "value": 3
+              }
+             }
+            }
+           }
+          },
+          "cpu-core-count": {
+           "description": "Number of cores on the host.",
+           "type": "uint64"
+          },
+          "om-cpu-model-string": {
+           "description": "Openmano CPU model string",
+           "type": "string"
+          }
+         },
+         "leaf-list": {
+          "cpu-feature": {
+           "description": "List of CPU features.",
+           "type": "manotypes:cpu-feature-type"
+          },
+          "om-cpu-feature": {
+           "description": "Openmano CPU features",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "guest-epa": {
+       "description": "EPA attributes for the guest",
+       "container": {
+        "guest-epa": {
+         "leaf": {
+          "trusted-execution": {
+           "description": "This VM should be allocated from trusted pool",
+           "type": "boolean"
+          },
+          "mempage-size": {
+           "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LARGE": {
+               "value": 0
+              },
+              "SMALL": {
+               "value": 1
+              },
+              "SIZE_2MB": {
+               "value": 2
+              },
+              "SIZE_1GB": {
+               "value": 3
+              },
+              "PREFER_LARGE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "cpu-pinning-policy": {
+           "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "DEDICATED": {
+               "value": 0
+              },
+              "SHARED": {
+               "value": 1
+              },
+              "ANY": {
+               "value": 2
+              }
+             }
+            }
+           },
+           "default": "ANY"
+          },
+          "cpu-thread-pinning-policy": {
+           "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "AVOID": {
+               "value": 0
+              },
+              "SEPARATE": {
+               "value": 1
+              },
+              "ISOLATE": {
+               "value": 2
+              },
+              "PREFER": {
+               "value": 3
+              }
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "pcie-device": {
+           "description": "List of pcie passthrough devices.",
+           "key": "device-id",
+           "leaf": {
+            "device-id": {
+             "description": "Device identifier.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of devices to attach to the VM.",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "choice": {
+          "numa-policy": {
+           "case": {
+            "numa-unware": {
+             "leaf": {
+              "numa-unware": {
+               "type": "empty"
+              }
+             }
+            },
+            "numa-aware": {
+             "container": {
+              "numa-node-policy": {
+               "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+               "leaf": {
+                "node-cnt": {
+                 "description": "The number of numa nodes to expose to the VM.",
+                 "type": "uint16"
+                },
+                "mem-policy": {
+                 "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "STRICT": {
+                     "value": 0
+                    },
+                    "PREFERRED": {
+                     "value": 1
+                    }
+                   }
+                  }
+                 }
+                }
+               },
+               "list": {
+                "node": {
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "NUMA node identification. Typically\nit's 0 or 1",
+                   "type": "uint64"
+                  },
+                  "memory-mb": {
+                   "description": "Memory size expressed in MB\nfor this NUMA node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "leaf-list": {
+                  "vcpu": {
+                   "description": "List of vcpus to allocate on\nthis numa node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "choice": {
+                  "om-numa-type": {
+                   "description": "Openmano Numa type selection",
+                   "case": {
+                    "cores": {
+                     "leaf": {
+                      "num-cores": {
+                       "type": "uint8"
+                      }
+                     }
+                    },
+                    "paired-threads": {
+                     "container": {
+                      "paired-threads": {
+                       "leaf": {
+                        "num-paired-threads": {
+                         "type": "uint8"
+                        }
+                       },
+                       "list": {
+                        "paired-thread-ids": {
+                         "description": "List of thread pairs to use in case of paired-thread numa",
+                         "max-elements": 16,
+                         "key": "thread-a",
+                         "leaf": {
+                          "thread-a": {
+                           "type": "uint8"
+                          },
+                          "thread-b": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "threads": {
+                     "leaf": {
+                      "num-threads": {
+                       "type": "uint8"
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "provider-network": {
+       "container": {
+        "provider-network": {
+         "description": "Container for the provider network.",
+         "leaf": {
+          "name": {
+           "description": "Name of the provider network.",
+           "type": "string"
+          },
+          "physical-network": {
+           "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+           "type": "string"
+          },
+          "overlay-type": {
+           "description": "Type of the overlay network.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LOCAL": {
+               "value": 0
+              },
+              "FLAT": {
+               "value": 1
+              },
+              "VLAN": {
+               "value": 2
+              },
+              "VXLAN": {
+               "value": 3
+              },
+              "GRE": {
+               "value": 4
+              }
+             }
+            }
+           }
+          },
+          "segmentation_id": {
+           "description": "Segmentation ID",
+           "type": "uint32"
+          }
+         }
+        }
+       }
+      },
+      "monitoring-param": {
+       "list": {
+        "http-endpoint": {
+         "description": "List of http endpoints to be used by monitoring params",
+         "key": "path",
+         "leaf": {
+          "path": {
+           "description": "The HTTP path on the management server",
+           "type": "string"
+          },
+          "https": {
+           "description": "Pick HTTPS instead of HTTP , Default is false",
+           "type": "boolean",
+           "default": "false"
+          },
+          "port": {
+           "description": "The HTTP port to connect to",
+           "type": "inet:port-number"
+          },
+          "username": {
+           "description": "The HTTP basic auth username",
+           "type": "string"
+          },
+          "password": {
+           "description": "The HTTP basic auth password",
+           "type": "string"
+          },
+          "polling_interval_secs": {
+           "description": "The HTTP polling interval in seconds",
+           "type": "uint8",
+           "default": "2"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nGET by default for action",
+           "type": "manotypes:http-method",
+           "default": "GET"
+          }
+         },
+         "list": {
+          "headers": {
+           "description": "Custom HTTP headers to put on HTTP request",
+           "key": "key",
+           "leaf": {
+            "key": {
+             "description": "HTTP header key",
+             "type": "string"
+            },
+            "value": {
+             "description": "HTTP header value",
+             "type": "string"
+            }
+           }
+          }
+         }
+        },
+        "monitoring-param": {
+         "description": "List of monitoring parameters at the NS level",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "http-endpoint-ref": {
+           "type": {
+            "leafref": {
+             "path": "../../http-endpoint/path"
+            }
+           }
+          },
+          "json-query-method": {
+           "type": "manotypes:json-query-method",
+           "default": "NAMEKEY"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameters",
+           "type": "string"
+          },
+          "value-type": {
+           "type": "manotypes:param-value-type",
+           "default": "INT"
+          },
+          "value-integer": {
+           "description": "Current value for an integer parameter",
+           "type": "int64"
+          },
+          "value-decimal": {
+           "description": "Current value for a decimal parameter",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "4"
+            }
+           }
+          },
+          "value-string": {
+           "description": "Current value for a string parameter",
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "units": {
+           "type": "string"
+          }
+         },
+         "container": {
+          "json-query-params": {
+           "leaf": {
+            "json-path": {
+             "description": "The jsonpath to use to extract value from JSON structure",
+             "type": "string"
+            },
+            "object-path": {
+             "description": "The objectpath to use to extract value from JSON structure",
+             "type": "string"
+            }
+           }
+          },
+          "numeric-constraints": {
+           "leaf": {
+            "min-value": {
+             "description": "Minimum value for the parameter",
+             "type": "uint64"
+            },
+            "max-value": {
+             "description": "Maxium value for the parameter",
+             "type": "uint64"
+            }
+           }
+          },
+          "text-constraints": {
+           "leaf": {
+            "min-length": {
+             "description": "Minimum string length for the parameter",
+             "type": "uint8"
+            },
+            "max-length": {
+             "description": "Maximum string length for the parameter",
+             "type": "uint8"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "control-param": {
+       "list": {
+        "control-param": {
+         "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group control parameters",
+           "type": "string"
+          },
+          "min-value": {
+           "description": "Minimum value for the parameter",
+           "type": "uint64"
+          },
+          "max-value": {
+           "description": "Maxium value for the parameter",
+           "type": "uint64"
+          },
+          "current-value": {
+           "description": "Current value for the parameter",
+           "type": "uint64"
+          },
+          "step-value": {
+           "description": "Step value for the parameter",
+           "type": "uint64"
+          },
+          "units": {
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-param": {
+       "list": {
+        "action-param": {
+         "description": "List of action parameters to\ncontrol VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameter",
+           "type": "string"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameters": {
+       "description": "",
+       "list": {
+        "input-parameters": {
+         "description": "List of input parameters",
+         "key": "uuid",
+         "leaf": {
+          "uuid": {
+           "description": "An identifier that uniquely identifies an input parameter",
+           "type": "string"
+          },
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          },
+          "value": {
+           "description": "The value that the element specified by the xpath should take when a\nrecord is created.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameters-descriptor": {
+       "description": "Input parameters in the descriptor",
+       "list": {
+        "input-parameters": {
+         "description": "List of input parameters",
+         "key": "uuid",
+         "leaf": {
+          "uuid": {
+           "description": "An identifier that uniquely identifies an input parameter",
+           "type": "string"
+          },
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter-xpath": {
+       "list": {
+        "input-parameter-xpath": {
+         "description": "List of xpaths to parameters inside the NSD\nthe can be customized during the instantiation.",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "An xpath that specifies the element in a descriptor.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "nfvi-metrics": {
+       "container": {
+        "vcpu": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "VCPU"
+          },
+          "total": {
+           "description": "The total number of VCPUs available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The VCPU utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "memory": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "MEMORY"
+          },
+          "used": {
+           "description": "The amount of memory (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of memory (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The memory utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "storage": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "STORAGE"
+          },
+          "used": {
+           "description": "The amount of storage (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of storage (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The storage utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "external-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "EXTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of external ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "internal-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "INTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of internal ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "network": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "NETWORK TRAFFIC"
+          }
+         },
+         "container": {
+          "incoming": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "INCOMING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of incoming bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of incoming packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current incoming byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current incoming packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          },
+          "outgoing": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "OUTGOING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of outgoing bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of outgoing packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current outgoing byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current outgoing packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  },
+  "rw-pb-ext": {
+   "module": {
+    "rw-pb-ext": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-pb-ext",
+     "prefix": "rwpb",
+     "revision": {
+      "2014-03-28": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang extensions for converting yang files to Google\nProtocol Buffers (protobuf) using rift protoc-c extensions."
+      }
+     }
+    }
+   }
+  },
+  "rwvcs-types": {
+   "module": {
+    "rwvcs-types": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rwvcs-types",
+     "prefix": "rwvcstypes"
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "pkgdir": "/Users/kkashalk/dev/rift/modules/ui/composer/webapp/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/rw.vnffgd-yang.json b/skyquake/plugins/composer/src/schemas/yang/rw.vnffgd-yang.json
new file mode 100644 (file)
index 0000000..42da1a0
--- /dev/null
@@ -0,0 +1,1719 @@
+{
+ "synth": "source",
+ "name": "vnffgd",
+ "schema": {
+  "module": {
+   "vnffgd": {
+    "namespace": "urn:ietf:params:xml:ns:yang:nfvo:vnffgd",
+    "prefix": "vnffgd",
+    "import": {
+     "rw-pb-ext": {
+      "prefix": "rwpb"
+     },
+     "ietf-inet-types": {
+      "prefix": "inet"
+     },
+     "ietf-yang-types": {
+      "prefix": "yang"
+     },
+     "mano-types": {
+      "prefix": "manotypes"
+     }
+    },
+    "revision": {
+     "2014-10-27": {
+      "description": "Initial revision. This YANG file defines\nthe VNF Forwarding Graph Descriptor (VNFFGD)",
+      "reference": "Derived from earlier versions of base YANG files"
+     }
+    },
+    "container": {
+     "vnffgd-catalog": {
+      "list": {
+       "vnffgd": {
+        "key": "id",
+        "leaf": {
+         "name": {
+          "description": "VNF Forwarding Graph Descriptor name.",
+          "type": "string"
+         },
+         "id": {
+          "description": "Identifier for the VNFFGD.",
+          "type": "yang:uuid"
+         },
+         "provider": {
+          "description": "Provider of the VNFFGD.",
+          "type": "string"
+         },
+         "description": {
+          "description": "Description of the VNFFGD.",
+          "type": "string"
+         },
+         "version": {
+          "description": "Version of the VNFFGD",
+          "type": "string"
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "dependencies": {
+  "rw-pb-ext": {
+   "module": {
+    "rw-pb-ext": {
+     "namespace": "http://riftio.com/ns/riftware-1.0/rw-pb-ext",
+     "prefix": "rwpb",
+     "revision": {
+      "2014-03-28": {
+       "description": "Initial revision.",
+       "reference": "RIFT yang extensions for converting yang files to Google\nProtocol Buffers (protobuf) using rift protoc-c extensions."
+      }
+     },
+     "extension": {
+      "msg-new": {
+       "argument": "typename",
+       "description": "Generate an equivalent, top-level, protobuf message for this\ncontainer, list, rpc input, rpc output, or notification.  The\nargument is the name of the protobuf message type.  Allowed\nvalues are valid C identifiers.\n\nThe protobuf definition will only be generated when processing\nthe same module that defines the yang object - a duplicate will\nnot be generated when importing reusing a yang object via uses,\nor when importing the module."
+      },
+      "msg-name": {
+       "argument": "typename",
+       "description": "Change the name of an embedded protobuf message type for this\ncontainer or list.  Allowed values are valid C identifiers.\n\nIn lieu of this extension, embedded protobuf message typenames\nare based on the fieldname, and further mangled by removing\nunderscores and CamelCased at underscore boundaries.  This\nextension allows the automatic mangling procedure to be\noverridden.\n\nThis extension is incompatible with msg-new, which already\ndefines the typename for top-level messages.  Use this extension\nsolely for embedded messages."
+      },
+      "msg-flat": {
+       "argument": "selection",
+       "description": "Set the protobuf message rw_msgopts flat option on a container\nor list statement.  Allowed values are 'true', 'false', and\n'auto'.  The default is 'false' for top-level messages, and\n'auto' for embedded messages.  If 'auto' is specified, the\nbehavior is the same as the enclosing container or list.\n\nUnless overridden, this extension effectively applies to all\nenclosed descendent container and list statements.  Flatness will\nbe required by the protobuf compilation step."
+      },
+      "msg-tag-base": {
+       "argument": "value",
+       "description": "Specify a base tag value for a container, list, grouping, or\nuses statement.  Field tags may be specified relative to this\nbase.  Allowed values are positive\ndecimal integers."
+      },
+      "msg-proto-max-size": {
+       "argument": "value",
+       "description": "Specify the maximum size of this message in the C structure or\nso in bytes.  Allowed values are positive decimal integers."
+      },
+      "msg-typedef": {
+       "argument": "typename",
+       "description": "Create a prototbuf-c message typedef for the original, base\ndefinition of the container, list, grouping, rpc input, rpc\noutput, or notification.  Allowed values are valid C identifiers.\n\ntypename will be appended to the mangeled protobuf package name\nand an underscore, to ensure name uniqueness across the global\nschema.\n\nThe typedef will only be generated when processing\nthe same module that defines the yang object - a duplicate will\nnot be generated when importing reusing a yang object via uses,\nor when importing the module."
+      },
+      "field-name": {
+       "argument": "fieldname",
+       "description": "Change the name of the element to fieldname, when converting the\nobject to protobuf.  Allowed values are valid C identifiers.\n\nIn lieu of this extension, element names will be used as-is, if\npossible, or mangled to fit in the C identifier character space\n(invalid C identifier characters will be replaced with\nunderscore).  This extension allows the automatic mangling\nprocedure to be overridden."
+      },
+      "field-inline": {
+       "argument": "selection",
+       "description": "Set the protobuf field 'inline' option on a container, list,\nleaf-list, or leaf statement.  Allowed values are 'true',\n'false', and 'auto'.  If 'auto' is specified, the behavior is\ncontrolled by the enclosing container or list's protobuf-msg-flat\nsetting.\n\nWhen applied to a container or list statement, this extension is\ninherited by all enclosed objects, unless overridden."
+      },
+      "field-inline-max": {
+       "argument": "limit",
+       "description": "Set the protobuf field 'inline_max' option for list and\nleaf-list statements.  Allowed values are a positive decimal\ninteger, 'yang', or 'none'.  Example limits:\n\n '64'\n 'yang'\n 'none'\n\nIf 'none' is specified, then the inline_max protobuf extension\nwill not be used.\n\nIf 'yang' is specified, then the number of elements specified in\nthe yang 'max-elements' statement is used.  If there is no\n'max-elements' statement, the behavior defaults to 'none'.\n\nIf a decimal integer is specified, that number is used as the\nmaximum length.\n\nIf this extension is not specified, the behavior defaults to\n'yang'.  Descendant list and leaf-list objects do not inherit\nthis extension."
+      },
+      "field-string-max": {
+       "argument": "limit",
+       "description": "Set the protobuf field 'string_max' option for a leaf or\nleaf-list of type string, binary, leafref, identityref, or\ninstance-identifier.  Allowed values are a positive decimal\ninteger, 'yang', or 'none'.  An optional encoding specifier may\nalso be specified, as octet or utf8, which specifies how\ncharacters are counted.  If specified, the encoding must come\nfirst.  Example limits:\n\n 'octet 64'\n 'utf8 20'\n 'utf8 yang'\n 'utf8'\n '128'\n 'none'\n\nIf 'none' is specified, then the string_max protobuf extension\nwill not be used.  'none' cannot be combined with 'octet' or\n'utf8'.\n\nIf 'yang' is specified, the yang type must be string or binary.\nIf the yang type includes the length statement, then the\nstatements maximum length is used as the length.  Otherwise,\nbehavior defaults to 'none'.\n\nIf a decimal integer is specified, that number is used as the\nlength.\n\nThe encoding specifiers are used to determine the actual number\nof bytes used in the protobuf extension.  If the 'octet'\nspecifier is used, then the maximum length is used literally as\nthe byte length.  If the 'utf8' specified is used, then the\nmaximum length is considered to be in terms of worst-case UTF-8\ncharacters, in which case the protobuf byte length will actually\nbe 4 times the specified length.\n\nFor string and binary types, the default encoding is 'octet'.\nFor the remaining types, the default encoding is 'utf8',\nreflecting those types fundemental description as XML entities\nassumed to be encoded in UTF-8.\n\nIf this extension is not specified, then the default is 'yang'\nfor string and binary, and 'none' for the other types.  This\nextension cannot be specified on aggregate objects, and so it\ncannot be inherited."
+      },
+      "field-tag": {
+       "argument": "value",
+       "description": "Set the protobuf field tag.  Allowed values are a positive\ndecimal integer, 'auto', a base-relative addition expression, or\na field-relative addition expression.\n\nIf a decimal integer is specified, then the tag is set to the\nspecified number.  You should avoid using this form in a\ngrouping, because you may not be able to guarantee uniqueness\nacross all the uses of the group.  However, the syntax will be\nallowed.\n\nA base-relative addition expression allows the tag of a field to\nbe defined in terms of the base tag of an enclosing grouping,\ncontainer, list, or uses statement.  The expression has the form\n'+NUMBER', where NUMBER is the value to add to the base to derive\nthe current field's tag.\n\nA field-relative addition expression allows the tag of one field\nto be defined in terms of another field.  The expression has the\nform 'NAME+NUMBER', where NAME is the name of the other field,\nand NUMBER is the value to add to the other fields tag to derive\nthe current field's tag.\n\nIf this extension is not specified, the default behavior is\n'auto'."
+      },
+      "field-type": {
+       "argument": "type",
+       "description": "Override the default protobuf field type mapping for a leaf or\nleaf-list type, and use the specified protobuf type instead.\n\nAllowed values are any of the Protobuf scalar types, as\nrestricted by the yang leaf type:\n\n+---------------------------+-------------------------------+\n| (pseudo) yang leaf type   | (pseudo) protobuf scalar type |\n|---------------------------+-------------------------------+\n| int8, int16, int32        | int32, sint32, sfixed32, auto |\n+---------------------------+-------------------------------+\n| int64                     | int64, sint64, sfixed64, auto |\n+---------------------------+-------------------------------+\n| uint8, uint16, uint32     | uint32, fixed32, auto         |\n+---------------------------+-------------------------------+\n| uint64                    | uint64, fixed64, auto         |\n+---------------------------+-------------------------------+\n| decimal                   | uint64, sint64, int64,        |\n|                           | fixed64, sfixed64,            |\n|                           | float, double, auto           |\n+---------------------------+-------------------------------+\n| empty, boolean            | bool, auto                    |\n+---------------------------+-------------------------------+\n| string, leafref,          | string, auto                  |\n| identityref,              |                               |\n| instance-identifier,      |                               |\n| anyxml                    |                               |\n+---------------------------+-------------------------------+\n| bits, binary              | bytes, auto                   |\n+---------------------------+-------------------------------+\n\nIf 'auto' is specified, the default conversion will be used.  The\nprotobuf pseudo-type utf8 is equivalent to string, except that\nlength limits will be adjusted in protobuf extentions to allow\nthe string to be composed entirely of the maximum sized UTF-8\nmultibyte characters (byte length is 4 times larger than the\ncharacter length)."
+      },
+      "field-c-type": {
+       "argument": "type",
+       "description": "Override the default protoc-c C-language type mapping for a leaf\nor leaf-list type, and use the specified C type instead."
+      },
+      "package-name": {
+       "argument": "pkgname",
+       "description": "Specifies the name of the package name in the generated .proto\nfile on a module statement The argument is the name of the\npackage-name.  Allowed values are valid C identifiers When\npackage-name is not specified the generated package name defaults\nto the Yang module name"
+      },
+      "application-request-point": {
+       "description": "This extension is used temporarily until the config and data portions\nare split into different namespaces and keyspecs. This allows\napplications to provide data at a keyspec, and request config at a\ndifferent level"
+      },
+      "enum-name": {
+       "argument": "enumname",
+       "description": "Use the specified name for the enum enumerator in the .proto\ninstead of the default mangled name of the yang identifer.\nIf there is a name conflict with other enum name either specified\nexplicitly or generated one, the yangpbc conversion will fail.\nAllowed values are valid C identifiers."
+      },
+      "enum-type": {
+       "argument": "enumtypename",
+       "description": "Use the specified name for the enum type in the .proto instead\nof the default mangled name of the yang identifier.  If there is\na name conflict with another enum type, either auto-generated or\nexplicitly specified one, the yangpbc conversion will fail.\nAllowed values are valid C identifiers."
+      },
+      "file-pbc-include": {
+       "argument": "pathstring",
+       "description": "A module level extension to specify the include files for pb-c.h\nwhen any rift specific c-types are used.  This extension can\noccur multiple times as a child of module statement.  The value\nshould be a valid path string."
+      },
+      "field-merge-behavior": {
+       "argument": "value",
+       "description": "An extension for controlling the merge done for listy types\nduring upacking of protobuf. It can take 3 different value:\n\n1) default: The default is whatever protobuf-c does today\n   (for keyed lists, the default is equivalent to by-keys).\n\n2) by-keys: allowed on keyed lists (and leaf-lists): merge\n   elements with matching key.\n\n3) none: allowed on keyed lists (and leaf-lists): do not\n   attempt to merge elements. This must ONLY be used when it\n   is known or expected that the proto message would contain\n   large number of list items."
+      }
+     }
+    }
+   }
+  },
+  "mano-types": {
+   "module": {
+    "mano-types": {
+     "namespace": "urn:ietf:params:xml:ns:yang:nfvo:mano-types",
+     "prefix": "manotypes",
+     "import": {
+      "ietf-inet-types": {
+       "prefix": "inet"
+      }
+     },
+     "revision": {
+      "2015-04-23": {
+       "description": "Initial revision. This YANG file defines\nthe reusable base types for VNF Management\nand Orchestration (MANO).",
+       "reference": "Derived from earlier versions of base YANG files"
+      }
+     },
+     "typedef": {
+      "virtual-link-type": {
+       "description": "Type of virtual link\nELAN: A multipoint service connecting a set of VNFs\n// ELINE: For a simple point to point connection\n//        between a VNF and the existing network.\n// ETREE: A multipoint service connecting one or\n//        more roots and a set of leaves, but\n//        preventing inter-leaf communication.",
+       "type": {
+        "enumeration": {
+         "enum": "ELAN"
+        }
+       }
+      },
+      "http-method": {
+       "description": "Type of HTTP operation",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "POST": null,
+          "PUT": null,
+          "GET": null,
+          "DELETE": null,
+          "OPTIONS": null,
+          "PATCH": null
+         }
+        }
+       }
+      },
+      "api-type": {
+       "description": "Type of API to fetch monitoring params",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HTTP": null,
+          "NETCONF": null,
+          "SOAP": null
+         }
+        }
+       }
+      },
+      "json-query-method": {
+       "description": "The method to extract a value from a JSON response\n\nNAMEKEY - Use the name as the key for a non-nested value.\nJSONPATH - Use jsonpath-rw implemenation to extract a value.\nOBJECTPATH - Use objectpath implemenation to extract a value.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "NAMEKEY": null,
+          "JSONPATH": null,
+          "OBJECTPATH": null
+         }
+        }
+       }
+      },
+      "param-value-type": {
+       "description": "The type of the parameter value",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "INT": null,
+          "DECIMAL": null,
+          "STRING": null
+         }
+        }
+       }
+      },
+      "connection-point-type": {
+       "description": "Type of connection point\nVPORT: Virtual Port\n// VNIC_ADDR: Virtual NIC Address\n// PNIC_ADDR: Physical NIC Address\n// PPORT: Phsical Port.",
+       "type": {
+        "enumeration": {
+         "enum": "VPORT"
+        }
+       }
+      },
+      "widget-type": {
+       "description": "Type of the widget, typically used by the UI.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "HISTOGRAM": null,
+          "BAR": null,
+          "GAUGE": null,
+          "SLIDER": null,
+          "COUNTER": null,
+          "TEXTBOX": null
+         }
+        }
+       }
+      },
+      "cpu-feature-type": {
+       "description": "Enumeration for CPU features.\n\nAES: CPU supports advanced instruction set for\nAES (Advanced Encryption Standard).\n\nCAT: Cache Allocation Technology (CAT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to specify the amount\nof L3 cache (currently the last-level cache\nin most server and client platforms) space an\napplication can fill (as a hint to hardware\nfunctionality, certain features such as power\nmanagement may override CAT settings).\n\nCMT: Cache Monitoring Technology (CMT) allows\nan Operating System, Hypervisor, or similar\nsystem management agent to determine the\nusage of cache based on applications running\non the platform. The implementation is\ndirected at L3 cache monitoring (currently\nthe last-level cache in most server and\nclient platforms).\n\nDDIO: Intel Data Direct I/O (DDIO) enables\nEthernet server NICs and controllers talk\ndirectly to the processor cache without a\ndetour via system memory. This enumeration\nspecifies if the VM requires a DDIO\ncapable host.",
+       "type": {
+        "enumeration": {
+         "enum": {
+          "PREFER_AES": null,
+          "REQUIRE_AES": null,
+          "PREFER_CAT": null,
+          "REQUIRE_CAT": null,
+          "PREFER_CMT": null,
+          "REQUIRE_CMT": null,
+          "PREFER_DDIO": null,
+          "REQUIRE_DDIO": null
+         }
+        }
+       }
+      }
+     },
+     "grouping": {
+      "named-value": {
+       "leaf": {
+        "name": {
+         "type": "string"
+        },
+        "value": {
+         "type": "string"
+        }
+       }
+      },
+      "vm-flavor": {
+       "container": {
+        "vm-flavor": {
+         "leaf": {
+          "vcpu-count": {
+           "description": "Number of vcpus for the VM.",
+           "type": "uint16"
+          },
+          "memory-mb": {
+           "description": "Amount of memory in MB.",
+           "type": "uint64"
+          },
+          "storage-gb": {
+           "description": "Amount of disk space in GB.",
+           "type": "uint64"
+          }
+         }
+        }
+       }
+      },
+      "vswitch-epa": {
+       "container": {
+        "vswitch-epa": {
+         "leaf": {
+          "ovs-acceleration": {
+           "description": "Specifies Open vSwitch acceleration mode.\nMANDATORY: OVS acceleration is required\nPREFERRED: OVS acceleration is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": null,
+              "PREFERRED": null,
+              "DISABLED": null
+             }
+            }
+           }
+          },
+          "ovs-offload": {
+           "description": "Specifies Open vSwitch hardware offload mode.\nMANDATORY: OVS offload is required\nPREFERRED: OVS offload is preferred",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "MANDATORY": null,
+              "PREFERRED": null,
+              "DISABLED": null
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "hypervisor-epa": {
+       "container": {
+        "hypervisor-epa": {
+         "leaf": {
+          "type": {
+           "description": "Specifies the type of hypervisor.\nKVM: KVM\nXEN: XEN",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_KVM": null,
+              "REQUIRE_KVM": null
+             }
+            }
+           }
+          },
+          "version": {
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "host-epa": {
+       "container": {
+        "host-epa": {
+         "description": "Specifies the host level EPA attributes.",
+         "leaf": {
+          "cpu-model": {
+           "description": "Host CPU model. Examples include: SandyBridge,\nIvyBridge",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_WESTMERE": null,
+              "REQUIRE_WESTMERE": null,
+              "PREFER_SANDYBRIDGE": null,
+              "REQUIRE_SANDYBRIDGE": null,
+              "PREFER_IVYBRIDGE": null,
+              "REQUIRE_IVYBRIDGE": null,
+              "PREFER_HASWELL": null,
+              "REQUIRE_HASWELL": null,
+              "PREFER_BROADWELL": null,
+              "REQUIRE_BROADWELL": null,
+              "PREFER_NEHALEM": null,
+              "REQUIRE_NEHALEM": null,
+              "PREFER_PENRYN": null,
+              "REQUIRE_PENRYN": null,
+              "PREFER_CONROE": null,
+              "REQUIRE_CONROE": null,
+              "PREFER_CORE2DUO": null,
+              "REQUIRE_CORE2DUO": null
+             }
+            }
+           }
+          },
+          "cpu-arch": {
+           "description": "Host CPU architecture.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_X86": null,
+              "REQUIRE_X86": null,
+              "PREFER_X86_64": null,
+              "REQUIRE_X86_64": null,
+              "PREFER_I686": null,
+              "REQUIRE_I686": null,
+              "PREFER_IA64": null,
+              "REQUIRE_IA64": null,
+              "PREFER_ARMV7": null,
+              "REQUIRE_ARMV7": null,
+              "PREFER_ARMV8": null,
+              "REQUIRE_ARMV8": null
+             }
+            }
+           }
+          },
+          "cpu-vendor": {
+           "description": "Host CPU Vendor.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_INTEL": null,
+              "REQUIRE_INTEL": null,
+              "PREFER_AMD": null,
+              "REQUIRE_AMD": null
+             }
+            }
+           }
+          },
+          "cpu-socket-count": {
+           "description": "Number of sockets on the host.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "PREFER_ONE": null,
+              "PREFER_TWO": null,
+              "REQUIRE_ONE": null,
+              "REQUIRE_TWO": null
+             }
+            }
+           }
+          },
+          "cpu-core-count": {
+           "description": "Number of cores on the host.",
+           "type": "uint64"
+          },
+          "om-cpu-model-string": {
+           "description": "Openmano CPU model string",
+           "type": "string"
+          }
+         },
+         "leaf-list": {
+          "cpu-feature": {
+           "description": "List of CPU features.",
+           "type": "manotypes:cpu-feature-type"
+          },
+          "om-cpu-feature": {
+           "description": "Openmano CPU features",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "guest-epa": {
+       "description": "EPA attributes for the guest",
+       "container": {
+        "guest-epa": {
+         "leaf": {
+          "trusted-execution": {
+           "description": "This VM should be allocated from trusted pool",
+           "type": "boolean"
+          },
+          "mempage-size": {
+           "description": "Memory page allocation size. If a VM requires\nhugepages, it should choose LARGE or SIZE_2MB\nor SIZE_1GB. If the VM prefers hugepages it\nshould chose PREFER_LARGE.\nLARGE        : Require hugepages (either 2MB or 1GB)\nSMALL        : Doesn't require hugepages\nSIZE_2MB     : Requires 2MB hugepages\nSIZE_1GB     : Requires 1GB hugepages\nPREFER_LARGE : Application perfers hugepages",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LARGE": null,
+              "SMALL": null,
+              "SIZE_2MB": null,
+              "SIZE_1GB": null,
+              "PREFER_LARGE": null
+             }
+            }
+           }
+          },
+          "cpu-pinning-policy": {
+           "description": "CPU pinning policy describes association\nbetween virtual CPUs in guest and the\nphysical CPUs in the host.\nDEDICATED : Virtual CPUs are pinned to\n            physical CPUs\nSHARED    : Multiple VMs may share the\n            same physical CPUs.\nANY       : Any policy is acceptable for the VM",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "DEDICATED": null,
+              "SHARED": null,
+              "ANY": null
+             }
+            }
+           },
+           "default": "ANY"
+          },
+          "cpu-thread-pinning-policy": {
+           "description": "CPU thread pinning policy describes how to\nplace the guest CPUs when the host supports\nhyper threads:\nAVOID   : Avoids placing a guest on a host\n          with threads.\nSEPARATE: Places vCPUs on separate cores,\n          and avoids placing two vCPUs on\n          two threads of same core.\nISOLATE : Places each vCPU on a different core,\n          and places no vCPUs from a different\n          guest on the same core.\nPREFER  : Attempts to place vCPUs on threads\n          of the same core.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "AVOID": null,
+              "SEPARATE": null,
+              "ISOLATE": null,
+              "PREFER": null
+             }
+            }
+           }
+          }
+         },
+         "list": {
+          "pcie-device": {
+           "description": "List of pcie passthrough devices.",
+           "key": "device-id",
+           "leaf": {
+            "device-id": {
+             "description": "Device identifier.",
+             "type": "string"
+            },
+            "count": {
+             "description": "Number of devices to attach to the VM.",
+             "type": "uint64"
+            }
+           }
+          }
+         },
+         "choice": {
+          "numa-policy": {
+           "case": {
+            "numa-unware": {
+             "leaf": {
+              "numa-unware": {
+               "type": "empty"
+              }
+             }
+            },
+            "numa-aware": {
+             "container": {
+              "numa-node-policy": {
+               "description": "This policy defines numa topology of the\nguest. Specifically identifies if the guest\nshould be run on a host with one numa\nnode or multiple numa nodes. As an example\na guest may want 8 vcpus and 4 GB of\nmemory. But may want the vcpus and memory\ndistributed across multiple numa nodes.\nThe NUMA node 1 may run with 6 vcpus and\n3GB, and NUMA node 2 may run with 2 vcpus\nand 1GB.",
+               "leaf": {
+                "node-cnt": {
+                 "description": "The number of numa nodes to expose to the VM.",
+                 "type": "uint16"
+                },
+                "mem-policy": {
+                 "description": "This policy specifies how the memory should\nbe allocated in a multi-node scenario.\nSTRICT    : The memory must be allocated\n            strictly from the memory attached\n            to the NUMA node.\nPREFERRED : The memory should be allocated\n            perferentially from the memory\n            attached to the NUMA node",
+                 "type": {
+                  "enumeration": {
+                   "enum": {
+                    "STRICT": null,
+                    "PREFERRED": null
+                   }
+                  }
+                 }
+                }
+               },
+               "list": {
+                "node": {
+                 "key": "id",
+                 "leaf": {
+                  "id": {
+                   "description": "NUMA node identification. Typically\nit's 0 or 1",
+                   "type": "uint64"
+                  },
+                  "memory-mb": {
+                   "description": "Memory size expressed in MB\nfor this NUMA node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "leaf-list": {
+                  "vcpu": {
+                   "description": "List of vcpus to allocate on\nthis numa node.",
+                   "type": "uint64"
+                  }
+                 },
+                 "choice": {
+                  "om-numa-type": {
+                   "description": "Openmano Numa type selection",
+                   "case": {
+                    "cores": {
+                     "leaf": {
+                      "num-cores": {
+                       "type": "uint8"
+                      }
+                     }
+                    },
+                    "paired-threads": {
+                     "container": {
+                      "paired-threads": {
+                       "leaf": {
+                        "num-paired-threads": {
+                         "type": "uint8"
+                        }
+                       },
+                       "list": {
+                        "paired-thread-ids": {
+                         "description": "List of thread pairs to use in case of paired-thread numa",
+                         "max-elements": "16",
+                         "key": "thread-a",
+                         "leaf": {
+                          "thread-a": {
+                           "type": "uint8"
+                          },
+                          "thread-b": {
+                           "type": "uint8"
+                          }
+                         }
+                        }
+                       }
+                      }
+                     }
+                    },
+                    "threads": {
+                     "leaf": {
+                      "num-threads": {
+                       "type": "uint8"
+                      }
+                     }
+                    }
+                   }
+                  }
+                 }
+                }
+               }
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "provider-network": {
+       "container": {
+        "provider-network": {
+         "description": "Container for the provider network.",
+         "leaf": {
+          "physical-network": {
+           "description": "Name of the phsyical network on which the provider\nnetwork is built.",
+           "type": "string"
+          },
+          "overlay-type": {
+           "description": "Type of the overlay network.",
+           "type": {
+            "enumeration": {
+             "enum": {
+              "LOCAL": null,
+              "FLAT": null,
+              "VLAN": null,
+              "VXLAN": null,
+              "GRE": null
+             }
+            }
+           }
+          },
+          "segmentation_id": {
+           "description": "Segmentation ID",
+           "type": "uint32"
+          }
+         }
+        }
+       }
+      },
+      "monitoring-param": {
+       "list": {
+        "http-endpoint": {
+         "description": "List of http endpoints to be used by monitoring params",
+         "key": "path",
+         "leaf": {
+          "path": {
+           "description": "The HTTP path on the management server",
+           "type": "string"
+          },
+          "https": {
+           "description": "Pick HTTPS instead of HTTP , Default is false",
+           "type": "boolean",
+           "default": "false"
+          },
+          "port": {
+           "description": "The HTTP port to connect to",
+           "type": "inet:port-number"
+          },
+          "username": {
+           "description": "The HTTP basic auth username",
+           "type": "string"
+          },
+          "password": {
+           "description": "The HTTP basic auth password",
+           "type": "string"
+          },
+          "polling_interval_secs": {
+           "description": "The HTTP polling interval in seconds",
+           "type": "uint8",
+           "default": "2"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nGET by default for action",
+           "type": "manotypes:http-method",
+           "default": "GET"
+          }
+         },
+         "list": {
+          "headers": {
+           "description": "Custom HTTP headers to put on HTTP request",
+           "key": "key",
+           "leaf": {
+            "key": {
+             "description": "HTTP header key",
+             "type": "string"
+            },
+            "value": {
+             "description": "HTTP header value",
+             "type": "string"
+            }
+           }
+          }
+         }
+        },
+        "monitoring-param": {
+         "description": "List of monitoring parameters at the NS level",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "http-endpoint-ref": {
+           "type": {
+            "leafref": {
+             "path": "../../http-endpoint/path"
+            }
+           }
+          },
+          "json-query-method": {
+           "type": "manotypes:json-query-method",
+           "default": "NAMEKEY"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameters",
+           "type": "string"
+          },
+          "value-type": {
+           "type": "manotypes:param-value-type",
+           "default": "INT"
+          },
+          "value-integer": {
+           "description": "Current value for an integer parameter",
+           "type": "int64"
+          },
+          "value-decimal": {
+           "description": "Current value for a decimal parameter",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "4"
+            }
+           }
+          },
+          "value-string": {
+           "description": "Current value for a string parameter",
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "units": {
+           "type": "string"
+          }
+         },
+         "container": {
+          "json-query-params": {
+           "leaf": {
+            "json-path": {
+             "description": "The jsonpath to use to extract value from JSON structure",
+             "type": "string"
+            },
+            "object-path": {
+             "description": "The objectpath to use to extract value from JSON structure",
+             "type": "string"
+            }
+           }
+          },
+          "numeric-constraints": {
+           "leaf": {
+            "min-value": {
+             "description": "Minimum value for the parameter",
+             "type": "uint64"
+            },
+            "max-value": {
+             "description": "Maxium value for the parameter",
+             "type": "uint64"
+            }
+           }
+          },
+          "text-constraints": {
+           "leaf": {
+            "min-length": {
+             "description": "Minimum string length for the parameter",
+             "type": "uint8"
+            },
+            "max-length": {
+             "description": "Maximum string length for the parameter",
+             "type": "uint8"
+            }
+           }
+          }
+         }
+        }
+       }
+      },
+      "control-param": {
+       "list": {
+        "control-param": {
+         "description": "List of control parameters to manage and\nupdate the running configuration of the VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group control parameters",
+           "type": "string"
+          },
+          "min-value": {
+           "description": "Minimum value for the parameter",
+           "type": "uint64"
+          },
+          "max-value": {
+           "description": "Maxium value for the parameter",
+           "type": "uint64"
+          },
+          "current-value": {
+           "description": "Current value for the parameter",
+           "type": "uint64"
+          },
+          "step-value": {
+           "description": "Step value for the parameter",
+           "type": "uint64"
+          },
+          "units": {
+           "type": "string"
+          },
+          "widget-type": {
+           "type": "manotypes:widget-type"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template as stringified\nJSON. This field provides the data  to be sent for this operation\ncall",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "action-param": {
+       "list": {
+        "action-param": {
+         "description": "List of action parameters to\ncontrol VNF",
+         "key": "id",
+         "leaf": {
+          "id": {
+           "type": "string"
+          },
+          "name": {
+           "type": "string"
+          },
+          "description": {
+           "type": "string"
+          },
+          "group-tag": {
+           "description": "A simple tag to group monitoring parameter",
+           "type": "string"
+          },
+          "url": {
+           "description": "This is the URL where to perform the operation",
+           "type": "inet:uri"
+          },
+          "method": {
+           "description": "This is the method to be performed at the uri.\nPOST by default for action",
+           "type": "manotypes:http-method",
+           "default": "POST"
+          },
+          "payload": {
+           "description": "This is the operation payload or payload template to be sent in\nthe data for this operation call",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter": {
+       "description": "",
+       "list": {
+        "input-parameter": {
+         "description": "List of input parameters",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "A an xpath that specfies which element in a descriptor is to be\nmodified.",
+           "type": "string"
+          },
+          "value": {
+           "description": "The value that the element specified by the xpath should take when a\nrecord is created.",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "input-parameter-xpath": {
+       "list": {
+        "input-parameter-xpath": {
+         "description": "List of xpaths to parameters inside the NSD\nthe can be customized during the instantiation.",
+         "key": "xpath",
+         "leaf": {
+          "xpath": {
+           "description": "An xpath that specifies the element in a descriptor.",
+           "type": "string"
+          },
+          "label": {
+           "description": "A descriptive string",
+           "type": "string"
+          }
+         }
+        }
+       }
+      },
+      "nfvi-metrics": {
+       "container": {
+        "vcpu": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "VCPU"
+          },
+          "total": {
+           "description": "The total number of VCPUs available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The VCPU utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "memory": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "MEMORY"
+          },
+          "used": {
+           "description": "The amount of memory (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of memory (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The memory utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "storage": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "STORAGE"
+          },
+          "used": {
+           "description": "The amount of storage (bytes) currently in use.",
+           "type": "uint64"
+          },
+          "total": {
+           "description": "The amount of storage (bytes) available.",
+           "type": "uint64"
+          },
+          "utilization": {
+           "description": "The storage utilization (percentage).",
+           "type": {
+            "decimal64": {
+             "fraction-digits": "2",
+             "range": "0 .. 100"
+            }
+           }
+          }
+         }
+        },
+        "external-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "EXTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of external ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "internal-ports": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "INTERNAL PORTS"
+          },
+          "total": {
+           "description": "The total number of internal ports.",
+           "type": "uint64"
+          }
+         }
+        },
+        "network": {
+         "leaf": {
+          "label": {
+           "description": "Label to show in UI",
+           "type": "string",
+           "default": "NETWORK TRAFFIC"
+          }
+         },
+         "container": {
+          "incoming": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "INCOMING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of incoming bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of incoming packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current incoming byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current incoming packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          },
+          "outgoing": {
+           "leaf": {
+            "label": {
+             "description": "Label to show in UI",
+             "type": "string",
+             "default": "OUTGOING NETWORK TRAFFIC"
+            },
+            "bytes": {
+             "description": "The cumulative number of outgoing bytes.",
+             "type": "uint64"
+            },
+            "packets": {
+             "description": "The cumulative number of outgoing packets.",
+             "type": "uint64"
+            },
+            "byte-rate": {
+             "description": "The current outgoing byte-rate (bytes per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            },
+            "packet-rate": {
+             "description": "The current outgoing packet (packets per second).",
+             "type": {
+              "decimal64": {
+               "fraction-digits": "2"
+              }
+             }
+            }
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+  }
+ },
+ "extension": {
+  "module": {
+   "argument": "name",
+   "include": "0..n",
+   "prefix": "0..1",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "namespace": "0..1",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, match, ref, synth, target;\n  synth = this.require('data-synth');\n  ref = params.augment;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  return delete this.source[params.prefix];\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var k, m, modules, ref, synth, v;\n  synth = this.require('data-synth');\n  modules = {};\n  ref = params[\"import\"];\n  for (k in ref) {\n    v = ref[k];\n    modules[k] = children[k];\n    delete children[k];\n  }\n  m = (synth.Store(params, function() {\n    return this.set({\n      name: arg,\n      modules: modules\n    });\n  })).bind(children);\n  this.define('module', arg, m);\n  return m;\n}"
+   }
+  },
+  "prefix": {
+   "argument": "value",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[arg] = this.source;\n}"
+   }
+  },
+  "include": {
+   "argument": "module",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, m, ref, ref1, ref2, results, v;\n  m = this.preprocess(this.resolve('dependencies', arg));\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    this.define('extension', k, v);\n  }\n  ref1 = m.typedef;\n  for (k in ref1) {\n    v = ref1[k];\n    this.define('typedef', k, v);\n  }\n  ref2 = m.schema;\n  results = [];\n  for (k in ref2) {\n    v = ref2[k];\n    results.push(ctx[k] = v);\n  }\n  return results;\n}"
+   },
+   "revision-date": "0..1"
+  },
+  "augment": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "target-node"
+  },
+  "belongs-to": {
+   "prefix": 1,
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.source[params.prefix] = this.source;\n}"
+   },
+   "argument": "module"
+  },
+  "bit": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "position": "0..1",
+   "argument": "name"
+  },
+  "case": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "argument": "name"
+  },
+  "choice": {
+   "anyxml": "0..n",
+   "case": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "mandatory": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "argument": "condition"
+  },
+  "config": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.config = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "container": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "must": "0..n",
+   "presence": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   },
+   "argument": "name"
+  },
+  "deviate": {
+   "config": "0..1",
+   "default": "0..1",
+   "mandatory": "0..1",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "type": "0..1",
+   "unique": "0..1",
+   "units": "0..1",
+   "argument": "value"
+  },
+  "deviation": {
+   "description": "0..1",
+   "deviate": "1..n",
+   "reference": "0..1",
+   "argument": "target-node"
+  },
+  "enum": {
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "value": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.value == null) {\n    if (this.enumValue == null) {\n      this.enumValue = 0;\n    }\n    params.value = this.enumValue++;\n  } else {\n    params.value = Number(params.value);\n    this.enumValue = params.value + 1;\n  }\n  return ctx[\"enum\"][arg] = params;\n}"
+   },
+   "argument": "name"
+  },
+  "feature": {
+   "description": "0..1",
+   "if-feature": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (params.status === 'unavailable') {\n    console.warn(\"feature \" + arg + \" is unavailable\");\n    if (typeof ctx.feature === 'object') {\n      return delete ctx.feature[arg];\n    } else {\n      return delete ctx.feature;\n    }\n  }\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var feature;\n  feature = this.resolve('feature', arg);\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "grouping": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('grouping', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "identity": {
+   "base": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('identity', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "if-feature": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if ((this.resolve('feature', arg)) == null) {\n    return ctx.status = 'unavailable';\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "import": {
+   "prefix": 1,
+   "revision-date": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var copy, k, m, original, ref, ref1, rev, schema, source, synth, v;\n  synth = this.require('data-synth');\n  schema = this.resolve('dependencies', arg, false);\n  if (schema == null) {\n    console.warn(\"no explicit dependency for \" + arg + \" defined, searching local filesystem\");\n    schema = this.parse(\"!yang \" + arg + \".yang\", this.source);\n    if (schema != null) {\n      this.define('dependencies', arg, schema);\n      source = this.source.parent;\n      while ((source.parent != null) && source.parent.name !== 'yangforge') {\n        source = source.parent;\n      }\n      if (source.dependencies == null) {\n        source.dependencies = {};\n      }\n      source.dependencies[arg] = schema;\n    }\n  }\n  m = this.preprocess(schema);\n  if (m == null) {\n    throw this.error(\"unable to resolve '\" + arg + \"' in dependencies\", 'import');\n  }\n  rev = params['revision-date'];\n  if ((rev != null) && !(rev in m.revision)) {\n    throw this.error(\"requested \" + rev + \" not available in \" + arg, 'import');\n  }\n  ref = m.extension;\n  for (k in ref) {\n    v = ref[k];\n    if (!(v.override === true)) {\n      continue;\n    }\n    original = this.resolve('extension', k);\n    copy = synth.copy({}, v);\n    copy.origin = synth.copy({}, (ref1 = original.origin) != null ? ref1 : original);\n    delete copy.override;\n    this.define('extension', k, copy);\n  }\n  return this.source[params.prefix] = m;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  return this.compile(this.source[params.prefix], this.source);\n}"
+   },
+   "argument": "module"
+  },
+  "input": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "leaf": {
+   "config": "0..1",
+   "default": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "mandatory": "0..1",
+   "must": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.Property(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "leaf-list": {
+   "config": "0..1",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "type": "0..1",
+   "units": "0..1",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return synth.List(params, function() {\n    if (children.type != null) {\n      return this.set({\n        type: children.type\n      });\n    }\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "list": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "config": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "key": "0..1",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "max-elements": "0..1",
+   "min-elements": "0..1",
+   "must": "0..n",
+   "ordered-by": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "unique": "0..1",
+   "uses": "0..n",
+   "when": "0..1",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var item, synth;\n  synth = this.require('data-synth');\n  item = (synth.Object(null)).bind(children);\n  return (synth.List(params)).set({\n    type: item\n  });\n}"
+   },
+   "argument": "name"
+  },
+  "mandatory": {
+   "preprocess": {
+    "!js/function": "function (arg, p, ctx) {\n  return ctx.mandatory = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "max-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  if (arg !== 'unbounded') {\n    return ctx['max-elements'] = Number(arg);\n  }\n}"
+   },
+   "argument": "value"
+  },
+  "min-elements": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['min-elements'] = Number(arg);\n}"
+   },
+   "argument": "value"
+  },
+  "must": {
+   "description": "0..1",
+   "error-app-tag": "0..1",
+   "error-message": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "notification": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('notification', arg, params);\n}"
+   },
+   "argument": "event"
+  },
+  "output": {
+   "anyxml": "0..n",
+   "choice": "0..n",
+   "container": "0..n",
+   "grouping": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var synth;\n  synth = this.require('data-synth');\n  return (synth.Object(params)).bind(children);\n}"
+   }
+  },
+  "path": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.path = arg.replace(/[_]/g, '.');\n}"
+   },
+   "argument": "value"
+  },
+  "pattern": {
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  if (ctx.patterns == null) {\n    ctx.patterns = [];\n  }\n  return ctx.patterns.push(new RegExp(arg));\n}"
+   },
+   "argument": "value"
+  },
+  "refine": {
+   "default": "0..1",
+   "description": "0..1",
+   "reference": "0..1",
+   "config": "0..1",
+   "mandatory": "0..1",
+   "presence": "0..1",
+   "must": "0..n",
+   "min-elements": "0..1",
+   "max-elements": "0..1",
+   "units": "0..1",
+   "argument": "target-node"
+  },
+  "require-instance": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx['require-instance'] = arg === true || arg === 'true';\n}"
+   },
+   "argument": "value"
+  },
+  "revision": {
+   "description": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return this.define('revision', arg, params);\n}"
+   },
+   "argument": "date"
+  },
+  "rpc": {
+   "description": "0..1",
+   "grouping": "0..n",
+   "if-feature": "0..n",
+   "input": "0..1",
+   "output": "0..1",
+   "reference": "0..1",
+   "status": "0..1",
+   "typedef": "0..n",
+   "construct": {
+    "!js/function": "function (arg, params, children) {\n  var func, method, ref, ref1, request, response, synth;\n  synth = this.require('data-synth');\n  func = this.resolve('rpc', arg, false);\n  if (func == null) {\n    func = function(input, output, done) {\n      return done(\"No control logic found for '\" + arg + \"' rpc operation\");\n    };\n  }\n  request = (ref = children.input) != null ? ref : synth.Meta;\n  response = (ref1 = children.output) != null ? ref1 : synth.Meta;\n  method = function(data, resolve, reject) {\n    var e, error, input, output;\n    if (typeof console.debug === \"function\") {\n      console.debug(\"executing rpc \" + arg + \"...\");\n    }\n    try {\n      input = new request(data, this);\n      output = new response(null, this);\n    } catch (error) {\n      e = error;\n      return reject(e);\n    }\n    return func.call(this, input, output, function(e) {\n      if (e == null) {\n        return resolve(output);\n      } else {\n        return reject(e);\n      }\n    });\n  };\n  method.params = params;\n  method.input = request;\n  method.output = response;\n  return method;\n}"
+   },
+   "argument": "name"
+  },
+  "submodule": {
+   "argument": "name",
+   "anyxml": "0..n",
+   "augment": "0..n",
+   "belongs-to": "0..1",
+   "choice": "0..n",
+   "contact": "0..1",
+   "container": "0..n",
+   "description": "0..1",
+   "deviation": "0..n",
+   "extension": "0..n",
+   "feature": "0..n",
+   "grouping": "0..n",
+   "identity": "0..n",
+   "import": "0..n",
+   "include": "0..n",
+   "leaf": "0..n",
+   "leaf-list": "0..n",
+   "list": "0..n",
+   "notification": "0..n",
+   "organization": "0..1",
+   "reference": "0..1",
+   "revision": "0..n",
+   "rpc": "0..n",
+   "typedef": "0..n",
+   "uses": "0..n",
+   "yang-version": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var k, v;\n  for (k in params) {\n    v = params[k];\n    ctx[k] = v;\n  }\n  return delete ctx.submodule;\n}"
+   }
+  },
+  "status": {
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return ctx.status != null ? ctx.status : ctx.status = arg;\n}"
+   },
+   "argument": "value"
+  },
+  "type": {
+   "base": "0..1",
+   "bit": "0..n",
+   "enum": "0..n",
+   "fraction-digits": "0..1",
+   "length": "0..1",
+   "path": "0..1",
+   "pattern": "0..n",
+   "range": "0..1",
+   "require-instance": "0..1",
+   "type": "0..n",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  return delete this.enumValue;\n}"
+   },
+   "construct": {
+    "!js/function": "function (arg, params, children, ctx) {\n  var key, mparams, ref, ref1, synth, typedef, value;\n  synth = this.require('data-synth');\n  typedef = this.resolve('typedef', arg);\n  if (typedef == null) {\n    throw this.error(\"unable to resolve typedef for \" + arg);\n  }\n  switch (false) {\n    case typedef.construct == null:\n      ctx.type = typedef.construct(params, this, arguments.callee);\n      break;\n    case typeof typedef.type !== 'object':\n      ref = typedef.type;\n      for (key in ref) {\n        value = ref[key];\n        mparams = synth.copy({}, value);\n        synth.copy(mparams, params);\n        arguments.callee.call(this, key, mparams, children, ctx);\n      }\n      break;\n    case typeof typedef.type !== 'string':\n      arguments.callee.call(this, typedef.type, params, children, ctx);\n  }\n  if ((ref1 = ctx.type) != null) {\n    ref1.toString = function() {\n      return arg;\n    };\n  }\n  return null;\n}"
+   },
+   "argument": "name"
+  },
+  "typedef": {
+   "default": "0..1",
+   "description": "0..1",
+   "units": "0..1",
+   "type": "0..1",
+   "reference": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params) {\n  return this.define('typedef', arg, params);\n}"
+   },
+   "argument": "name"
+  },
+  "uses": {
+   "augment": "0..n",
+   "description": "0..1",
+   "if-feature": "0..n",
+   "refine": "0..n",
+   "reference": "0..1",
+   "status": "0..1",
+   "when": "0..1",
+   "preprocess": {
+    "!js/function": "function (arg, params, ctx) {\n  var changes, grouping, k, match, ref, ref1, synth, target, v;\n  synth = this.require('data-synth');\n  grouping = synth.copy({}, this.resolve('grouping', arg));\n  delete grouping.description;\n  delete grouping.reference;\n  synth.copy(ctx, grouping);\n  ref = params.refine;\n  for (target in ref) {\n    changes = ref[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    for (k in changes) {\n      v = changes[k];\n      match[k] = v;\n    }\n  }\n  ref1 = params.augment;\n  for (target in ref1) {\n    changes = ref1[target];\n    match = this.locate(ctx, target);\n    if (match == null) {\n      continue;\n    }\n    synth.copy(match, changes);\n  }\n  if (typeof ctx.uses === 'object') {\n    return delete ctx.uses[arg];\n  } else {\n    return delete ctx.uses;\n  }\n}"
+   },
+   "argument": "name"
+  },
+  "when": {
+   "description": "0..1",
+   "reference": "0..1",
+   "argument": "condition"
+  },
+  "anyxml": {},
+  "base": {
+   "argument": "name"
+  },
+  "contact": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "default": {
+   "argument": "value"
+  },
+  "description": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "error-app-tag": {
+   "argument": "value"
+  },
+  "error-message": {
+   "argument": {
+    "value": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "fraction-digits": {
+   "argument": "value"
+  },
+  "key": {
+   "argument": "value"
+  },
+  "length": {
+   "argument": "value"
+  },
+  "namespace": {
+   "argument": "uri"
+  },
+  "ordered-by": {
+   "argument": "value"
+  },
+  "organization": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "position": {
+   "argument": "value"
+  },
+  "presence": {
+   "argument": "value"
+  },
+  "range": {
+   "argument": "value"
+  },
+  "reference": {
+   "argument": {
+    "text": {
+     "yin-element": "true"
+    }
+   }
+  },
+  "revision-date": {
+   "argument": "date"
+  },
+  "unique": {
+   "argument": "tag"
+  },
+  "units": {
+   "argument": "value"
+  },
+  "value": {
+   "argument": "value"
+  },
+  "yang-version": {
+   "argument": "value"
+  },
+  "yin-element": {
+   "argument": "value"
+  }
+ },
+ "pkgdir": "/Users/onvelocity/rift-composer/webapp/schemas/yang",
+ "module": {}
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/schemas/yang/rwvcs-types.yang.src b/skyquake/plugins/composer/src/schemas/yang/rwvcs-types.yang.src
new file mode 100755 (executable)
index 0000000..32d9dea
--- /dev/null
@@ -0,0 +1,434 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module rwvcs-types
+{
+  namespace "http://riftio.com/ns/riftware-1.0/rwvcs-types";
+  prefix "rwvcstypes";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import rw-yang-types {
+    prefix "rwt";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+    revision-date 2013-07-15;
+  }
+
+  revision 2014-03-12 {
+    description
+      "Initial implementation of RW.Manifest.";
+    reference
+      "RW.VX Software Component Document";
+  }
+
+  typedef component_type {
+    type enumeration {
+      enum RWCOLLECTION;
+      enum RWVM;
+      enum RWPROC;
+      enum PROC;
+      enum RWTASKLET;
+    }
+  }
+
+  typedef recovery-type {
+    type enumeration {
+      enum NONE;
+      enum RESTART;
+      enum FAILCRITICAL;
+      enum IGNORE;
+      enum CUSTOM;
+    }
+  }
+
+  grouping rwvcs-variable-list {
+    leaf-list python-variable {
+      description
+          "List of Python variable assignments";
+      type string;
+    }
+  }
+
+  grouping valgrind {
+    container valgrind {
+      leaf enable {
+        description
+            "Run the component under valgrind";
+        type boolean;
+      }
+
+      leaf-list opts {
+        description
+            "Command line options to pass to valgrind";
+        type string;
+      }
+    }
+  }
+
+  grouping action-list {
+    list action {
+      description
+          "This section contains a sequence
+           of RW.VCS actions";
+      key "name";
+      //rwpb:msg-new VcsAction;
+
+      leaf name {
+        description
+            "Name of the action within the sequence";
+        type string;
+      }
+
+      grouping rwvcs-python-loop {
+        leaf python-loop-expression {
+          description "Python expression";
+          type string;
+        }
+
+        leaf python-loop-iterate {
+          description "Python iteration";
+          type string;
+        }
+      }
+      uses rwvcs-python-loop;
+
+      choice action {
+        case annex {
+          container annex {
+            leaf component-name {
+              description
+                  "Name of the component type
+                   in the inventory";
+              type leafref {
+                path "../../../../../../../component/component-name";
+              }
+            }
+            leaf instance-id {
+              description
+                  "ID of the component instance
+                   in the inventory";
+              type string;
+            }
+          }
+        }
+
+        case start {
+          container start {
+            //rwpb:msg-new ActionStart;
+
+            uses rwvcs-variable-list;
+            leaf component-name {
+              description
+                  "Name of the component type in
+                   the inventory";
+              type leafref {
+                path "../../../../../../../component/component-name";
+              }
+            }
+            leaf instance-id {
+              description
+                  "ID of the component instance
+                   in the inventory";
+              type string;
+            }
+            leaf config-ready {
+              description
+                  "Config readiness check enable";
+              type boolean;
+              default true;
+            }
+            leaf recovery-action {
+              description
+                  "Define recovery action if this component fail";
+              type recovery-type;
+            }
+          }
+        }
+
+        case sleep {
+          container sleep {
+            leaf wait-time-usec {
+              description
+                  "Time to wait while sleeping";
+              type uint32;
+            }
+          }
+        }
+      } // choice action
+    } // list action
+  } // grouping action-list
+
+  grouping rwvcs-event-list {
+    container event-list {
+      description "";
+      //rwpb:msg-new VcsEventList;
+
+      list event {
+        description
+            "This section contains a list
+             of RW.VCS events";
+        key "name";
+        //rwpb:msg-new VcsEvent;
+
+        leaf name {
+          description
+              "Name of the event";
+          type string;
+        }
+
+        uses action-list;
+      } // list event
+    } // container event-list
+  } // grouping rwvcs-event-list
+
+  grouping rwvcs-rwcollection {
+    container rwcollection {
+      description
+          "This section defines a RW.VCS
+           rwollection component";
+      //rwpb:msg-new VcsRwCollection;
+
+      leaf collection-type {
+        description "Collection type";
+        type string;
+      }
+
+      uses rwvcs-event-list;
+    }
+  }
+
+  grouping rwvcs-rwvm {
+    container rwvm {
+      description
+          "This section defines a RW.VCS
+           rwvm component";
+      //rwpb:msg-new VcsRwVm;
+
+      leaf pool-name {
+        description
+            "Name of the pool from which to
+             allocate the VM";
+        type string;
+      }
+
+      leaf leader {
+        description
+            "True if this VM is designated as a leader for
+             the parent collection.";
+        type boolean;
+      }
+
+      uses rwvcs-event-list;
+      uses valgrind;
+    }
+  }
+
+  grouping rwvcs-rwproc {
+    container rwproc {
+      description
+          "This section defines a RW.VCS
+           rwproc component";
+      //rwpb:msg-new VcsRwproc;
+
+      leaf run-as {
+        description
+            "Host OS user that should run this
+             process, requires sudo -E access
+             and non-collapsed processes";
+        type string;
+      }
+
+      list tasklet {
+        description
+            "List of tasklets to be run within
+             this process";
+        key "name";
+        //rwpb:msg-new RwprocTasklet;
+
+        leaf name {
+          description
+              "Local description of the tasklet";
+          type string;
+        }
+
+        leaf component-name {
+          description
+              "Component name of the tasklet";
+          mandatory true;
+          type string;
+        }
+
+        leaf instance-id {
+          description
+              "If specified, the desired instance-id of
+               tasklet component instance";
+          type uint32;
+        }
+
+        leaf config-ready {
+          description
+              "Config readiness check enable";
+          type boolean;
+          default true;
+        }
+
+        leaf recovery-action {
+          description
+              "Define recovery action if this component fail";
+          type recovery-type;
+        }
+
+        uses rwvcs-variable-list;
+      }
+      uses valgrind;
+    }
+  }
+
+  grouping native-proc {
+    container native-proc {
+      //rwpb:msg-new NativeProc;
+
+      leaf run-as {
+        description
+            "Host OS user that should run this
+             process, requires sudo -E access";
+        type string;
+      }
+
+      leaf environment {
+        description
+            "Runtime environment for native process";
+        type string;
+      }
+
+      leaf exe-path {
+        description
+            "Path to native process executable";
+        type string;
+      }
+
+      leaf args {
+        description
+            "Arguments to pass to native process";
+        type string;
+      }
+
+      leaf network-namespace {
+        description
+            "Namespace to start process in";
+        type string;
+      }
+
+      leaf stdout {
+        description
+            "Redirect stdout to the file at the
+             specified path";
+        type string;
+      }
+
+      leaf stderr {
+        description
+            "Redirect stderr to the file at the
+             specified path. Optionally, 'stdout'
+             may be used to redirect to the same
+             file as stdout";
+        type string;
+      }
+
+      leaf interactive {
+        description "Native process is interactive and needs
+          terminal control";
+        type empty;
+      }
+      uses valgrind;
+    }
+  }
+
+  grouping rwvcs-rwtasklet {
+    container rwtasklet {
+      description
+          "This section defines a RW.VCS
+           rwtasklet component";
+      //rwpb:msg-new VcsRwTasklet;
+
+      leaf plugin-directory {
+        description "";
+        type string;
+      }
+
+      leaf plugin-name {
+        description "";
+        type string;
+      }
+
+      leaf plugin-version {
+        description "";
+        type string;
+      }
+    }
+  }
+
+  grouping rwvcs-component-list {
+    list component {
+      description
+          "This section defines the RIFT.ware
+           virtual components";
+      key "component-name";
+      //rwpb:application-request-point;
+
+      leaf component-name {
+        description "";
+        type string;
+      }
+
+      leaf component-type {
+        description "";
+        type component_type;
+        mandatory true;
+      }
+
+      choice component {
+        case rwvcs-rwcollection {
+          uses rwvcs-rwcollection;
+        }
+        case rwvcs-rwvm {
+          uses rwvcs-rwvm;
+        }
+        case rwvcs-rwproc {
+          uses rwvcs-rwproc;
+        }
+        case native-proc {
+          uses native-proc;
+        }
+        case rwvcs-rwtasklet {
+          uses rwvcs-rwtasklet;
+        }
+      }
+    } // list component
+  } // grouping rwvcs-component-list
+}
+
+// vim: sw=2
+
diff --git a/skyquake/plugins/composer/src/schemas/yang/src-append.sh b/skyquake/plugins/composer/src/schemas/yang/src-append.sh
new file mode 100755 (executable)
index 0000000..a4f806a
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+# append .src to all the yang files
+
+# show the commands we will run
+for f in *.yang; do echo mv "$f" "$f.src"; done
+
+# then do it
+for f in *.yang; do mv "$f" "$f.src"; done
diff --git a/skyquake/plugins/composer/src/schemas/yang/src-remove.sh b/skyquake/plugins/composer/src/schemas/yang/src-remove.sh
new file mode 100755 (executable)
index 0000000..43f12d5
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+# remove .src from all the yang files
+
+# show the commands we will run
+for f in *.yang.src; do echo mv "$f" "${f/.src/}"; done
+
+# then run them
+for f in *.yang.src; do mv "$f" "${f/.src/}"; done
diff --git a/skyquake/plugins/composer/src/schemas/yang/vld.yang.src b/skyquake/plugins/composer/src/schemas/yang/vld.yang.src
new file mode 100755 (executable)
index 0000000..2747887
--- /dev/null
@@ -0,0 +1,141 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module vld
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:vld";
+  prefix "vld";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import vnfd {
+    prefix "vnfd";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file defines
+       the Virtual Link Descriptor (VLD)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  container vld-catalog {
+
+    list vld {
+      key "id";
+
+      leaf id {
+        description "Identifier for the VLD.";
+        type yang:uuid;
+      }
+
+      leaf name {
+        description "Virtual Link Descriptor (VLD) name.";
+        type string;
+      }
+
+      leaf short-name {
+        description "Short name for VLD for UI";
+        type string;
+      }
+
+      leaf vendor {
+        description "Provider of the VLD.";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the VLD.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the VLD";
+        type string;
+      }
+
+      leaf type {
+        type manotypes:virtual-link-type;
+      }
+
+      leaf root-bandwidth {
+        description
+            "For ELAN this is the aggregate bandwidth.";
+        type uint64;
+      }
+
+      leaf leaf-bandwidth {
+        description
+            "For ELAN this is the bandwidth of branches.";
+        type uint64;
+      }
+
+      list vnfd-connection-point-ref {
+        description
+            "A list of references to connection points.";
+        key "vnfd-ref member-vnf-index-ref";
+
+        leaf vnfd-ref {
+          description "A reference to a vnfd";
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+          }
+        }
+
+        leaf member-vnf-index-ref {
+          description 
+              "A reference to the consituent-vnfd id in nsd. 
+              Should have been a leafref to:
+                '/nsd:nsd-catalog:/nsd:nsd/constituent-vnfd/member-vnf-index-ref'. 
+              Instead using direct leaf to avoid circular reference.";
+          type uint64; 
+        }
+
+        leaf vnfd-connection-point-ref {
+          description 
+              "A reference to a connection point name in a vnfd";
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd" 
+               + "[vnfd:id = current()/../vld:vnfd-ref]"
+               + "/vnfd:connection-point/vnfd:name";
+          }
+        }
+      }
+
+      // replicate for pnfd container here
+      uses manotypes:provider-network;
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/vlr.yang.src b/skyquake/plugins/composer/src/schemas/yang/vlr.yang.src
new file mode 100755 (executable)
index 0000000..bb69fee
--- /dev/null
@@ -0,0 +1,178 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module vlr
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:vlr";
+  prefix "vlr";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import vld {
+    prefix "vld";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file defines
+       the Virtual Link Record (VLR)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  container vlr-catalog {
+    config false;
+
+    list vlr {
+      key "id";
+      unique "name";
+
+      leaf id {
+        description "Identifier for the VLR.";
+        type yang:uuid;
+      }
+
+      leaf name {
+        description "VLR name.";
+        type string;
+      }
+
+      leaf nsr-id-ref {
+        description
+            "NS instance identifier.
+             This is a leafref /nsr:ns-instance-config/nsr:nsr/nsr:id";
+        type yang:uuid;
+      }
+
+      leaf res-id {
+        description "Identifier for resmgr id mapping";
+        type yang:uuid;
+      }
+
+      leaf short-name {
+        description "Short name for VLR for UI";
+        type string;
+      }
+
+      leaf vendor {
+        description "Provider of the VLR.";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the VLR.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the VLR";
+        type string;
+      }
+
+      leaf type {
+        type manotypes:virtual-link-type;
+      }
+
+      leaf root-bandwidth {
+        description
+            "For ELAN this is the aggregate bandwidth.";
+        type uint64;
+      }
+
+      leaf leaf-bandwidth {
+        description
+            "For ELAN this is the bandwidth of branches.";
+        type uint64;
+      }
+
+      leaf create-time {
+        description
+          "Creation timestamp of this Virtual Link.
+          The timestamp is expressed as seconds
+          since unix epoch - 1970-01-01T00:00:00Z";
+
+        type uint32;
+      }
+
+      leaf vld-ref {
+        description "Reference to VLD";
+        type leafref {
+          path "/vld:vld-catalog/vld:vld/vld:id";
+        }
+      }
+
+      leaf network-id {
+        description
+            "Identifier for the allocated network resource.";
+        type string;
+      }
+
+      // replicate for pnfd container here
+
+      uses manotypes:provider-network;
+
+      leaf status {
+        description
+            "Status of the virtual link record.";
+        type enumeration {
+          enum LINK_UP;
+          enum DEGRADED;
+          enum LINK_DOWN;
+        }
+      }
+      leaf operational-status {
+        description
+          "The operational status of the Virtual Link
+            init                 : The VL is in init stat.
+            vl-alloc-pending     : The VL alloc is pending in VIM
+            running              : The VL is up  and running in VM
+            vl-terminate-pending : The VL is being terminated in VIM.
+            terminated           : The VL is terminated in the VM.
+            failed               : The VL instantiation failed in VIM.
+          ";
+
+        type enumeration {
+          //rwpb:enum-type "VlOperationalStatus";
+          enum init;
+          enum vl-alloc-pending;
+          enum running;
+          enum vl-terminate-pending;
+          enum terminated;
+          enum failed;
+        }
+      }
+    }
+  }
+}
+
diff --git a/skyquake/plugins/composer/src/schemas/yang/vnfd.yang.src b/skyquake/plugins/composer/src/schemas/yang/vnfd.yang.src
new file mode 100644 (file)
index 0000000..bd6589c
--- /dev/null
@@ -0,0 +1,491 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module vnfd
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:vnfd";
+  prefix "vnfd";
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file defines
+       the Virtual Network Function (VNF)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  grouping common-connection-point {
+    leaf name {
+      description "Name of the connection point";
+      type string;
+    }
+    
+    leaf id {
+      description "Identifier for the internal connection points";
+      type string;
+    }
+
+    leaf short-name {
+      description "Short name of the connection point";
+      type string;
+    }
+    
+    leaf type {
+      description "Type of the connection point.";
+      type manotypes:connection-point-type;
+    }
+  }
+  
+  grouping virtual-interface {
+    container virtual-interface {
+      description
+          "Container for the virtual interface properties";
+
+      leaf type {
+        description
+            "Specifies the type of virtual interface
+             between VM and host.
+             VIRTIO          : Use the traditional VIRTIO interface.
+             PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.
+             SR-IOV          : Use SR-IOV interface.
+             OM-MGMT         : Used to specify openmano mgmt external-connection type";
+
+        type enumeration {
+          enum OM-MGMT;
+          enum PCI-PASSTHROUGH;
+          enum SR-IOV;
+          enum VIRTIO;
+        }
+        default "VIRTIO";
+      }
+
+      leaf vpci {
+        description
+            "Specifies the virtual PCI address. Expressed in
+             the following format dddd:dd:dd.d. For example
+             0000:00:12.0. This information can be used to
+             pass as metadata during the VM creation.";
+        type string;
+      }
+
+      leaf bandwidth {
+        description
+            "Aggregate bandwidth of the NIC.";
+        type uint64;
+      }
+    }
+  }
+
+  container vnfd-catalog {
+
+    description
+        "Virtual Network Function Descriptor (VNFD).";
+
+    list vnfd {
+      key "id";
+
+      leaf id {
+        description "Identifier for the VNFD.";
+        type string;
+      }
+
+      leaf name {
+        description "VNFD name.";
+        mandatory true;
+        type string;
+      }
+
+      leaf short-name {
+        description "VNFD short name.";
+        type string;
+      }
+
+      leaf vendor {
+        description "Vendor of the VNFD.";
+        type string;
+      }
+
+      leaf logo {
+        description
+            "Vendor logo for the Virtual Network Function";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the VNFD.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the VNFD";
+        type string;
+      }
+
+      container mgmt-interface {
+        description
+            "Interface over which the VNF is managed.";
+
+        uses manotypes:vnf-configuration;
+        
+        choice endpoint-type {
+          description
+              "Indicates the type of management endpoint.";
+
+          case ip {
+            description
+                "Specifies the static IP address for managing the VNF.";
+            leaf ip-address {
+              type inet:ip-address;
+            }
+          }
+
+          case vdu-id {
+            description
+                "Use the default management interface on this VDU.";
+            leaf vdu-id {
+              type leafref {
+                path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id";
+              }
+            }
+          }
+
+          case cp {
+            description
+                "Use the ip address associated with this connection point.";
+            leaf cp {
+              type leafref {
+                path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name";
+              }
+            }
+          }
+        }
+
+        leaf port {
+          description
+              "Port for the management interface.";
+          type inet:port-number;
+        }
+
+        container dashboard-params {
+          description "Parameters for the VNF dashboard";
+
+          leaf path {
+            description "The HTTP path for the dashboard";
+            type string;
+          }
+
+          leaf https {
+            description "Pick HTTPS instead of HTTP , Default is false";
+            type boolean;
+          }
+
+          leaf port {
+            description "The HTTP port for the dashboard";
+            type inet:port-number;
+          }
+        }
+      }
+
+      list internal-vld {
+        key "id";
+        description
+            "List of Internal Virtual Link Descriptors (VLD).
+            The internal VLD describes the basic topology of
+            the connectivity (e.g. E-LAN, E-Line, E-Tree)
+            between internal VNF components of the system.";
+
+        leaf id {
+          description "Identifier for the VLD";
+          type string;
+        }
+
+        leaf name {
+          description "Name of the internal VLD";
+          type string;
+        }
+
+        leaf short-name {
+          description "Short name of the internal VLD";
+          type string;
+        }
+
+        leaf description {
+          type string;
+        }
+
+        leaf type {
+          type manotypes:virtual-link-type;
+        }
+
+        leaf root-bandwidth {
+          description
+              "For ELAN this is the aggregate bandwidth.";
+          type uint64;
+        }
+
+        leaf leaf-bandwidth {
+          description
+              "For ELAN this is the bandwidth of branches.";
+          type uint64;
+        }
+
+        leaf-list internal-connection-point-ref {
+          type leafref {
+            path "../../vdu/internal-connection-point/id";
+          }
+        }
+
+        uses manotypes:provider-network;
+      }
+
+      list connection-point {
+        key "name";
+        description
+            "List for external connection points. Each VNF has one
+            or more external connection points. As the name
+            implies that external connection points are used for
+            connecting the VNF to other VNFs or to external networks.
+            Each VNF exposes these connection points to the
+            orchestrator. The orchestrator can construct network
+            services by connecting the connection points between
+            different VNFs. The NFVO will use VLDs and VNFFGs at
+            the network service level to construct network services.";
+
+        uses common-connection-point;
+      }
+
+      list vdu {
+        description "List of Virtual Deployment Units";
+        key "id";
+
+        leaf id {
+          description "Unique id for the VDU";
+          type string;
+        }
+
+        leaf name {
+          description "Unique name for the VDU";
+          type string;
+        }
+
+        leaf description {
+            description "Description of the VDU.";
+            type string;
+        }
+
+        leaf count {
+          description "Number of instances of VDU";
+          type uint64;
+        }
+
+        leaf mgmt-vpci {
+          description
+              "Specifies the virtual PCI address. Expressed in
+             the following format dddd:dd:dd.d. For example
+             0000:00:12.0. This information can be used to
+             pass as metadata during the VM creation.";
+          type string;
+        }
+
+        uses manotypes:vm-flavor;
+        uses manotypes:guest-epa;
+        uses manotypes:vswitch-epa;
+        uses manotypes:hypervisor-epa;
+        uses manotypes:host-epa;
+
+        list alarm {
+          key "alarm-id";
+
+          uses manotypes:alarm;
+        }
+
+        leaf image {
+          description
+            "Image name for the software image.
+             If the image name is found within the VNF packaage it will
+             be uploaded to all cloud accounts during onboarding process.
+             Otherwise, the image must be added to the cloud account with
+             the same name as entered here.
+            ";
+          mandatory true;
+          type string;
+        }
+
+        leaf image-checksum {
+          description
+            "Image md5sum for the software image.
+            The md5sum, if provided, along with the image name uniquely
+            identifies an image uploaded to the CAL.
+            ";
+          type string;
+        }
+
+        leaf cloud-init {
+          description "Content of cloud-init script";
+          type string;
+        }
+
+        list internal-connection-point {
+          key "id";
+          description
+              "List for internal connection points. Each VNFC
+              has zero or more internal connection points.
+              Internal connection points are used for connecting
+              the VNF components internal to the VNF. If a VNF
+              has only one VNFC, it may not have any internal
+              connection points.";
+
+          uses common-connection-point;
+
+          leaf internal-vld-ref {
+            type leafref {
+              path "../../../internal-vld/id";
+            }
+          }
+        }
+
+        list internal-interface {
+          description
+              "List of internal interfaces for the VNF";
+          key name;
+
+          leaf name {
+            description
+                "Name of internal interface. Note that this
+                name has only local significance to the VDU.";
+            type string;
+          }
+
+          leaf vdu-internal-connection-point-ref {
+            type leafref {
+              path "../../internal-connection-point/id";
+            }
+          }
+          uses virtual-interface;
+        }
+
+        list external-interface {
+          description
+              "List of external interfaces for the VNF.
+              The external interfaces enable sending
+              traffic to and from VNF.";
+          key name;
+
+          leaf name {
+            description
+                "Name of the external interface. Note that
+                this name has only local significance.";
+            type string;
+          }
+
+          leaf vnfd-connection-point-ref {
+            description
+              "Name of the external connection point.";
+            type leafref {
+              path "../../../connection-point/name";
+            }
+          }
+          uses virtual-interface;
+        }
+      }
+
+      list vdu-dependency {
+        description
+            "List of VDU dependencies.";
+
+        key vdu-source-ref;
+        leaf vdu-source-ref {
+          type leafref {
+            path "../../vdu/id";
+          }
+        }
+
+        leaf vdu-depends-on-ref {
+          description
+              "Reference to the VDU that
+              source VDU depends.";
+          type leafref {
+            path "../../vdu/id";
+          }
+        }
+      }
+
+      leaf service-function-chain {
+        description "Type of node in Service Function Chaining Architecture";
+
+        type enumeration {
+          enum UNAWARE;
+          enum CLASSIFIER;
+          enum SF;
+          enum SFF;
+        }
+        default "UNAWARE";
+      }
+
+      leaf service-function-type {
+        description
+            "Type of Service Function.
+             NOTE: This needs to map with Service Function Type in ODL to
+             support VNFFG. Service Function Type is manadatory param in ODL
+             SFC. This is temporarily set to string for ease of use";
+            type string;
+      }
+
+      uses manotypes:monitoring-param;
+
+      list placement-groups {
+        description "List of placement groups at VNF level";
+
+        key "name";
+        uses manotypes:placement-group-info;
+        
+        list member-vdus {
+          description
+              "List of VDUs that are part of this placement group";
+          key "member-vdu-ref";
+        
+          leaf member-vdu-ref {
+            type leafref {
+              path "../../../vdu/id";
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+// vim: sw=2
diff --git a/skyquake/plugins/composer/src/schemas/yang/vnffgd.yang.src b/skyquake/plugins/composer/src/schemas/yang/vnffgd.yang.src
new file mode 100755 (executable)
index 0000000..99347ae
--- /dev/null
@@ -0,0 +1,83 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module vnffgd
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:vnffgd";
+  prefix "vnffgd";
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  revision 2014-10-27 {
+    description
+      "Initial revision. This YANG file defines 
+       the VNF Forwarding Graph Descriptor (VNFFGD)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  container vnffgd-catalog {
+
+    list vnffgd {
+      key "id";
+
+      leaf name {
+        description "VNF Forwarding Graph Descriptor name.";
+        type string;
+      }
+
+      leaf id {
+        description "Identifier for the VNFFGD.";
+        type yang:uuid;
+      }
+
+      leaf provider {
+        description "Provider of the VNFFGD.";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the VNFFGD.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the VNFFGD";
+        type string;
+      }
+
+      //TODO: Add more content here
+    }
+  }
+}
diff --git a/skyquake/plugins/composer/src/schemas/yang/vnfr.yang.src b/skyquake/plugins/composer/src/schemas/yang/vnfr.yang.src
new file mode 100755 (executable)
index 0000000..232d409
--- /dev/null
@@ -0,0 +1,521 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module vnfr
+{
+  namespace "urn:ietf:params:xml:ns:yang:nfvo:vnfr";
+  prefix "vnfr";
+
+  import mano-types {
+    prefix "manotypes";
+  }
+
+  import rw-pb-ext {
+    prefix "rwpb";
+  }
+
+  import vnfd {
+    prefix "vnfd";
+  }
+
+  import nsd {
+    prefix "nsd";
+  }
+
+  import vlr {
+    prefix "vlr";
+  }
+
+  import ietf-yang-types {
+    prefix "yang";
+  }
+
+  import ietf-inet-types {
+    prefix "inet";
+  }
+
+  revision 2015-09-10 {
+    description
+      "Initial revision. This YANG file defines
+       the Virtual Network Function Record (VNFR)";
+    reference
+      "Derived from earlier versions of base YANG files";
+  }
+
+  grouping placement-group-info {
+    list placement-groups-info {
+      description
+          "
+          Placement groups to which this VDU belongs and its
+          cloud construct
+          ";
+      key "name";
+      uses manotypes:placement-group-info;
+      uses manotypes:placement-group-input;
+    }
+  }
+
+
+  grouping virtual-interface {
+    container virtual-interface {
+      description
+          "Container for the virtual interface properties";
+
+      leaf type {
+        description
+            "Specifies the type of virtual interface
+             between VM and host.
+             VIRTIO          : Use the traditional VIRTIO interface.
+             PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface.
+             SR-IOV          : Use SR-IOV interface.";
+        type enumeration {
+          enum VIRTIO;
+          enum PCI-PASSTHROUGH;
+          enum SR-IOV;
+        }
+      }
+
+      leaf bandwidth {
+        description
+            "Aggregate bandwidth of the NIC.";
+        type uint64;
+      }
+
+      leaf ovs-offload {
+        description
+            "Defines if the NIC supports OVS offload.
+             MANDATORY : OVS offload support in the NIC is mandatory.
+             PREFERRED : OVS offload support in the NIC is preferred.";
+        type enumeration {
+          enum MANDATORY;
+          enum PREFERRED;
+        }
+      }
+
+      leaf vendor-id {
+        description
+            "Specifies the vendor specific id for
+             the device. This is used when a NIC from
+             specific HW vendor is required.";
+        type string;
+      }
+
+      leaf datapath-library {
+        description
+            "Specifies the name and version of the datapath
+             library the NIC is expected to support.";
+        type string;
+      }
+
+      leaf provider-network-name {
+        description
+            "Name of the provider network to which this
+             NIC is attached.";
+        type string;
+      }
+    }
+  }
+
+  container vnfr-catalog {
+    config false;
+    list vnfr {
+      description
+          "Virtual Network Function Record (VNFR).";
+      key "id";
+      unique "name";
+
+      leaf id {
+        description "Identifier for the VNFR.";
+        type yang:uuid;
+      }
+
+      leaf nsr-id-ref {
+        description
+            "NS instance identifier.
+             This is a leafref /nsr:ns-instance-config/nsr:nsr/nsr:id";
+        type yang:uuid;
+      }
+
+      leaf member-vnf-index-ref {
+        description "Reference to member VNF index in Network service.";
+        type leafref {
+          path "/nsd:nsd-catalog/nsd:nsd/nsd:constituent-vnfd/nsd:member-vnf-index";
+        }
+      }
+
+      leaf dashboard-url {
+        description "Dashboard URL";
+        type inet:uri;
+      }
+
+      leaf name {
+        description "VNFR name.";
+        type string;
+      }
+
+      leaf short-name {
+        description "VNFR short name.";
+        type string;
+      }
+
+      leaf vendor {
+        description "Vendor of the VNFR.";
+        type string;
+      }
+
+      leaf description {
+        description "Description of the VNFR.";
+        type string;
+      }
+
+      leaf version {
+        description "Version of the VNFR";
+        type string;
+      }
+
+      leaf create-time {
+        description
+          "Creation timestamp of this Virtual Network
+          Function.  The timestamp is expressed as
+          seconds since unix epoch - 1970-01-01T00:00:00Z";
+
+        type uint32;
+      }
+
+      leaf vnfd-ref {
+        description "Reference to VNFD";
+        type leafref {
+          path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+        }
+      }
+
+      // Use parameters provided here to configure this VNF
+      uses manotypes:vnf-configuration;
+
+      // Mainly used by Mon-params & dashboard url
+      container mgmt-interface {
+        leaf ip-address {
+          type inet:ip-address;
+        }
+        leaf port {
+          type inet:port-number;
+        }
+      }
+
+      list internal-vlr {
+        key "vlr-ref";
+
+        leaf vlr-ref {
+          description "Reference to a VLR record in the VLR catalog";
+          type leafref {
+            path "/vlr:vlr-catalog/vlr:vlr/vlr:id";
+          }
+        }
+
+        leaf-list internal-connection-point-ref {
+          type leafref {
+            path "../../vdur/internal-connection-point/id";
+          }
+        }
+      }
+
+      list connection-point {
+        key "name";
+        description
+            "List for external connection points. Each VNF has one
+             or more external connection points. As the name
+             implies that external connection points are used for
+             connecting the VNF to other VNFs or to external networks.
+             Each VNF exposes these connection points to the
+             orchestrator. The orchestrator can construct network
+             services by connecting the connection points between
+             different VNFs. The NFVO will use VLDs and VNFFGs at
+             the network service level to construct network services.";
+
+        uses vnfd:common-connection-point;
+
+        leaf vlr-ref {
+          description
+              "Reference to the VLR associated with this connection point";
+          type  leafref {
+            path "/vlr:vlr-catalog/vlr:vlr/vlr:id";
+          }
+        }
+
+        leaf ip-address {
+          description
+              "IP address assigned to the external connection point";
+          type inet:ip-address;
+        }
+        leaf connection-point-id {
+          //rwpb:field-inline "true";
+          //rwpb:field-string-max 64;
+          type string;
+        }
+      }
+
+      list vdur {
+        description "List of Virtual Deployment Units";
+        key "id";
+        unique "name";
+
+        leaf id {
+          description "Unique id for the VDU";
+          type yang:uuid;
+        }
+
+        leaf name {
+          description "name of the instantiated VDUR";
+          type string;
+        }
+
+        leaf vdu-id-ref {
+          type leafref {
+            path "/vnfd:vnfd-catalog/vnfd:vnfd"
+               + "[vnfd:id = current()/../../vnfr:vnfd-ref]"
+               + "/vnfd:vdu/vnfd:id";
+          }
+        }
+
+        leaf vim-id {
+          description "Allocated VM resource id";
+          type string;
+        }
+
+        leaf flavor-id {
+          description "VIM assigned flavor id";
+          type string;
+        }
+
+        leaf image-id {
+          description "VIM assigned image id";
+          type string;
+        }
+
+        leaf management-ip {
+          description "Management IP address";
+          type inet:ip-address;
+        }
+
+        leaf vm-management-ip {
+          description "VM Private Management IP address";
+          type inet:ip-address;
+        }
+
+        uses manotypes:vm-flavor;
+        uses manotypes:guest-epa;
+        uses manotypes:vswitch-epa;
+        uses manotypes:hypervisor-epa;
+        uses manotypes:host-epa;
+
+        list alarms {
+          description
+              "A list of the alarms that have been created for this VDU";
+
+          key "alarm-id";
+          uses manotypes:alarm;
+        }
+
+        list internal-connection-point {
+          key "id";
+          description
+              "List for internal connection points. Each VNFC
+               has zero or more internal connection points.
+               Internal connection points are used for connecting
+               the VNF components internal to the VNF. If a VNF
+               has only one VNFC, it may not have any internal
+               connection points.";
+
+          uses vnfd:common-connection-point;
+
+          leaf ip-address {
+            description
+                "IP address assigned to the external connection point";
+            type inet:ip-address;
+          }
+        }
+
+        list internal-interface {
+          description
+              "List of internal interfaces for the VNF";
+          key name;
+
+          leaf name {
+            description
+                "Name of internal interface. Note that this
+                 name has only local significance to the VDU.";
+            type string;
+          }
+
+          leaf vdur-internal-connection-point-ref {
+            type leafref {
+              path "../../internal-connection-point/id";
+            }
+          }
+          uses virtual-interface;
+        }
+
+        list external-interface {
+          description
+              "List of external interfaces for the VNF.
+               The external interfaces enable sending
+               traffic to and from VNF.";
+          key name;
+
+          leaf name {
+            description
+                "Name of the external interface. Note that
+                 this name has only local significance.";
+            type string;
+          }
+
+          leaf vnfd-connection-point-ref {
+            description
+              "Name of the external connection point.";
+            type leafref {
+              path "../../../connection-point/name";
+            }
+          }
+          uses virtual-interface;
+        }
+        leaf operational-status {
+          description
+            "The operational status of the VDU
+              init                : The VDU has just started.
+              vm-init-phase       : The VDUs in the VNF is being created in VIM.
+              vm-alloc-pending    : The  VM alloc is pending in VIM
+              running             : The VDU is active in VM
+              terminate           : The VDU is being terminated
+              vm-terminate-phase  : The VDU in the VNF is being terminated in VIM.
+              terminated          : The VDU is in the terminated state.
+              failed              : The VDU  instantiation failed.
+            ";
+
+          type enumeration {
+            //rwpb:enum-type "VduOperationalStatus";
+            enum init;
+            enum vm-init-phase;
+            enum vm-alloc-pending;
+            enum running;
+            enum terminate;
+            enum vl-terminate-phase;
+            enum terminated;
+            enum failed;
+          }
+        }
+        uses placement-group-info;
+      }
+
+      uses manotypes:monitoring-param;
+
+      leaf operational-status {
+        description
+          "The operational status of the VNFR instance
+            init                : The VNF has just started.
+            vl-init-phase       : The internal VLs in the VNF are being instantiated.
+            vm-init-phase       : The VMs for VDUs in the VNF are being instantiated.
+            running             : The VNF is in running state.
+            terminate           : The VNF is being terminated.
+            vm-terminate-phase  : The VMs in the VNF are being terminated.
+            vl-terminate-phase  : The internal VLs in the VNF are being terminated.
+            terminated          : The VNF is in the terminated state.
+            failed              : The VNF instantiation failed
+          ";
+
+        type enumeration {
+          //rwpb:enum-type "VnfrOperationalStatus";
+          enum init;
+          enum vl-init-phase;
+          enum vm-init-phase;
+          enum running;
+          enum terminate;
+          enum vm-terminate-phase;
+          enum vl-terminate-phase;
+          enum terminated;
+          enum failed;
+        }
+      }
+      leaf config-status {
+        description
+          "The configuration status of the NS instance
+            configuring: At least one of the VNFs in this instance is in configuring state
+            configured:  All the VNFs in this NS instance are configured or config-not-needed state
+          ";
+
+        type enumeration {
+          enum configuring {
+            value 1;
+          }
+          enum configured {
+            value 2;
+          }
+          enum failed {
+            value 3;
+          }
+          enum config-not-needed {
+            value 4;
+          }
+        }
+      }
+      uses placement-group-info;
+    }
+  }
+
+  rpc create-alarm {
+    description "Create an alert for a running VDU";
+    input {
+      leaf cloud-account {
+        mandatory true;
+        type string;
+      }
+
+      leaf vdu-id {
+        mandatory true;
+        type string;
+      }
+
+      container alarm {
+        uses manotypes:alarm;
+      }
+    }
+
+    output {
+      leaf alarm-id {
+        type string;
+      }
+    }
+  }
+
+  rpc destroy-alarm {
+    description "Destroy an alert that is associated with a running VDU";
+    input {
+      leaf cloud-account {
+        mandatory true;
+        type string;
+      }
+
+      leaf alarm-id {
+        mandatory true;
+        type string;
+      }
+    }
+  }
+}
+
diff --git a/skyquake/plugins/composer/src/schemas/yang/yang2json.sh b/skyquake/plugins/composer/src/schemas/yang/yang2json.sh
new file mode 100755 (executable)
index 0000000..5842e8d
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+./src-remove.sh
+
+yfc schema -c rw-nsd.yang -f json -o json-nsd.json
+yfc schema -c rw-vnfd.yang -f json -o json-vnfd.json
+#yfc schema -c vnffgd.yang -f json -o json-vnffgd.json
+#yfc schema -c rw-vld.yang -f json -o json-vld.json
+#yfc schema -c ietf-inet-types.yang -f json -o ietf-inet-types.yang.json;
+#yfc schema -c ietf-yang-types.yang -f json -o ietf-yang-types.yang.json
+
+./src-append.sh
+
+# todo: transform the -yang.json into a simpler json for the UI to consume
diff --git a/skyquake/plugins/composer/src/src/README.md b/skyquake/plugins/composer/src/src/README.md
new file mode 100644 (file)
index 0000000..f36327a
--- /dev/null
@@ -0,0 +1,69 @@
+
+The application enables editing of CONFD YANG instances.
+
+Catalog Panel - loads the NSD and VNFD and PNFD catalogs from the server and updates the internal indexes used throughout
+       the UI
+Canvas Panel - graphical editor of the relations and networks of NSD and VNFD descriptors
+Details Panel - schema driven editor of every property in the YANG models
+Forwarding Graphs Tray - editing FG RSP, Classifier and MatchAttribute properties
+
+# Details Panel
+
+ - To get an object to show up in the Details Panel it must be defined in the DescriptorModelMeta.json schema file.
+
+ - only needs the DescriptorModelMeta.json file to define the JSON to create / edited.
+
+ - To make an object appear in the Details Panel you need to add it to the "containersList" in the DescriptorModelFactor.js class.
+
+# Canvas Panel
+
+ - is coded specifically to enable graphical editing of certain descriptor model elements and is the least flexible
+
+ - To make an object "selectable" it must have a data-uid field.
+
+ The canvas panel uses D3 to render the graphical editing experience.
+
+# State Management
+
+There are two layers of state: 1) model state, 2) UI state.
+
+The YANG models are wrapped in Class objects to facilitate contextual operations that may change either state, like
+adding and removing property values, accessing the underlying uiState object, etc. These classes are defined in the
+`src/libraries/model/` directory.
+
+## Model State
+
+The UI uses Alt.js implementation of Flux. Alt.js provides for the actions and state of the application. Model state is
+managed by the CatalogDataStore. Any change made to the model must notify the CatalogDataStore. Upon notification of a
+change the Alt DataStore will setState() with a deep clone of the model causing a UI update.
+
+You will see `CatalogItemsActions.catalogItemDescriptorChanged(catalogItemModel)` everywhere a change is made to the
+model. In essence the UI treats the model as immutable. While the object is technically mutable the UI is modifying a copy
+of the model and so for changes to 'stick' the UI must notify the CatalogDataStore.
+
+## UI State
+
+UI state is managed in a couple different ways depending on the specific need of the UI. The three ways are: 1) a field
+named 'uiState' added to each YANG model instance when the catalog is loaded from the server; 2) React Component state not
+saved in the Alt DataStore; and 3) module variables.
+
+Ideally, all uiState would us the later two methods. The 'uiState' field poses a potential name collision with the YANG
+model (not likely, but if it happens could be really bad for the application!).
+
+## ReactJS and d3
+
+The components built using d3 own the management of the DOM under the SVGSVGElement. ReactJS manages the content DOM element
+above the SVG element. This is a clean separation of concerns. Any model or UI state changes are handled by the model
+classes and therefore d3 is agnostic and ignorant of managing state. ReactJS is not responsible for the DOM below the
+SVG content DIV and so does not care about any of the DOM manipulations that d3 makes.
+
+All of the UI is driven by the model which is always passed down through the props of the parent ReactJS Component. The
+d3 components provide a way to pass the model and UI state into them. For an example of this look at the
+`CatalogItemCanvasEditor::componentDidMount()` method. You will see the parent content div and the model data are given
+to the `DescriptorGraph()` d3 component.
+
+The d3 graphing components are located in the `src/libraries/graph/` directory.
+
+
+
+
diff --git a/skyquake/plugins/composer/src/src/actions/CanvasEditorActions.js b/skyquake/plugins/composer/src/src/actions/CanvasEditorActions.js
new file mode 100644 (file)
index 0000000..7324efd
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/14/15.
+ */
+import alt from '../alt';
+
+class CanvasEditorActions {
+
+       constructor() {
+               this.generateActions('showMoreInfo', 'showLessInfo', 'toggleShowMoreInfo', 'applyDefaultLayout', 'setCanvasZoom', 'addVirtualLinkDescriptor', 'addForwardingGraphDescriptor', 'addVirtualDeploymentDescriptor');
+       }
+
+}
+
+export default alt.createActions(CanvasEditorActions);
diff --git a/skyquake/plugins/composer/src/src/actions/CanvasPanelTrayActions.js b/skyquake/plugins/composer/src/src/actions/CanvasPanelTrayActions.js
new file mode 100644 (file)
index 0000000..9a76db8
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 2/4/16.
+ */
+import alt from '../alt';
+
+class CanvasPanelTrayActions {
+
+       constructor() {
+               this.generateActions('open', 'close', 'toggleOpenClose');
+       }
+
+}
+
+export default alt.createActions(CanvasPanelTrayActions);
diff --git a/skyquake/plugins/composer/src/src/actions/CatalogDataSourceActions.js b/skyquake/plugins/composer/src/src/actions/CatalogDataSourceActions.js
new file mode 100644 (file)
index 0000000..f5e95ee
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/11/15.
+ */
+import alt from '../alt';
+
+class CatalogDataSourceActions {
+
+       constructor() {
+               this.generateActions('loadCatalogsSuccess', 'loadCatalogsError', 'deleteCatalogItemSuccess', 'deleteCatalogItemError', 'saveCatalogItemSuccess', 'saveCatalogItemError');
+       }
+
+}
+
+export default alt.createActions(CatalogDataSourceActions);
diff --git a/skyquake/plugins/composer/src/src/actions/CatalogFilterActions.js b/skyquake/plugins/composer/src/src/actions/CatalogFilterActions.js
new file mode 100644 (file)
index 0000000..b285301
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/11/15.
+ */
+import alt from '../alt';
+
+class CatalogFilterActions {
+
+       constructor() {
+               this.generateActions('filterByType');
+       }
+
+}
+
+export default alt.createActions(CatalogFilterActions);
diff --git a/skyquake/plugins/composer/src/src/actions/CatalogItemsActions.js b/skyquake/plugins/composer/src/src/actions/CatalogItemsActions.js
new file mode 100644 (file)
index 0000000..c55e150
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/11/15.
+ */
+import alt from '../alt';
+
+/*
+ This class manages Catalog Data State
+ */
+
+class CatalogItemsActions {
+
+       constructor() {
+               this.generateActions('catalogItemMetaDataChanged', 'catalogItemDescriptorChanged', 'createCatalogItem', 'editCatalogItem', 'duplicateSelectedCatalogItem', 'selectCatalogItem', 'deleteSelectedCatalogItem', 'cancelCatalogItemChanges', 'saveCatalogItem', 'exportSelectedCatalogItems');
+       }
+
+}
+
+export default alt.createActions(CatalogItemsActions);
diff --git a/skyquake/plugins/composer/src/src/actions/CatalogPackageManagerActions.js b/skyquake/plugins/composer/src/src/actions/CatalogPackageManagerActions.js
new file mode 100644 (file)
index 0000000..22e32d3
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import alt from '../alt';
+
+class CatalogPackageManagerActions {
+
+       constructor() {
+               this.generateActions('downloadCatalogPackage', 'downloadCatalogPackageStatusUpdated', 'downloadCatalogPackageError', 'uploadCatalogPackage', 'uploadCatalogPackageStatusUpdated', 'uploadCatalogPackageError', 'removeCatalogPackage');
+       }
+
+}
+
+export default alt.createActions(CatalogPackageManagerActions);
diff --git a/skyquake/plugins/composer/src/src/actions/CatalogPanelTrayActions.js b/skyquake/plugins/composer/src/src/actions/CatalogPanelTrayActions.js
new file mode 100644 (file)
index 0000000..7a5011b
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/11/15.
+ */
+import alt from '../alt';
+
+class CatalogPanelTrayActions {
+
+       constructor() {
+               this.generateActions('open', 'close', 'toggleOpenClose');
+       }
+
+}
+
+export default alt.createActions(CatalogPanelTrayActions);
diff --git a/skyquake/plugins/composer/src/src/actions/ComposerAppActions.js b/skyquake/plugins/composer/src/src/actions/ComposerAppActions.js
new file mode 100644 (file)
index 0000000..03e784a
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by kkashalk on 11/30/15.
+ */
+import alt from '../alt';
+
+class ComposerAppActions {
+
+       constructor() {
+               this.generateActions('showError', 'clearError', 'setDragState', 'propertySelected', 'showJsonViewer', 'closeJsonViewer', 'selectModel', 'outlineModel', 'clearSelection', 'enterFullScreenMode', 'exitFullScreenMode');
+       }
+
+}
+
+export default alt.createActions(ComposerAppActions);
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/actions/ModalOverlayActions.js b/skyquake/plugins/composer/src/src/actions/ModalOverlayActions.js
new file mode 100644 (file)
index 0000000..7e0429e
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/14/15.
+ */
+import alt from '../alt';
+
+class ModalOverlayActions {
+
+       constructor() {
+               this.generateActions('showModalOverlay', 'hideModalOverlay');
+       }
+
+}
+
+export default alt.createActions(ModalOverlayActions);
diff --git a/skyquake/plugins/composer/src/src/actions/PanelResizeAction.js b/skyquake/plugins/composer/src/src/actions/PanelResizeAction.js
new file mode 100644 (file)
index 0000000..d721391
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/11/15.
+ */
+import alt from '../alt';
+import changeCase from 'change-case'
+
+/*
+ This class manages Composer Layout State
+ */
+
+const cleanNameRegExp = /(-is-tray-open|panel-)/i;
+
+class PanelResizeAction {
+
+       resize(e) {
+
+               /* we expect two types of resize events:
+                * window resize - invoked by window
+                * resize-manager resize - invoked by ResizeManager
+                *
+                * normalize the data needed by the Composer Layout or ignore invalid ones
+                *
+                * */
+
+               if (!e) {
+                       return false;
+               }
+
+               if (e.detail && e.detail.side) {
+                       // a ResizeManager event
+                       this.dispatch(PanelResizeAction.buildResizeManagerInfo(e))
+               } else {
+                       // a window event
+                       this.dispatch(PanelResizeAction.buildWindowResizeInfo(e));
+               }
+
+       }
+
+       static buildWindowResizeInfo(e) {
+               return e;
+       }
+
+       static buildResizeManagerInfo(e) {
+               const info = Object.assign({originalEvent: e}, e.detail);
+               const name = changeCase.paramCase(info.target.className.replace(cleanNameRegExp, ''));
+               info.type = 'resize-manager.resize.' + name;
+               return info;
+       }
+
+}
+
+export default alt.createActions(PanelResizeAction);
diff --git a/skyquake/plugins/composer/src/src/actions/RiftHeaderActions.js b/skyquake/plugins/composer/src/src/actions/RiftHeaderActions.js
new file mode 100644 (file)
index 0000000..a389395
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by kkashalk on 11/10/15.
+ */
+import alt from '../alt';
+
+class RiftHeaderActions {
+
+       constructor() {
+               this.generateActions('requestLaunchpadConfigSuccess');
+       }
+
+}
+
+export default alt.createActions(RiftHeaderActions);
diff --git a/skyquake/plugins/composer/src/src/alt.js b/skyquake/plugins/composer/src/src/alt.js
new file mode 100644 (file)
index 0000000..d8bf42d
--- /dev/null
@@ -0,0 +1,27 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/11/15.
+ */
+'use strict';
+
+var Alt = require('alt');
+var alt = new Alt();
+
+export default alt;
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Black-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Black-webfont.woff
new file mode 100755 (executable)
index 0000000..0229086
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Black-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-BlackItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-BlackItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..1875c0b
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-BlackItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Bold-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Bold-webfont.woff
new file mode 100755 (executable)
index 0000000..0c69948
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Bold-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-BoldItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-BoldItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..99de61a
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-BoldItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Italic-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Italic-webfont.woff
new file mode 100755 (executable)
index 0000000..dd74244
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Italic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Light-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Light-webfont.woff
new file mode 100755 (executable)
index 0000000..cc534a3
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Light-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-LightItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-LightItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..3071ff4
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-LightItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Medium-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Medium-webfont.woff
new file mode 100755 (executable)
index 0000000..cd810ef
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Medium-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-MediumItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-MediumItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..69a1458
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-MediumItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Regular-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Regular-webfont.woff
new file mode 100755 (executable)
index 0000000..bfa05d5
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Regular-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-Thin-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-Thin-webfont.woff
new file mode 100755 (executable)
index 0000000..f10b831
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-Thin-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/Roboto-ThinItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/Roboto-ThinItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..9ef17a8
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/Roboto-ThinItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Bold-webfont.woff b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Bold-webfont.woff
new file mode 100755 (executable)
index 0000000..235c963
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Bold-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/RobotoCondensed-BoldItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-BoldItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..df69b95
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-BoldItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Italic-webfont.woff b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Italic-webfont.woff
new file mode 100755 (executable)
index 0000000..67804e1
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Italic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Light-webfont.woff b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Light-webfont.woff
new file mode 100755 (executable)
index 0000000..c414478
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Light-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/RobotoCondensed-LightItalic-webfont.woff b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-LightItalic-webfont.woff
new file mode 100755 (executable)
index 0000000..5536e16
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-LightItalic-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Regular-webfont.woff b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Regular-webfont.woff
new file mode 100755 (executable)
index 0000000..ec28f95
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/RobotoCondensed-Regular-webfont.woff differ
diff --git a/skyquake/plugins/composer/src/src/assets/big-honking-catalog.json b/skyquake/plugins/composer/src/src/assets/big-honking-catalog.json
new file mode 100644 (file)
index 0000000..25dce0c
--- /dev/null
@@ -0,0 +1,1901 @@
+[
+  {
+    "id": "GUID-1",
+    "name": "RIFT.ware™ NS Descriptors Catalog",
+    "short-name": "rift.ware-nsd-cat",
+    "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+    "vendor": "RIFT.io",
+    "version": "",
+    "created-on": "",
+    "type": "nsd",
+    "meta": {
+      "icon-svg": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22iso-8859-1%22%3F%3E%0A%3C!--%20Generator%3A%20Adobe%20Illustrator%2018.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200)%20%20--%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22connection-icon-1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2050%2050%22%20style%3D%22enable-background%3Anew%200%200%2050%2050%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%09%3Cpath%20d%3D%22M15%2030c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2020c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2040c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M19.007%2025.885l12.88%206.44-.895%201.788-12.88-6.44z%22%2F%3E%3Cpath%20d%3D%22M30.993%2015.885l.894%201.79-12.88%206.438-.894-1.79z%22%2F%3E%3C%2Fsvg%3E"
+    },
+    "descriptors": [
+      {
+        "description": "VPNaaS Provider NSD for Corporation X",
+        "version": 1,
+        "constituent-vnfd": [
+          {
+            "vnf-configuration": {
+              "config-type": "netconf",
+              "config-template": "\n        <vnf-config xmlns=\"http://riftio.com/ns/riftware-1.0/mano-base\">\n      <vnf>\n        <name>trafgen</name>\n        <instance>0</instance>\n        <network-context xmlns=\"http://riftio.com/ns/riftware-1.0/rw-vnf-base-config\">\n          <name>trafgen-lb</name>\n          <interface>\n            <name>N1TenGi-1</name>\n            <bind>\n              <port>trafgen_vnfd/cp0</port>\n            </bind>\n          </interface>\n          <interface>\n              <name>vlan200</name>\n              <bind>\n                <port>trafgen_vnfd/cp0</port>\n                <vlan>200</vlan>\n              </bind>\n              <ip>\n                <address>200.1.1.1/24</address>\n              </ip>\n          </interface>\n        </network-context>\n        <port xmlns=\"http://riftio.com/ns/riftware-1.0/rw-vnf-base-config\">\n          <name>trafgen_vnfd/cp0</name>\n          <open/>\n          <application>\n            <rx>rw_trafgen</rx>\n            <tx>rw_trafgen</tx>\n          </application>\n          <receive-q-length>2</receive-q-length>\n          <vlan><id>200</id><open/></vlan>\n          <port-identity>\n          <ip-address><rw_connection_point_name trafgen_vnfd/cp0></ip-address>\n          <port-mode>direct</port-mode>\n          </port-identity>\n          <trafgen xmlns=\"http://riftio.com/ns/riftware-1.0/rw-trafgen\">\n            <transmit-params>\n              <tx-rate>10</tx-rate>\n              <transmit-mode>\n                <range/>\n              </transmit-mode>\n            </transmit-params>\n            <range-template>\n              <destination-mac>\n                <dynamic>\n                  <gateway>200.1.1.2</gateway>\n                </dynamic>\n              </destination-mac>\n              <source-ip>\n                <start>200.1.1.1</start>\n                <minimum>200.1.1.1</minimum>\n                <maximum>200.1.1.1</maximum>\n                <increment>1</increment>\n              </source-ip>\n              <destination-ip>\n                <start>50.1.1.1</start>\n                <minimum>50.1.1.1</minimum>\n                <maximum>50.1.1.1</maximum>\n                <increment>1</increment>\n              </destination-ip>\n              <source-port>\n                <start>10000</start>\n                <minimum>10000</minimum>\n                <maximum>10128</maximum>\n                <increment>1</increment>\n              </source-port>\n              <destination-port>\n                <start>5678</start>\n                <minimum>5678</minimum>\n                <maximum>5678</maximum>\n                <increment>1</increment>\n              </destination-port>\n              <packet-size>\n                <start>1024</start>\n                <minimum>1024</minimum>\n                <maximum>1024</maximum>\n                <increment>1</increment>\n              </packet-size>\n              <vlan>\n                <start>200</start>\n                <minimum>200</minimum>\n                <maximum>200</maximum>\n                <increment>1</increment>\n              </vlan>\n            </range-template>\n          </trafgen>\n        </port>\n      </vnf>\n    </vnf-config>\n    <logging xmlns=\"http://riftio.com/ns/riftware-1.0/rwlog-mgmt\">\n      <sink>\n        <name>syslog</name>\n        <server-address><rw_mgmt_ip></server-address>\n        <port>514</port>\n      </sink>\n    </logging>\n        ",
+              "input-params": {
+                "config-delay": 180,
+                "config-priority": 1
+              },
+              "netconf": {
+                "target": "running",
+                "port": 2022
+              }
+            },
+            "vnfd-id-ref": "2544951a-d6b5-11e5-9bb7-001b21b98a89",
+            "member-vnf-index": 1
+          },
+          {
+            "vnf-configuration": {
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 2
+              },
+              "config-type": "script",
+              "config-template": "\n#!/usr/bin/expect -f\nset login \"root\"\nset addr <rw_mgmt_ip>\nset pw \"6windos\"\nspawn ssh -1 $login@$addr\n\nset timeout 60\n\nexpect \"yes/no\" {\n    send \"yes\\r\"\n    expect \"*?assword:\" { send \"$pw\\r\" }\n    } \"*?assword:\" { send \"$pw\\r\" }\n\nexpect \"# \"\nsend \"cli\\r\"\nexpect \"{}\"\nsend \"edit conf running\\r\"\nexpect \"ing}\"\n\n# Setup eth1 config\nsend \"eth1\\r\"\nexpect \"eth1}\"\nsend \"ipaddress dhcpv4\\r\"\nexpect \"dhcpv4}\"\nsend \"dhcp enable\\r\"\nexpect \"dhcpv4}\"\nsend \"exit\\r\"\nexpect \"eth1}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n# Setup eth2 config\nsend \"eth2\\r\"\nexpect \"eth2}\"\nsend \"ipaddress dhcpv4\\r\"\nexpect \"dhcpv4}\"\nsend \"dhcp enable\\r\"\nexpect \"dhcpv4}\"\nsend \"exit\\r\"\nexpect \"eth2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup loopback\nsend \"loopback0\\r\"\nexpect \"back0}\"\nsend \"ipaddress 2.2.2.2/32\\r\"\nexpect \"back0}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup VRF 2\nsend \"vrf2\\r\"\nexpect \"vrf2}\"\nsend \"forwarding ipv4 enable\\r\"\nexpect \"vrf2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Applyconfig\nsend \"addrunning\\r\"\nexpect \"ing}\"\nsend \"exit\\r\"\nexpect \"{}\"\n\n# Get MAC of eth2\nsend \"show interface eth2\\r\"\nexpect -re {ether (\\S+)}\nset macaddr $expect_out(1,string)\nputs $macaddr\n\n# Enter into edit config mode again\nsend \"edit conf running\\r\"\n\n#Setup route for GRE tunnel\nsend \"rtg\\r\"\nexpect \"rtg}\"\nsend \"route 3.3.3.3/32 100.0.108.60\\r\"\nexpect \"rtg}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup VLAN on eth2 and vrf2\nsend \"vlan2\\r\"\nexpect \"vlan2}\"\nsend \"bind eth2 id 200\\r\"\nexpect \"vlan2}\"\nsend \"mac-address $macaddr\\r\"\nexpect \"vlan2}\"\nsend \"ipaddress 200.1.1.2/24\\r\"\nexpect \"vlan2}\"\nsend \"vrf-id 2\\r\"\nexpect \"vlan2}\"\nsend \"interface up\\r\"\nexpect \"vlan2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup GRE on vrf2\nsend \"gre2\\r\"\nexpect \"gre2}\"\nsend \"bind 2.2.2.2 3.3.3.3 \\r\"\nexpect \"gre2}\"\nsend \"endpoints 5.1.1.1 5.1.1.2\\r\"\nexpect \"gre2}\"\nsend \"vrf-id 2\\r\"\nexpect \"gre2}\"\nsend \"checksum-input disable\\r\"\nexpect \"gre2}\"\nsend \"interface up\\r\"\nexpect \"gre2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup routing in VRF2 for VLAN2 traffic\nsend \"rtg\\r\"\nexpect \"rtg}\"\nsend \"route 50.1.1.1/32 5.1.1.2 vrf-id 2\\r\"\nexpect \"rtg}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Applyconfig\nsend \"addrunning\\r\"\nexpect \"ing}\"\nsend \"exit\\r\"\nexpect \"{}\"\n        ",
+              "script": {
+                "script-type": "expect"
+              }
+            },
+            "vnfd-id-ref": "23028096-d6b5-11e5-8e3f-001b21b98a89",
+            "member-vnf-index": 2
+          },
+          {
+            "vnf-configuration": {
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 0
+              }
+            },
+            "vnfd-id-ref": "2407d7a2-d6b5-11e5-95d4-001b21b98a89",
+            "member-vnf-index": 3
+          },
+          {
+            "vnfd-id-ref": "23095c22-d6b5-11e5-9e33-001b21b98a89",
+            "member-vnf-index": 4
+          },
+          {
+            "vnfd-id-ref": "2329d470-d6b5-11e5-98fb-001b21b98a89",
+            "member-vnf-index": 5
+          }
+        ],
+        "short-name": "Vpn_Provider_Site_CorpA_nsd",
+        "vld": [
+          {
+            "description": "Corporate LAN for A,SRIOV based",
+            "type": "ELAN",
+            "version": 1,
+            "provider-network": {
+              "physical-network": "physnet3",
+              "overlay-type": "FLAT"
+            },
+            "short-name": "Corp-A Prov-link",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 1,
+                "vnfd-connection-point-ref": "trafgen_vnfd/cp0",
+                "vnfd-id-ref": "2544951a-d6b5-11e5-9bb7-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp0",
+                "vnfd-id-ref": "23028096-d6b5-11e5-8e3f-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 3,
+                "vnfd-connection-point-ref": "cwims_vnfd/cp0",
+                "vnfd-id-ref": "2407d7a2-d6b5-11e5-95d4-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 4,
+                "vnfd-connection-point-ref": "Riverbed_SteelHead_vnfd/cp0",
+                "vnfd-id-ref": "23095c22-d6b5-11e5-9e33-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 5,
+                "vnfd-connection-point-ref": "F5_BigIP_vnfd/cp0",
+                "vnfd-id-ref": "2329d470-d6b5-11e5-98fb-001b21b98a89"
+              }
+            ],
+            "name": "Corp-A Prov-link",
+            "vendor": "RIFT.io",
+            "id": "28b2c8a2-d6b5-11e5-9a50-001b21b98a89"
+          },
+          {
+            "description": "HA link between BigIPs",
+            "type": "ELAN",
+            "version": 1,
+            "short-name": "Corp-A HA-link",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 5,
+                "vnfd-connection-point-ref": "F5_BigIP_vnfd/cp1",
+                "vnfd-id-ref": "2329d470-d6b5-11e5-98fb-001b21b98a89"
+              }
+            ],
+            "name": "Corp-A HA-link",
+            "vendor": "RIFT.io",
+            "id": "28b329be-d6b5-11e5-9a50-001b21b98a89"
+          },
+          {
+            "description": "Egress link between BigIPs",
+            "type": "ELAN",
+            "version": 1,
+            "short-name": "Corp-A Egress-link",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 5,
+                "vnfd-connection-point-ref": "F5_BigIP_vnfd/cp2",
+                "vnfd-id-ref": "2329d470-d6b5-11e5-98fb-001b21b98a89"
+              }
+            ],
+            "name": "Corp-A Egress-link",
+            "vendor": "RIFT.io",
+            "id": "28b33d32-d6b5-11e5-9a50-001b21b98a89"
+          },
+          {
+            "description": "External network VIRTIO based",
+            "type": "ELAN",
+            "version": 1,
+            "short-name": "multisite",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp1",
+                "vnfd-id-ref": "23028096-d6b5-11e5-8e3f-001b21b98a89"
+              }
+            ],
+            "name": "multisite",
+            "vendor": "RIFT.io",
+            "id": "28b350ce-d6b5-11e5-9a50-001b21b98a89"
+          }
+        ],
+        "name": "Vpn_Provider_Site_CorpA_nsd",
+        "vendor": "RIFT.io",
+        "id": "28922610-d6b5-11e5-9a50-001b21b98a89",
+        "meta": {
+          "instance-ref-count": 0
+        }
+      },
+      {
+        "description": "VPNaaS Provider NSD for Corporation X",
+        "version": 1,
+        "constituent-vnfd": [
+          {
+            "vnf-configuration": {
+              "config-type": "netconf",
+              "config-template": "\n        <vnf-config xmlns=\"http://riftio.com/ns/riftware-1.0/mano-base\">\n      <vnf>\n        <name>trafgen</name>\n        <instance>0</instance>\n        <network-context xmlns=\"http://riftio.com/ns/riftware-1.0/rw-vnf-base-config\">\n          <name>trafgen-lb</name>\n          <interface>\n            <name>N1TenGi-1</name>\n            <bind>\n              <port>trafgen_vnfd/cp0</port>\n            </bind>\n          </interface>\n          <interface>\n              <name>vlan200</name>\n              <bind>\n                <port>trafgen_vnfd/cp0</port>\n                <vlan>200</vlan>\n              </bind>\n              <ip>\n                <address>200.1.1.1/24</address>\n              </ip>\n          </interface>\n        </network-context>\n        <port xmlns=\"http://riftio.com/ns/riftware-1.0/rw-vnf-base-config\">\n          <name>trafgen_vnfd/cp0</name>\n          <open/>\n          <application>\n            <rx>rw_trafgen</rx>\n            <tx>rw_trafgen</tx>\n          </application>\n          <receive-q-length>2</receive-q-length>\n          <vlan><id>200</id><open/></vlan>\n          <port-identity>\n          <ip-address><rw_connection_point_name trafgen_vnfd/cp0></ip-address>\n          <port-mode>direct</port-mode>\n          </port-identity>\n          <trafgen xmlns=\"http://riftio.com/ns/riftware-1.0/rw-trafgen\">\n            <transmit-params>\n              <tx-rate>10</tx-rate>\n              <transmit-mode>\n                <range/>\n              </transmit-mode>\n            </transmit-params>\n            <range-template>\n              <destination-mac>\n                <dynamic>\n                  <gateway>200.1.1.2</gateway>\n                </dynamic>\n              </destination-mac>\n              <source-ip>\n                <start>200.1.1.1</start>\n                <minimum>200.1.1.1</minimum>\n                <maximum>200.1.1.1</maximum>\n                <increment>1</increment>\n              </source-ip>\n              <destination-ip>\n                <start>50.1.1.1</start>\n                <minimum>50.1.1.1</minimum>\n                <maximum>50.1.1.1</maximum>\n                <increment>1</increment>\n              </destination-ip>\n              <source-port>\n                <start>10000</start>\n                <minimum>10000</minimum>\n                <maximum>10128</maximum>\n                <increment>1</increment>\n              </source-port>\n              <destination-port>\n                <start>5678</start>\n                <minimum>5678</minimum>\n                <maximum>5678</maximum>\n                <increment>1</increment>\n              </destination-port>\n              <packet-size>\n                <start>1024</start>\n                <minimum>1024</minimum>\n                <maximum>1024</maximum>\n                <increment>1</increment>\n              </packet-size>\n              <vlan>\n                <start>200</start>\n                <minimum>200</minimum>\n                <maximum>200</maximum>\n                <increment>1</increment>\n              </vlan>\n            </range-template>\n          </trafgen>\n        </port>\n      </vnf>\n    </vnf-config>\n    <logging xmlns=\"http://riftio.com/ns/riftware-1.0/rwlog-mgmt\">\n      <sink>\n        <name>syslog</name>\n        <server-address><rw_mgmt_ip></server-address>\n        <port>514</port>\n      </sink>\n    </logging>\n        ",
+              "input-params": {
+                "config-delay": 180,
+                "config-priority": 1
+              },
+              "netconf": {
+                "target": "running",
+                "port": 2022
+              }
+            },
+            "vnfd-id-ref": "2544951a-d6b5-11e5-9bb7-001b21b98a89",
+            "member-vnf-index": 1
+          },
+          {
+            "vnf-configuration": {
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 2
+              },
+              "config-type": "script",
+              "config-template": "\n#!/usr/bin/expect -f\nset login \"root\"\nset addr <rw_mgmt_ip>\nset pw \"6windos\"\nspawn ssh -1 $login@$addr\n\nset timeout 60\n\nexpect \"yes/no\" {\n    send \"yes\\r\"\n    expect \"*?assword:\" { send \"$pw\\r\" }\n    } \"*?assword:\" { send \"$pw\\r\" }\n\nexpect \"# \"\nsend \"cli\\r\"\nexpect \"{}\"\nsend \"edit conf running\\r\"\nexpect \"ing}\"\n\n# Setup eth1 config\nsend \"eth1\\r\"\nexpect \"eth1}\"\nsend \"ipaddress dhcpv4\\r\"\nexpect \"dhcpv4}\"\nsend \"dhcp enable\\r\"\nexpect \"dhcpv4}\"\nsend \"exit\\r\"\nexpect \"eth1}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n# Setup eth2 config\nsend \"eth2\\r\"\nexpect \"eth2}\"\nsend \"ipaddress dhcpv4\\r\"\nexpect \"dhcpv4}\"\nsend \"dhcp enable\\r\"\nexpect \"dhcpv4}\"\nsend \"exit\\r\"\nexpect \"eth2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup loopback\nsend \"loopback0\\r\"\nexpect \"back0}\"\nsend \"ipaddress 2.2.2.2/32\\r\"\nexpect \"back0}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup VRF 2\nsend \"vrf2\\r\"\nexpect \"vrf2}\"\nsend \"forwarding ipv4 enable\\r\"\nexpect \"vrf2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Applyconfig\nsend \"addrunning\\r\"\nexpect \"ing}\"\nsend \"exit\\r\"\nexpect \"{}\"\n\n# Get MAC of eth2\nsend \"show interface eth2\\r\"\nexpect -re {ether (\\S+)}\nset macaddr $expect_out(1,string)\nputs $macaddr\n\n# Enter into edit config mode again\nsend \"edit conf running\\r\"\n\n#Setup route for GRE tunnel\nsend \"rtg\\r\"\nexpect \"rtg}\"\nsend \"route 3.3.3.3/32 100.0.108.60\\r\"\nexpect \"rtg}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup VLAN on eth2 and vrf2\nsend \"vlan2\\r\"\nexpect \"vlan2}\"\nsend \"bind eth2 id 200\\r\"\nexpect \"vlan2}\"\nsend \"mac-address $macaddr\\r\"\nexpect \"vlan2}\"\nsend \"ipaddress 200.1.1.2/24\\r\"\nexpect \"vlan2}\"\nsend \"vrf-id 2\\r\"\nexpect \"vlan2}\"\nsend \"interface up\\r\"\nexpect \"vlan2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup GRE on vrf2\nsend \"gre2\\r\"\nexpect \"gre2}\"\nsend \"bind 2.2.2.2 3.3.3.3 \\r\"\nexpect \"gre2}\"\nsend \"endpoints 5.1.1.1 5.1.1.2\\r\"\nexpect \"gre2}\"\nsend \"vrf-id 2\\r\"\nexpect \"gre2}\"\nsend \"checksum-input disable\\r\"\nexpect \"gre2}\"\nsend \"interface up\\r\"\nexpect \"gre2}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Setup routing in VRF2 for VLAN2 traffic\nsend \"rtg\\r\"\nexpect \"rtg}\"\nsend \"route 50.1.1.1/32 5.1.1.2 vrf-id 2\\r\"\nexpect \"rtg}\"\nsend \"exit\\r\"\nexpect \"ing}\"\n\n#Applyconfig\nsend \"addrunning\\r\"\nexpect \"ing}\"\nsend \"exit\\r\"\nexpect \"{}\"\n        ",
+              "script": {
+                "script-type": "expect"
+              }
+            },
+            "vnfd-id-ref": "23028096-d6b5-11e5-8e3f-001b21b98a89",
+            "member-vnf-index": 2
+          },
+          {
+            "vnf-configuration": {
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 0
+              }
+            },
+            "vnfd-id-ref": "2407d7a2-d6b5-11e5-95d4-001b21b98a89",
+            "member-vnf-index": 3
+          }
+        ],
+        "short-name": "Vpn_Provider_Site_CorpB_nsd",
+        "vld": [
+          {
+            "description": "Corporate LAN for B,SRIOV based",
+            "type": "ELAN",
+            "version": 1,
+            "provider-network": {
+              "physical-network": "physnet4",
+              "overlay-type": "FLAT"
+            },
+            "short-name": "Corp-B Prov-link",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 1,
+                "vnfd-connection-point-ref": "trafgen_vnfd/cp0",
+                "vnfd-id-ref": "2544951a-d6b5-11e5-9bb7-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp0",
+                "vnfd-id-ref": "23028096-d6b5-11e5-8e3f-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 3,
+                "vnfd-connection-point-ref": "cwims_vnfd/cp0",
+                "vnfd-id-ref": "2407d7a2-d6b5-11e5-95d4-001b21b98a89"
+              }
+            ],
+            "name": "Corp-B Prov-link",
+            "vendor": "RIFT.io",
+            "id": "29405438-d6b5-11e5-a599-001b21b98a89"
+          },
+          {
+            "description": "External network VIRTIO based",
+            "type": "ELAN",
+            "version": 1,
+            "short-name": "multisite",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp1",
+                "vnfd-id-ref": "23028096-d6b5-11e5-8e3f-001b21b98a89"
+              }
+            ],
+            "name": "multisite",
+            "vendor": "RIFT.io",
+            "id": "2940a00a-d6b5-11e5-a599-001b21b98a89"
+          }
+        ],
+        "name": "Vpn_Provider_Site_CorpB_nsd",
+        "vendor": "RIFT.io",
+        "id": "29212fb8-d6b5-11e5-a599-001b21b98a89",
+        "meta": {
+          "instance-ref-count": 0
+        }
+      },
+      {
+        "description": "NS Vrouter-Trafsink",
+        "version": 1,
+        "constituent-vnfd": [
+          {
+            "vnf-configuration": {
+              "config-type": "netconf",
+              "config-template": "\n        <vnf-config xmlns=\"http://riftio.com/ns/riftware-1.0/mano-base\">\n      <vnf>\n        <name>trafsink</name>\n        <instance>0</instance>\n        <network-context xmlns=\"http://riftio.com/ns/riftware-1.0/rw-vnf-base-config\">\n          <name>lb-trafsink</name>\n          <interface>\n            <name>N3TenGigi-1</name>\n            <bind>\n              <port>trafsink_vnfd/cp0</port>\n            </bind>\n            <ip>\n              <address>50.1.1.1/24</address>\n            </ip>\n          </interface>\n        </network-context>\n        <port xmlns=\"http://riftio.com/ns/riftware-1.0/rw-vnf-base-config\">\n          <name>trafsink_vnfd/cp0</name>\n          <open/>\n          <application>\n            <rx>rw_trafgen</rx>\n            <tx>rw_trafgen</tx>\n          </application>\n          <receive-q-length>2</receive-q-length>\n          <port-identity>\n          <ip-address><rw_connection_point_name trafsink_vnfd/cp0></ip-address>\n          <port-mode>direct</port-mode>\n          </port-identity>\n          <trafgen xmlns=\"http://riftio.com/ns/riftware-1.0/rw-trafgen\">\n            <receive-param>\n              <receive-echo>\n                <on/>\n              </receive-echo>\n            </receive-param>\n          </trafgen>\n        </port>\n      </vnf>\n    </vnf-config>\n    <logging xmlns=\"http://riftio.com/ns/riftware-1.0/rwlog-mgmt\">\n      <sink>\n        <name>syslog</name>\n        <server-address><rw_mgmt_ip></server-address>\n        <port>514</port>\n      </sink>\n    </logging>\n\n        ",
+              "input-params": {
+                "config-delay": 180,
+                "config-priority": 1
+              },
+              "netconf": {
+                "target": "running",
+                "port": 2022
+              },
+              "config-access": {
+                "password": "admin",
+                "username": "admin"
+              }
+            },
+            "vnfd-id-ref": "26a08568-d6b5-11e5-a5c6-001b21b98a89",
+            "member-vnf-index": 1
+          },
+          {
+            "vnf-configuration": {
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 2
+              },
+              "config-type": "script",
+              "config-template": "\n#!/usr/bin/expect -f\nset login \"vyatta\"\nset addr <rw_mgmt_ip>\nset pw \"vyatta\"\nspawn ssh $login@$addr\n\nset timeout 60\n\nexpect \"yes/no\" {\n    send \"yes\n\"\n    expect \"*?assword:\" { send \"$pw\n\" }\n    } \"*?assword:\" { send \"$pw\n\" }\n\nexpect \"$ \"\nsend \"configure\n\"\nexpect \"# \"\nsend \"set protocols static interface-route 50.1.1.0/24 next-hop-interface dp0s6\n\"\nexpect \"# \"\nsend \"set protocols static route 2.2.2.2/32 next-hop 100.0.108.5\n\"\nexpect \"# \"\nsend \"set interfaces loopback lo1 address 3.3.3.3/32\n\"\nexpect \"# \"\nsend \"set interfaces tunnel tun0 address 5.1.1.2/24\n\"\nexpect \"# \"\nsend \"set interfaces tunnel tun0 encapsulation gre\n\"\nexpect \"# \"\nsend \"set interfaces tunnel tun0 local-ip 3.3.3.3\n\"\nexpect \"# \"\nsend \"set interfaces tunnel tun0 remote-ip 2.2.2.2\n\"\nexpect \"# \"\nsend \"set protocols static route 200.1.1.1/32 next-hop 5.1.1.1\n\"\nexpect \"# \"\nsend \"commit\n\"\nexpect \"# \"\nsend \"exit \n\"\nexpect \"$ \"\n        ",
+              "script": {
+                "script-type": "expect"
+              }
+            },
+            "vnfd-id-ref": "a6ce0f96-d6cc-11e5-9540-001b21b98a89",
+            "member-vnf-index": 2
+          }
+        ],
+        "short-name": "Vpn_Remote_Site_nsd",
+        "vld": [
+          {
+            "description": "Corporate LAN for X,SRIOV based",
+            "type": "ELAN",
+            "version": 1,
+            "provider-network": {
+              "physical-network": "physnet3",
+              "overlay-type": "FLAT"
+            },
+            "short-name": "Corp-X Remote Site link",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 1,
+                "vnfd-connection-point-ref": "trafsink_vnfd/cp0",
+                "vnfd-id-ref": "26a08568-d6b5-11e5-a5c6-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp0",
+                "vnfd-id-ref": "a6ce0f96-d6cc-11e5-9540-001b21b98a89"
+              }
+            ],
+            "name": "Corp-X Remote Site link",
+            "vendor": "RIFT.io",
+            "id": "b83bb668-d6cf-11e5-99d1-001b21b98a89"
+          },
+          {
+            "description": "External network VIRTIO based",
+            "type": "ELAN",
+            "version": 1,
+            "short-name": "multisite",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp1",
+                "vnfd-id-ref": "a6ce0f96-d6cc-11e5-9540-001b21b98a89"
+              }
+            ],
+            "name": "multisite",
+            "vendor": "RIFT.io",
+            "id": "b83bff92-d6cf-11e5-99d1-001b21b98a89"
+          }
+        ],
+        "name": "Vpn_Remote_Site_nsd",
+        "vendor": "RIFT.io",
+        "id": "b81198ec-d6cf-11e5-99d1-001b21b98a89",
+        "meta": {
+          "instance-ref-count": 0
+        }
+      },
+      {
+        "description": "6wind turborouter only",
+        "version": 1,
+        "constituent-vnfd": [
+          {
+            "vnf-configuration": {
+              "initial-config-primitive": [
+                {
+                  "parameter": [
+                    {
+                      "name": "pass",
+                      "value": "6windos"
+                    },
+                    {
+                      "name": "user",
+                      "value": "root"
+                    },
+                    {
+                      "name": "vpe-router",
+                      "value": "<rw_mgmt_ip>"
+                    }
+                  ],
+                  "name": "config",
+                  "seq": 1
+                },
+                {
+                  "parameter": [
+                    {
+                      "name": "cidr",
+                      "value": "10.10.10.2/30"
+                    },
+                    {
+                      "name": "iface-name",
+                      "value": "eth1"
+                    }
+                  ],
+                  "name": "configure-interface",
+                  "seq": 2
+                }
+              ],
+              "config-type": "juju",
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 0
+              },
+              "juju": {
+                "charm": "vpe-router"
+              }
+            },
+            "vnfd-id-ref": "c49db92a-d6d8-11e5-9537-6cb3113b406f",
+            "member-vnf-index": 1
+          }
+        ],
+        "short-name": "tr_juju_nsd",
+        "vld": [
+          {
+            "description": "Link from TR to ELAN",
+            "type": "ELAN",
+            "version": 1,
+            "short-name": "Link1",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 1,
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp0",
+                "vnfd-id-ref": "c49db92a-d6d8-11e5-9537-6cb3113b406f"
+              }
+            ],
+            "name": "Link1",
+            "vendor": "RIFT.io",
+            "id": "c4f9dc50-d6d8-11e5-864f-6cb3113b406f"
+          }
+        ],
+        "config-primitive": [
+          {
+            "parameter": [
+              {
+                "data-type": "string",
+                "name": "Corporation Name",
+                "mandatory": "true"
+              },
+              {
+                "data-type": "integer",
+                "name": "Tunnel Key",
+                "default-value": 1,
+                "mandatory": "true"
+              }
+            ],
+            "name": "Add Corporation",
+            "parameter-group": [
+              {
+                "parameter": [
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Gateway",
+                    "default-value": "10.0.1.1",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Network",
+                    "default-value": "10.0.1.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Interface Name",
+                    "default-value": "eth3",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network",
+                    "default-value": "10.255.255.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network Area",
+                    "default-value": 0,
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "integer",
+                    "name": "Vlan ID",
+                    "default-value": 101,
+                    "mandatory": "true"
+                  }
+                ],
+                "name": "PE1",
+                "mandatory": "false"
+              },
+              {
+                "parameter": [
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Gateway",
+                    "default-value": "10.0.2.1",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Network",
+                    "default-value": "10.0.2.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Interface Name",
+                    "default-value": "eth3",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network",
+                    "default-value": "10.255.255.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network Area",
+                    "default-value": 0,
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "integer",
+                    "name": "Vlan ID",
+                    "default-value": 102,
+                    "mandatory": "true"
+                  }
+                ],
+                "name": "PE2",
+                "mandatory": "false"
+              },
+              {
+                "parameter": [
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Gateway",
+                    "default-value": "10.0.4.1",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Network",
+                    "default-value": "10.0.4.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Interface Name",
+                    "default-value": "eth4",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network",
+                    "default-value": "10.255.255.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network Area",
+                    "default-value": 0,
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "integer",
+                    "name": "Vlan ID",
+                    "default-value": 108,
+                    "mandatory": "true"
+                  }
+                ],
+                "name": "PE3",
+                "mandatory": "false"
+              }
+            ],
+            "user-defined-script": "/home/rift/.install/usr/bin/add_corporation.py"
+          },
+          {
+            "parameter": [
+              {
+                "data-type": "string",
+                "name": "Corporation Name",
+                "mandatory": "true"
+              },
+              {
+                "data-type": "integer",
+                "name": "Tunnel Key",
+                "default-value": 10,
+                "mandatory": "true"
+              }
+            ],
+            "name": "Add SP Test Corporation",
+            "parameter-group": [
+              {
+                "parameter": [
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Gateway",
+                    "default-value": "10.0.1.1",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Network",
+                    "default-value": "10.0.1.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Interface Name",
+                    "default-value": "eth3",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network",
+                    "default-value": "10.255.255.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network Area",
+                    "default-value": 0,
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "integer",
+                    "name": "Vlan ID",
+                    "default-value": 3000,
+                    "mandatory": "true"
+                  }
+                ],
+                "name": "PE1",
+                "mandatory": "false"
+              },
+              {
+                "parameter": [
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Gateway",
+                    "default-value": "10.0.2.1",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Network",
+                    "default-value": "10.0.2.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Interface Name",
+                    "default-value": "eth3",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network",
+                    "default-value": "10.255.255.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network Area",
+                    "default-value": 0,
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "integer",
+                    "name": "Vlan ID",
+                    "default-value": 3000,
+                    "mandatory": "true"
+                  }
+                ],
+                "name": "PE2",
+                "mandatory": "false"
+              },
+              {
+                "parameter": [
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Gateway",
+                    "default-value": "10.0.3.1",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Corp. Network",
+                    "default-value": "10.0.3.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Interface Name",
+                    "default-value": "eth3",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network",
+                    "default-value": "10.255.255.0/24",
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "string",
+                    "name": "Local Network Area",
+                    "default-value": 0,
+                    "mandatory": "true"
+                  },
+                  {
+                    "data-type": "integer",
+                    "name": "Vlan ID",
+                    "default-value": 3000,
+                    "mandatory": "true"
+                  }
+                ],
+                "name": "PE3",
+                "mandatory": "false"
+              }
+            ],
+            "user-defined-script": "/home/rift/.install/usr/bin/add_corporation.py"
+          }
+        ],
+        "name": "tr_juju_nsd",
+        "vendor": "6Wind",
+        "id": "c4f7fb6a-d6d8-11e5-864f-6cb3113b406f",
+        "meta": {
+          "instance-ref-count": 0
+        }
+      },
+      {
+        "description": "NS Clearewater IMS only",
+        "input-parameter-xpath": [
+          {
+            "label": "net-corp-vlan",
+            "default-value": 55,
+            "xpath": "/nsd:nsd-catalog/nsd:nsd[nsd:id=c719e6ba-d6d8-11e5-8962-6cb3113b406f]/nsd:vld[nsd:id=c71b347a-d6d8-11e5-8962-6cb3113b406f]/nsd:provider-network/manotypes:segmentation_id"
+          }
+        ],
+        "version": 1,
+        "constituent-vnfd": [
+          {
+            "vnf-configuration": {
+              "config-primitive": [
+                {
+                  "parameter": [
+                    {
+                      "data-type": "string",
+                      "name": "base_number"
+                    },
+                    {
+                      "data-type": "string",
+                      "name": "home_domain"
+                    },
+                    {
+                      "data-type": "integer",
+                      "name": "number_count"
+                    },
+                    {
+                      "data-type": "string",
+                      "name": "password"
+                    }
+                  ],
+                  "name": "config"
+                },
+                {
+                  "parameter": [
+                    {
+                      "data-type": "string",
+                      "name": "number",
+                      "mandatory": "true"
+                    },
+                    {
+                      "data-type": "string",
+                      "name": "password",
+                      "mandatory": "true"
+                    }
+                  ],
+                  "name": "create-update-user"
+                },
+                {
+                  "parameter": [
+                    {
+                      "data-type": "string",
+                      "name": "number",
+                      "mandatory": "true"
+                    }
+                  ],
+                  "name": "delete-user"
+                }
+              ],
+              "config-type": "juju",
+              "initial-config-primitive": [
+                {
+                  "parameter": [
+                    {
+                      "name": "proxied_ip",
+                      "value": "<rw_mgmt_ip>"
+                    }
+                  ],
+                  "name": "config",
+                  "seq": 1
+                }
+              ],
+              "input-params": {
+                "config-delay": 0,
+                "config-priority": 1
+              },
+              "juju": {
+                "charm": "clearwater-aio-proxy"
+              }
+            },
+            "vnfd-id-ref": "c663ea54-d6d8-11e5-9f1a-6cb3113b406f",
+            "member-vnf-index": 1
+          }
+        ],
+        "short-name": "cwims_juju_nsd",
+        "vld": [
+          {
+            "description": "Link from cwims to ELAN",
+            "type": "ELAN",
+            "version": 1,
+            "provider-network": {
+              "physical-network": "physnet1",
+              "overlay-type": "VLAN"
+            },
+            "short-name": "net-corp",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 1,
+                "vnfd-connection-point-ref": "cwims_vnfd/cp0",
+                "vnfd-id-ref": "c663ea54-d6d8-11e5-9f1a-6cb3113b406f"
+              }
+            ],
+            "name": "net-corp",
+            "vendor": "RIFT.io",
+            "id": "c71b347a-d6d8-11e5-8962-6cb3113b406f"
+          }
+        ],
+        "config-primitive": [
+          {
+            "name": "Add User",
+            "vnf-primitive-group": [
+              {
+                "vnfd-name": "cwims_vnfd",
+                "member-vnf-index-ref": 1,
+                "vnfd-id-ref": "c663ea54-d6d8-11e5-9f1a-6cb3113b406f",
+                "primitive": [
+                  {
+                    "index": 1,
+                    "name": "create-update-user"
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "name": "Delete User",
+            "vnf-primitive-group": [
+              {
+                "vnfd-name": "cwims_vnfd",
+                "member-vnf-index-ref": 1,
+                "vnfd-id-ref": "c663ea54-d6d8-11e5-9f1a-6cb3113b406f",
+                "primitive": [
+                  {
+                    "index": 1,
+                    "name": "delete-user"
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "name": "Update Domain",
+            "vnf-primitive-group": [
+              {
+                "vnfd-name": "cwims_vnfd",
+                "member-vnf-index-ref": 1,
+                "vnfd-id-ref": "c663ea54-d6d8-11e5-9f1a-6cb3113b406f",
+                "primitive": [
+                  {
+                    "index": 1,
+                    "name": "config"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "name": "cwims_juju_nsd",
+        "vendor": "RIFT.io",
+        "id": "c719e6ba-d6d8-11e5-8962-6cb3113b406f",
+        "meta": {
+          "instance-ref-count": 0
+        }
+      }
+    ]
+  },
+  {
+    "id": "GUID-2",
+    "name": "RIFT.ware™ VNF Descriptors Catalog",
+    "short-name": "rift.ware-vnfd-cat",
+    "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+    "vendor": "RIFT.io",
+    "version": "",
+    "created-on": "",
+    "type": "vnfd",
+    "meta": {
+      "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_3\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <g> <path d=\"M58.852,62.447l-4.662-1.033c-0.047-3.138-0.719-6.168-1.996-9.007l3.606-2.92c0.858-0.695,0.99-1.954,0.296-2.813 l-4.521-5.584c-0.334-0.413-0.818-0.675-1.346-0.731c-0.525-0.057-1.056,0.102-1.468,0.435L45.25,43.64v0 c-2.486-1.907-5.277-3.259-8.297-4.019v-4.458c0-1.104-0.896-2-2-2H27.77c-1.104,0-2,0.896-2,2v4.461 c-3.08,0.777-5.922,2.171-8.447,4.144l-3.545-2.82c-0.415-0.33-0.94-0.479-1.472-0.422c-0.527,0.06-1.009,0.327-1.339,0.743 l-4.472,5.623c-0.688,0.864-0.544,2.123,0.32,2.81l3.642,2.896v0c-1.25,2.848-1.895,5.88-1.916,9.011l-4.666,1.078 c-1.076,0.249-1.747,1.322-1.499,2.398l1.616,7.001c0.249,1.077,1.325,1.747,2.399,1.499l4.813-1.111v0 c1.429,2.681,3.344,5.017,5.691,6.943l-2.17,4.55c-0.476,0.997-0.054,2.19,0.943,2.666l6.484,3.094 c0.271,0.129,0.566,0.195,0.861,0.195c0.226,0,0.451-0.038,0.668-0.115c0.5-0.177,0.909-0.545,1.138-1.024l2.198-4.611 c2.923,0.563,5.966,0.554,8.879-0.033l2.236,4.585c0.484,0.994,1.685,1.403,2.675,0.921l6.456-3.148 c0.992-0.484,1.405-1.682,0.921-2.674l-2.206-4.524c2.335-1.946,4.231-4.301,5.639-6.999l4.812,1.067 c1.076,0.237,2.146-0.441,2.385-1.52l1.556-7.014c0.115-0.518,0.02-1.06-0.266-1.508C59.82,62.878,59.369,62.562,58.852,62.447z M40.18,61.761c0,4.859-3.953,8.812-8.813,8.812c-4.858,0-8.811-3.953-8.811-8.812s3.952-8.812,8.811-8.812 C36.227,52.949,40.18,56.902,40.18,61.761z\"/> <path d=\"M64.268,45.324c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.826,0.353,3.736,0.345,5.551-0.021l1.07,2.195 c0.484,0.992,1.682,1.405,2.675,0.921l2.691-1.313c0.477-0.233,0.842-0.646,1.015-1.147c0.172-0.501,0.139-1.051-0.095-1.528 l-1.052-2.155c1.458-1.214,2.645-2.686,3.527-4.377l2.278,0.504c1.075,0.238,2.146-0.442,2.386-1.52l0.647-2.923 c0.238-1.078-0.442-2.146-1.521-2.385l-2.184-0.484c-0.028-1.962-0.449-3.857-1.248-5.632l1.673-1.355 c0.412-0.334,0.675-0.818,0.73-1.345s-0.102-1.056-0.436-1.468l-1.884-2.327c-0.697-0.859-1.957-0.99-2.813-0.295l-1.614,1.307 c-1.554-1.193-3.299-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.04 c-1.927,0.486-3.703,1.358-5.28,2.592l-1.634-1.298c-0.862-0.687-2.12-0.543-2.81,0.32l-1.864,2.344 c-0.33,0.416-0.481,0.945-0.422,1.472c0.061,0.527,0.327,1.009,0.743,1.339l1.69,1.345c-0.78,1.779-1.184,3.676-1.197,5.636 l-2.189,0.505c-0.517,0.119-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51l0.675,2.918 c0.249,1.076,1.323,1.747,2.398,1.498l2.28-0.527c0.892,1.676,2.089,3.137,3.559,4.343l-1.035,2.17 c-0.228,0.479-0.257,1.028-0.08,1.528c0.178,0.5,0.546,0.91,1.024,1.138l2.703,1.289C63.686,45.261,63.979,45.324,64.268,45.324z M64.334,27.961c0-3.039,2.473-5.51,5.512-5.51c3.038,0,5.51,2.472,5.51,5.51c0,3.039-2.472,5.511-5.51,5.511 C66.807,33.472,64.334,31,64.334,27.961z\"/> <path d=\"M96.107,66.441l-2.182-0.484c-0.028-1.961-0.449-3.856-1.25-5.632l1.675-1.355c0.412-0.334,0.675-0.818,0.73-1.346 c0.056-0.527-0.102-1.056-0.436-1.468l-1.885-2.327c-0.695-0.859-1.956-0.99-2.813-0.295l-1.614,1.307 c-1.555-1.193-3.3-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.041 c-1.929,0.486-3.706,1.358-5.282,2.592l-0.001,0l-1.631-1.298c-0.415-0.331-0.938-0.482-1.472-0.422 c-0.527,0.06-1.009,0.327-1.339,0.742l-1.863,2.343c-0.688,0.865-0.544,2.123,0.32,2.811l1.691,1.345 c-0.782,1.784-1.186,3.68-1.199,5.636l-2.188,0.505c-0.517,0.12-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51 l0.675,2.918c0.249,1.076,1.327,1.744,2.397,1.498l2.281-0.526c0.893,1.677,2.09,3.138,3.558,4.343h0.001l-1.035,2.168 c-0.229,0.479-0.258,1.029-0.081,1.529c0.178,0.5,0.546,0.909,1.024,1.138l2.702,1.289c0.278,0.132,0.571,0.195,0.86,0.195 c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.828,0.353,3.739,0.347,5.552-0.021l1.071,2.194 c0.484,0.992,1.682,1.405,2.675,0.921l2.69-1.312c0.477-0.233,0.842-0.645,1.014-1.147c0.173-0.501,0.14-1.051-0.093-1.528 l-1.052-2.155c1.459-1.215,2.645-2.688,3.525-4.377l2.278,0.505c0.52,0.116,1.061,0.02,1.508-0.266 c0.447-0.285,0.763-0.736,0.878-1.254l0.647-2.923C97.866,67.748,97.186,66.681,96.107,66.441z M85.162,66.174 c0,3.039-2.471,5.511-5.508,5.511c-3.039,0-5.512-2.472-5.512-5.511c0-3.039,2.473-5.511,5.512-5.511 C82.691,60.664,85.162,63.136,85.162,66.174z\"/> </g> </svg> "
+    },
+    "descriptors": [
+      {
+        "description": "This is a Benu ClientSim VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "clientsim_vnfd/cp0"
+              },
+              {
+                "name": "eth2",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "clientsim_vnfd/cp1"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 8192,
+              "storage-gb": 80,
+              "vcpu-count": 2
+            },
+            "name": "master",
+            "image": "clientsim-benu.qcow2",
+            "id": "19550ac8-c51c-11e5-b578-001b21b98a89",
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nruncmd:\n  - [ systemctl, daemon-reload ]\n  - [ systemctl, start, --no-block, ngnix.service ]\n  - [ systemctl, start, --no-block, php-fpm.service ]\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "clientsim_vnfd/cp0",
+            "type": "VPORT"
+          },
+          {
+            "name": "clientsim_vnfd/cp1",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "19550ac8-c51c-11e5-b578-001b21b98a89",
+          "dashboard-params": {
+            "port": 8008,
+            "path": "/"
+          },
+          "port": 2022
+        },
+        "version": 1,
+        "short-name": "clientsim_vnfd",
+        "name": "clientsim_vnfd",
+        "vendor": "RIFT.io",
+        "id": "1953f58e-c51c-11e5-b578-001b21b98a89"
+      },
+      {
+        "description": "This is a 6Wind TurboRouter VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp0"
+              },
+              {
+                "name": "eth2",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp1"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "storage-gb": 40,
+              "vcpu-count": 2
+            },
+            "name": "iovdu",
+            "image": "turbo-router-riftio-4-sriov.img.qcow2",
+            "id": "2302e4c8-d6b5-11e5-8e3f-001b21b98a89",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "turborouter_vnfd/cp0",
+            "type": "VPORT"
+          },
+          {
+            "name": "turborouter_vnfd/cp1",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "2302e4c8-d6b5-11e5-8e3f-001b21b98a89",
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "turborouter_vnfd",
+        "name": "turborouter_vnfd",
+        "vendor": "6Wind",
+        "id": "23028096-d6b5-11e5-8e3f-001b21b98a89"
+      },
+      {
+        "description": "This is a Riverbed Steelhead VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "Riverbed_SteelHead_vnfd/cp0"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "storage-gb": 40,
+              "vcpu-count": 2
+            },
+            "name": "iovdu",
+            "image": "riverbedimg",
+            "id": "2309cf5e-d6b5-11e5-9e33-001b21b98a89",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "Riverbed_SteelHead_vnfd/cp0",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "2309cf5e-d6b5-11e5-9e33-001b21b98a89",
+          "dashboard-params": {
+            "port": 80,
+            "path": "/"
+          },
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "Riverbed_SteelHead_vnfd",
+        "name": "Riverbed_SteelHead_vnfd",
+        "vendor": "Riverbed",
+        "http-endpoint": [
+          {
+            "password": "password",
+            "polling_interval_secs": 2,
+            "path": "rest/info",
+            "username": "admin"
+          }
+        ],
+        "id": "23095c22-d6b5-11e5-9e33-001b21b98a89"
+      },
+      {
+        "description": "This is a F5 Big-IP load balancer VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "F5_BigIP_vnfd/cp0"
+              },
+              {
+                "name": "eth2",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "F5_BigIP_vnfd/cp1"
+              },
+              {
+                "name": "eth3",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "F5_BigIP_vnfd/cp2"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "storage-gb": 40,
+              "vcpu-count": 2
+            },
+            "name": "iovdu",
+            "image": "BIGIP-11.6.0.6.146.442.qcow2",
+            "id": "232a52ba-d6b5-11e5-98fb-001b21b98a89",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "F5_BigIP_vnfd/cp0",
+            "type": "VPORT"
+          },
+          {
+            "name": "F5_BigIP_vnfd/cp1",
+            "type": "VPORT"
+          },
+          {
+            "name": "F5_BigIP_vnfd/cp2",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "232a52ba-d6b5-11e5-98fb-001b21b98a89",
+          "dashboard-params": {
+            "https": "true",
+            "port": 443,
+            "path": "/"
+          },
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "F5_BigIP_vnfd",
+        "name": "F5_BigIP_vnfd",
+        "vendor": "F5 Networks",
+        "http-endpoint": [
+          {
+            "password": "password",
+            "polling_interval_secs": 2,
+            "path": "rest/info",
+            "username": "admin"
+          }
+        ],
+        "id": "2329d470-d6b5-11e5-98fb-001b21b98a89"
+      },
+      {
+        "description": "This is a Clearwater IMS VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "cwims_vnfd/cp0"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "storage-gb": 40,
+              "vcpu-count": 2
+            },
+            "name": "iovdu",
+            "image": "cw-aio.qcow2",
+            "id": "2408452a-d6b5-11e5-95d4-001b21b98a89",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "cwims_vnfd/cp0",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "2408452a-d6b5-11e5-95d4-001b21b98a89",
+          "dashboard-params": {
+            "port": 80,
+            "path": "/"
+          },
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "cwims_vnfd",
+        "name": "cwims_vnfd",
+        "vendor": "Clearwater",
+        "http-endpoint": [
+          {
+            "password": "vyatta",
+            "polling_interval_secs": 2,
+            "path": "rest/app/gui/dashboard/sysinfo",
+            "username": "vyatta"
+          }
+        ],
+        "id": "2407d7a2-d6b5-11e5-95d4-001b21b98a89"
+      },
+      {
+        "description": "This is a RIFT.ware Trafgen VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "trafgen_vnfd/cp0"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 16384,
+              "storage-gb": 32,
+              "vcpu-count": 4
+            },
+            "name": "iovdu",
+            "image": "rift-root-latest-trafgen-k2.qcow2",
+            "id": "2545bca6-d6b5-11e5-9bb7-001b21b98a89",
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nruncmd:\n  - [ systemctl, daemon-reload ]\n  - [ systemctl, enable, trafgen.service ]\n  - [ systemctl, start, --no-block, trafgen.service ]\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "trafgen_vnfd/cp0",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "2545bca6-d6b5-11e5-9bb7-001b21b98a89",
+          "port": 2022
+        },
+        "version": 1,
+        "short-name": "trafgen_vnfd",
+        "name": "trafgen_vnfd",
+        "vendor": "RIFT.io",
+        "http-endpoint": [
+          {
+            "polling_interval_secs": 3,
+            "headers": [
+              {
+                "key": "Accept",
+                "value": "json"
+              },
+              {
+                "key": "Content-type",
+                "value": "application/vnd.yang.data+json"
+              }
+            ],
+            "port": 8008,
+            "password": "fedora",
+            "path": "api/operational/vnf-opdata/vnf/trafgen,0/port-state",
+            "username": "fedora"
+          }
+        ],
+        "id": "2544951a-d6b5-11e5-9bb7-001b21b98a89",
+        "monitoring-param": [
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'trafgen_vnfd/cp0'].counters.'tx-rate-mbps'"
+            },
+            "description": "Outgoing byte rate of interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp0 Tx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 1000
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/trafgen,0/port-state",
+            "id": 1,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'trafgen_vnfd/cp0'].counters.'rx-rate-mbps'"
+            },
+            "description": "Incoming byte rate of interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp0 Rx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 1000
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/trafgen,0/port-state",
+            "id": 2,
+            "json-query-method": "OBJECTPATH"
+          }
+        ]
+      },
+      {
+        "description": "This is a RIFT.ware Trafsink VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "trafsink_vnfd/cp0"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 16384,
+              "storage-gb": 32,
+              "vcpu-count": 4
+            },
+            "name": "iovdu",
+            "image": "rift-root-latest-trafgen-j.qcow2",
+            "id": "26a19e3a-d6b5-11e5-a5c6-001b21b98a89",
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nruncmd:\n  - [ systemctl, daemon-reload ]\n  - [ systemctl, enable, trafsink.service ]\n  - [ systemctl, start, --no-block, trafsink.service ]\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "trafsink_vnfd/cp0",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "26a19e3a-d6b5-11e5-a5c6-001b21b98a89",
+          "port": 2022
+        },
+        "version": 1,
+        "short-name": "trafsink_vnfd",
+        "name": "trafsink_vnfd",
+        "vendor": "RIFT.io",
+        "http-endpoint": [
+          {
+            "polling_interval_secs": 3,
+            "headers": [
+              {
+                "key": "Accept",
+                "value": "json"
+              },
+              {
+                "key": "Content-type",
+                "value": "application/vnd.yang.data+json"
+              }
+            ],
+            "port": 8008,
+            "password": "fedora",
+            "path": "api/operational/vnf-opdata/vnf/trafsink,0/port-state",
+            "username": "fedora"
+          }
+        ],
+        "id": "26a08568-d6b5-11e5-a5c6-001b21b98a89",
+        "monitoring-param": [
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'trafsink_vnfd/cp0'].counters.'tx-rate-mbps'"
+            },
+            "description": "Outgoing bytes at interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp0 Tx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 1000
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/trafsink,0/port-state",
+            "id": 1,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'trafsink_vnfd/cp0'].counters.'rx-rate-mbps'"
+            },
+            "description": "Incoming bytes at interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp0 Rx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 1000
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/trafsink,0/port-state",
+            "id": 2,
+            "json-query-method": "OBJECTPATH"
+          }
+        ]
+      },
+      {
+        "description": "This is a Benu SSC VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "ssc_vnfd/cp0"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 8192,
+              "storage-gb": 48,
+              "vcpu-count": 2
+            },
+            "name": "master",
+            "image": "ssc-benu.qcow2",
+            "id": "2e981d3a-d00c-11e5-ab30-625662870761",
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nruncmd:\n  - [ service, startssc, start ]\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "ssc_vnfd/cp0",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "2e981d3a-d00c-11e5-ab30-625662870761",
+          "dashboard-params": {
+            "port": 80,
+            "path": "/"
+          },
+          "port": 2022
+        },
+        "version": 1,
+        "short-name": "ssc_vnfd",
+        "name": "ssc_vnfd",
+        "vendor": "RIFT.io",
+        "id": "2e9819f2-d00c-11e5-ab30-625662870761"
+      },
+      {
+        "description": "This is a Brocade vRouter VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth0",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp0"
+              },
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp1"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 8192,
+              "storage-gb": 40,
+              "vcpu-count": 4
+            },
+            "name": "iovdu",
+            "image": "vyatta-7.qcow2",
+            "id": "a6cf9a28-d6cc-11e5-9540-001b21b98a89",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "vrouter_vnfd/cp0",
+            "type": "VPORT"
+          },
+          {
+            "name": "vrouter_vnfd/cp1",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "a6cf9a28-d6cc-11e5-9540-001b21b98a89",
+          "dashboard-params": {
+            "port": 80,
+            "path": "/"
+          },
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "vrouter_vnfd",
+        "name": "vrouter_vnfd",
+        "vendor": "Brocade",
+        "http-endpoint": [
+          {
+            "password": "vyatta",
+            "polling_interval_secs": 3,
+            "port": 80,
+            "path": "rest/app/gui/dashboard/interfaces",
+            "username": "vyatta"
+          },
+          {
+            "password": "vyatta",
+            "polling_interval_secs": 3,
+            "port": 80,
+            "path": "rest/app/gui/dashboard/sysinfo",
+            "username": "vyatta"
+          }
+        ],
+        "id": "a6ce0f96-d6cc-11e5-9540-001b21b98a89",
+        "monitoring-param": [
+          {
+            "json-query-params": {
+              "json-path": "$.system.mem_total"
+            },
+            "description": "Memory usage of vrouter",
+            "widget-type": "COUNTER",
+            "group-tag": "Group1",
+            "units": "KB",
+            "value-type": "INT",
+            "name": "Total memory",
+            "http-endpoint-ref": "rest/app/gui/dashboard/sysinfo",
+            "id": 1,
+            "json-query-method": "JSONPATH"
+          },
+          {
+            "json-query-params": {
+              "json-path": "$.system.mem"
+            },
+            "description": "Memory utilization of vrouter",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "%",
+            "value-type": "DECIMAL",
+            "name": "Memory utilization",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 100
+            },
+            "http-endpoint-ref": "rest/app/gui/dashboard/sysinfo",
+            "id": 2,
+            "json-query-method": "JSONPATH"
+          },
+          {
+            "json-query-params": {
+              "json-path": "$.system.cpu[0].usage"
+            },
+            "description": "CPU utilization (all) of vrouter",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "%",
+            "value-type": "DECIMAL",
+            "name": "CPU utilization",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 100
+            },
+            "http-endpoint-ref": "rest/app/gui/dashboard/sysinfo",
+            "id": 3,
+            "json-query-method": "JSONPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..interfaces[@.name is 'dp0s6']['in']"
+            },
+            "description": "Incoming bytes at interface",
+            "widget-type": "COUNTER",
+            "group-tag": "Group2",
+            "units": "bytes",
+            "value-type": "INT",
+            "name": "Interface[dp0s6] Rx",
+            "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+            "id": 4,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..interfaces[@.name is 'dp0s6']['out']"
+            },
+            "description": "Outgoing bytes at interface",
+            "widget-type": "COUNTER",
+            "group-tag": "Group2",
+            "units": "bytes",
+            "value-type": "INT",
+            "name": "Interface[dp0s6] Tx",
+            "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+            "id": 5,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..interfaces[@.name is 'tun0']['in']"
+            },
+            "description": "Incoming bytes at interface",
+            "widget-type": "COUNTER",
+            "group-tag": "Group2",
+            "units": "bytes",
+            "value-type": "INT",
+            "name": "Interface[tun0] Rx",
+            "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+            "id": 6,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..interfaces[@.name is 'tun0']['out']"
+            },
+            "description": "Outgoing bytes at interface",
+            "widget-type": "COUNTER",
+            "group-tag": "Group2",
+            "units": "bytes",
+            "value-type": "INT",
+            "name": "Interface[tun0] Tx",
+            "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+            "id": 7,
+            "json-query-method": "OBJECTPATH"
+          }
+        ]
+      },
+      {
+        "description": "This is a Benu VSE-SI VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "vm-flavor": {
+              "memory-mb": 16384,
+              "storage-gb": 64,
+              "vcpu-count": 4
+            },
+            "name": "RW.VM.MASTER",
+            "image": "Benu_VSE_Image_02_09.qcow2",
+            "id": "c1bb1a92-aa48-4908-89b2-5a78ff324953",
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nwrite_files:\n  - path: /opt/rift/.vnf_start_conf\n    content: |\n        VNFNAME=\"vsesi\"\n        VDUNAME={{ vdu.name }}\n        MASTERIP= \nruncmd: \n  - [ systemctl, daemon-reload ]\n  - [ systemctl, enable, multivmvnf.service ]\n  - [ systemctl, start, --no-block, multivmvnf.service ]\n"
+          },
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "vsesi_vnfd/cp0"
+              },
+              {
+                "name": "eth2",
+                "virtual-interface": {
+                  "type": "SR-IOV"
+                },
+                "vnfd-connection-point-ref": "vsesi_vnfd/cp1"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 32768,
+              "storage-gb": 128,
+              "vcpu-count": 4
+            },
+            "name": "RW.VM.FASTPATH.LEAD",
+            "image": "Benu_VSE_Image_02_09.qcow2",
+            "id": "d1bb1a92-aa48-4908-89b2-5a78ff324953",
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }                                                                                                                 \nssh_pwauth: True\nwrite_files:\n  - path: /opt/rift/.vnf_start_conf\n    content: |\n        VNFNAME=\"vsesi\"\n        VDUNAME={{ vdu.name }}\n        MASTERIP= {{ vdu[c1bb1a92-aa48-4908-89b2-5a78ff324953].mgmt.ip }}\nruncmd:\n  - [ systemctl, daemon-reload ]\n  - [ systemctl, enable, multivmvnf.service ]\n  - [ systemctl, start, --no-block, multivmvnf.service ]\n  - [ systemctl, enable, benuvnf.service ]\n  - [ systemctl, start, --no-block, benuvnf.service ]\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "vsesi_vnfd/cp0",
+            "type": "VPORT"
+          },
+          {
+            "name": "vsesi_vnfd/cp1",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "c1bb1a92-aa48-4908-89b2-5a78ff324953",
+          "port": 2022
+        },
+        "version": 1,
+        "short-name": "vsesi_vnfd",
+        "name": "vsesi_vnfd",
+        "vendor": "Benu",
+        "http-endpoint": [
+          {
+            "polling_interval_secs": 3,
+            "headers": [
+              {
+                "key": "Accept",
+                "value": "json"
+              },
+              {
+                "key": "Content-type",
+                "value": "application/vnd.yang.data+json"
+              }
+            ],
+            "port": 8008,
+            "password": "fedora",
+            "path": "api/operational/vnf-opdata/vnf/vsesi,0/port-state",
+            "username": "fedora"
+          }
+        ],
+        "id": "b1633f8c-ce8c-11e5-a62b-001b21b98a89",
+        "monitoring-param": [
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'vsesi/1/1'].counters.'tx-rate-mbps'"
+            },
+            "description": "Outgoing byte rate of interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp0 Tx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 100
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/vsesi,0/port-state",
+            "id": 1,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'vsesi/1/1'].counters.'rx-rate-mbps'"
+            },
+            "description": "Incoming byte rate of interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group1",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp0 Rx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 100
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/vsesi,0/port-state",
+            "id": 2,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'vsesi/1/2'].counters.'tx-rate-mbps'"
+            },
+            "description": "Outgoing byte rate of interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group2",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp1 Tx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 100
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/vsesi,0/port-state",
+            "id": 3,
+            "json-query-method": "OBJECTPATH"
+          },
+          {
+            "json-query-params": {
+              "object-path": "$..*[@.portname is 'vsesi/1/2'].counters.'rx-rate-mbps'"
+            },
+            "description": "Incoming byte rate of interface",
+            "widget-type": "GAUGE",
+            "group-tag": "Group2",
+            "units": "mbps",
+            "value-type": "INT",
+            "name": "Cp1 Rx Rate",
+            "numeric-constraints": {
+              "min-value": 0,
+              "max-value": 100
+            },
+            "http-endpoint-ref": "api/operational/vnf-opdata/vnf/vsesi,0/port-state",
+            "id": 4,
+            "json-query-method": "OBJECTPATH"
+          }
+        ]
+      },
+      {
+        "description": "This is a 6Wind TurboRouter VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp0"
+              },
+              {
+                "name": "eth2",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "turborouter_vnfd/cp1"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "storage-gb": 40,
+              "vcpu-count": 2
+            },
+            "name": "iovdu",
+            "image": "turbo-router-riftio-5.img.qcow2",
+            "id": "c49dffe8-d6d8-11e5-9537-6cb3113b406f",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "turborouter_vnfd/cp0",
+            "type": "VPORT"
+          },
+          {
+            "name": "turborouter_vnfd/cp1",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "c49dffe8-d6d8-11e5-9537-6cb3113b406f",
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "turborouter_vnfd",
+        "name": "turborouter_vnfd",
+        "vendor": "6Wind",
+        "id": "c49db92a-d6d8-11e5-9537-6cb3113b406f"
+      },
+      {
+        "description": "This is a Clearwater IMS VNF",
+        "vdu": [
+          {
+            "count": 1,
+            "external-interface": [
+              {
+                "name": "eth1",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "vnfd-connection-point-ref": "cwims_vnfd/cp0"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "storage-gb": 40,
+              "vcpu-count": 2
+            },
+            "name": "iovdu",
+            "image": "cw-aio.qcow2",
+            "id": "c66438c4-d6d8-11e5-9f1a-6cb3113b406f",
+            "cloud-init": "#cloud-config\n"
+          }
+        ],
+        "connection-point": [
+          {
+            "name": "cwims_vnfd/cp0",
+            "type": "VPORT"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "c66438c4-d6d8-11e5-9f1a-6cb3113b406f",
+          "dashboard-params": {
+            "port": 80,
+            "path": "/"
+          },
+          "port": 80
+        },
+        "version": 1,
+        "short-name": "cwims_vnfd",
+        "name": "cwims_vnfd",
+        "vendor": "Clearwater",
+        "http-endpoint": [
+          {
+            "password": "vyatta",
+            "polling_interval_secs": 2,
+            "path": "rest/app/gui/dashboard/sysinfo",
+            "username": "vyatta"
+          }
+        ],
+        "id": "c663ea54-d6d8-11e5-9f1a-6cb3113b406f"
+      }
+    ]
+  },
+  {
+    "id": "GUID-3",
+    "name": "RIFT.ware™ PNF Descriptors Catalog",
+    "short-name": "rift.ware-pnfd-cat",
+    "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+    "vendor": "RIFT.io",
+    "version": "",
+    "created-on": "",
+    "type": "pnfd",
+    "meta": {
+      "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_4\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <path d=\"M86.334,47.444V35.759H13.666v11.686h3.561v5.111h-3.561v11.686h72.668V52.556h-4.108v-5.111H86.334z M26.628,59.454h-5.051 v-4.941h5.051V59.454z M26.628,52.404h-5.051v-4.941h5.051V52.404z M26.628,45.486h-5.051v-4.941h5.051V45.486z M34.094,59.454 h-5.051v-4.941h5.051V59.454z M34.094,52.404h-5.051v-4.941h5.051V52.404z M34.094,45.486h-5.051v-4.941h5.051V45.486z M41.452,59.454h-5.051v-4.941h5.051V59.454z M41.452,52.404h-5.051v-4.941h5.051V52.404z M41.452,45.486h-5.051v-4.941h5.051 V45.486z M48.733,59.454h-5.051v-4.941h5.051V59.454z M48.733,52.404h-5.051v-4.941h5.051V52.404z M48.733,45.486h-5.051v-4.941 h5.051V45.486z M56.2,59.454h-5.051v-4.941H56.2V59.454z M56.2,52.404h-5.051v-4.941H56.2V52.404z M56.2,45.486h-5.051v-4.941H56.2 V45.486z M63.558,59.454h-5.05v-4.941h5.05V59.454z M63.558,52.404h-5.05v-4.941h5.05V52.404z M63.558,45.486h-5.05v-4.941h5.05 V45.486z M74.858,59.312h-6.521v-3.013h6.521V59.312z M71.572,50.854c-2.875,0-5.204-2.33-5.204-5.203s2.329-5.203,5.204-5.203 s5.204,2.33,5.204,5.203S74.446,50.854,71.572,50.854z M74.858,45.618c0,1.801-1.46,3.261-3.261,3.261 c-1.8,0-3.261-1.46-3.261-3.261s1.46-3.26,3.261-3.26C73.398,42.358,74.858,43.817,74.858,45.618z\"/> </svg>"
+    },
+    "descriptors": []
+  }
+]
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/assets/empty-nsd-catalog.json b/skyquake/plugins/composer/src/src/assets/empty-nsd-catalog.json
new file mode 100644 (file)
index 0000000..db379d6
--- /dev/null
@@ -0,0 +1,290 @@
+[
+       {
+               "id": "GUID-1",
+               "name": "RIFT.ware™ NS Descriptors Catalog",
+               "short-name": "rift.ware-nsd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "nsd",
+               "descriptors": []
+       },
+       {
+               "id": "GUID-2",
+               "name": "RIFT.ware™ VNF Descriptors Catalog",
+               "short-name": "rift.ware-vnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "vnfd",
+               "descriptors": [
+                       {
+                               "id": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                               "name": "ping-vnfd",
+                               "short-name": "ping-vnfd",
+                               "vendor": "RIFT.io",
+                               "description": "This is an example RIFT.ware VNF",
+                               "version": "1.0",
+                               "internal-vld": [
+                                       {
+                                               "id": "ba1478fe-626b-11e5-998d-6cb3113b406f",
+                                               "name": "fabric",
+                                               "short-name": "fabric",
+                                               "description": "Virtual link for internal fabric",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "connection-point": [
+                                       {
+                                               "name": "ping-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "ping-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "ba14a504-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "ba153744-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "ba153744-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                               "name": "pong-vnfd",
+                               "short-name": "pong-vnfd",
+                               "vendor": "RIFT.io",
+                               "description": "This is an example RIFT.ware VNF",
+                               "version": "1.0",
+                               "internal-vld": [
+                                       {
+                                               "id": "ba195068-626b-11e5-998d-6cb3113b406f",
+                                               "name": "fabric",
+                                               "short-name": "fabric",
+                                               "description": "Virtual link for internal fabric",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "connection-point": [
+                                       {
+                                               "name": "pong-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "pong-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "ba1960ee-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "ba198696-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "ba198696-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-3",
+               "name": "RIFT.ware™ PNF Descriptors Catalog",
+               "short-name": "rift.ware-pnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "pnfd",
+               "descriptors": []
+       }
+]
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-144x144.png b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-144x144.png
new file mode 100644 (file)
index 0000000..4c4a4e9
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-144x144.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-192x192.png b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-192x192.png
new file mode 100644 (file)
index 0000000..457cbff
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-192x192.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-36x36.png b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-36x36.png
new file mode 100644 (file)
index 0000000..89bc496
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-36x36.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-48x48.png b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-48x48.png
new file mode 100644 (file)
index 0000000..27e0eda
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-48x48.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-72x72.png b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-72x72.png
new file mode 100644 (file)
index 0000000..ddb6815
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-72x72.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-96x96.png b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-96x96.png
new file mode 100644 (file)
index 0000000..063ac0f
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/android-chrome-96x96.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-114x114.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-114x114.png
new file mode 100644 (file)
index 0000000..978d123
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-114x114.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-120x120.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-120x120.png
new file mode 100644 (file)
index 0000000..c8c6a18
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-120x120.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-144x144.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-144x144.png
new file mode 100644 (file)
index 0000000..af3d971
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-144x144.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-152x152.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-152x152.png
new file mode 100644 (file)
index 0000000..1380273
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-152x152.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-180x180.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-180x180.png
new file mode 100644 (file)
index 0000000..705da61
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-180x180.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-57x57.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-57x57.png
new file mode 100644 (file)
index 0000000..98579a5
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-57x57.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-60x60.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-60x60.png
new file mode 100644 (file)
index 0000000..3556937
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-60x60.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-72x72.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-72x72.png
new file mode 100644 (file)
index 0000000..188a99a
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-72x72.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-76x76.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-76x76.png
new file mode 100644 (file)
index 0000000..b6ab765
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-76x76.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-precomposed.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-precomposed.png
new file mode 100644 (file)
index 0000000..e2ea832
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon-precomposed.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon.png b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon.png
new file mode 100644 (file)
index 0000000..705da61
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/apple-touch-icon.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/browserconfig.xml b/skyquake/plugins/composer/src/src/assets/favicons/browserconfig.xml
new file mode 100644 (file)
index 0000000..fe44cae
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+  <msapplication>
+    <tile>
+      <square70x70logo src="/mstile-70x70.png"/>
+      <square150x150logo src="/mstile-150x150.png"/>
+      <square310x310logo src="/mstile-310x310.png"/>
+      <wide310x150logo src="/mstile-310x150.png"/>
+      <TileColor>#da532c</TileColor>
+    </tile>
+  </msapplication>
+</browserconfig>
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/favicon-16x16.png b/skyquake/plugins/composer/src/src/assets/favicons/favicon-16x16.png
new file mode 100644 (file)
index 0000000..962310f
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/favicon-16x16.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/favicon-194x194.png b/skyquake/plugins/composer/src/src/assets/favicons/favicon-194x194.png
new file mode 100644 (file)
index 0000000..4fe8e4c
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/favicon-194x194.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/favicon-32x32.png b/skyquake/plugins/composer/src/src/assets/favicons/favicon-32x32.png
new file mode 100644 (file)
index 0000000..d5068bd
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/favicon-32x32.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/favicon-96x96.png b/skyquake/plugins/composer/src/src/assets/favicons/favicon-96x96.png
new file mode 100644 (file)
index 0000000..6c20bb0
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/favicon-96x96.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/favicon.ico b/skyquake/plugins/composer/src/src/assets/favicons/favicon.ico
new file mode 100644 (file)
index 0000000..0b7d4b7
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/favicon.ico differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/manifest.json b/skyquake/plugins/composer/src/src/assets/favicons/manifest.json
new file mode 100644 (file)
index 0000000..74798cf
--- /dev/null
@@ -0,0 +1,41 @@
+{
+       "name": "RIFT.ware",
+       "icons": [
+               {
+                       "src": "\/android-chrome-36x36.png",
+                       "sizes": "36x36",
+                       "type": "image\/png",
+                       "density": "0.75"
+               },
+               {
+                       "src": "\/android-chrome-48x48.png",
+                       "sizes": "48x48",
+                       "type": "image\/png",
+                       "density": "1.0"
+               },
+               {
+                       "src": "\/android-chrome-72x72.png",
+                       "sizes": "72x72",
+                       "type": "image\/png",
+                       "density": "1.5"
+               },
+               {
+                       "src": "\/android-chrome-96x96.png",
+                       "sizes": "96x96",
+                       "type": "image\/png",
+                       "density": "2.0"
+               },
+               {
+                       "src": "\/android-chrome-144x144.png",
+                       "sizes": "144x144",
+                       "type": "image\/png",
+                       "density": "3.0"
+               },
+               {
+                       "src": "\/android-chrome-192x192.png",
+                       "sizes": "192x192",
+                       "type": "image\/png",
+                       "density": "4.0"
+               }
+       ]
+}
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/mstile-144x144.png b/skyquake/plugins/composer/src/src/assets/favicons/mstile-144x144.png
new file mode 100644 (file)
index 0000000..aece734
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/mstile-144x144.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/mstile-150x150.png b/skyquake/plugins/composer/src/src/assets/favicons/mstile-150x150.png
new file mode 100644 (file)
index 0000000..8750124
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/mstile-150x150.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/mstile-310x150.png b/skyquake/plugins/composer/src/src/assets/favicons/mstile-310x150.png
new file mode 100644 (file)
index 0000000..db6d760
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/mstile-310x150.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/mstile-310x310.png b/skyquake/plugins/composer/src/src/assets/favicons/mstile-310x310.png
new file mode 100644 (file)
index 0000000..2cacdd1
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/mstile-310x310.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/mstile-70x70.png b/skyquake/plugins/composer/src/src/assets/favicons/mstile-70x70.png
new file mode 100644 (file)
index 0000000..34ab792
Binary files /dev/null and b/skyquake/plugins/composer/src/src/assets/favicons/mstile-70x70.png differ
diff --git a/skyquake/plugins/composer/src/src/assets/favicons/safari-pinned-tab.svg b/skyquake/plugins/composer/src/src/assets/favicons/safari-pinned-tab.svg
new file mode 100644 (file)
index 0000000..fa3c696
--- /dev/null
@@ -0,0 +1,69 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="1040.000000pt" height="1040.000000pt" viewBox="0 0 1040.000000 1040.000000"
+ preserveAspectRatio="xMidYMid meet">
+<metadata>
+Created by potrace 1.11, written by Peter Selinger 2001-2013
+</metadata>
+<g transform="translate(0.000000,1040.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M5259 8646 c-2 -2 -31 -6 -64 -10 -33 -3 -71 -9 -85 -12 -14 -3 -36
+-7 -50 -10 -14 -3 -32 -7 -40 -9 -8 -2 -30 -7 -47 -10 -55 -9 -260 -74 -351
+-110 -133 -54 -352 -189 -492 -304 -95 -78 -262 -252 -343 -359 -121 -159
+-181 -266 -292 -527 -38 -88 -94 -331 -112 -485 -10 -84 -10 -344 -1 -436 l8
+-71 -83 -51 c-45 -27 -119 -77 -162 -111 -113 -85 -179 -150 -322 -315 -52
+-59 -155 -225 -208 -332 -45 -91 -115 -276 -130 -343 -19 -81 -44 -228 -49
+-281 -7 -74 -8 -312 -2 -350 3 -14 9 -56 15 -95 17 -108 20 -123 53 -235 92
+-320 286 -629 530 -848 249 -222 565 -373 875 -417 21 -3 49 -8 63 -10 77 -15
+339 -18 1540 -20 l1325 -1 47 48 c119 123 211 311 234 478 l6 39 -1369 1
+c-1567 1 -1652 2 -1748 24 -5 2 -28 6 -50 11 -59 12 -236 79 -281 107 -21 13
+-52 30 -69 38 -16 8 -48 27 -70 43 -22 15 -51 35 -65 44 -55 37 -201 195 -257
+279 -113 168 -178 331 -210 530 -14 87 -8 322 11 408 70 322 237 581 498 774
+31 23 60 42 64 42 4 0 15 6 23 14 39 32 162 88 316 141 61 21 115 42 121 46 8
+6 4 36 -13 101 -65 261 -74 318 -78 492 -3 131 1 195 15 280 55 335 196 612
+427 838 220 217 463 341 793 403 90 17 322 24 410 11 222 -31 436 -105 599
+-208 60 -37 170 -117 197 -143 6 -5 31 -28 55 -50 141 -131 217 -244 393 -592
+31 -62 60 -114 64 -117 4 -2 61 36 127 86 256 191 340 237 520 282 88 22 144
+29 255 29 241 2 516 -118 705 -307 87 -87 132 -151 187 -261 30 -60 76 -180
+69 -180 -1 0 2 -12 8 -27 15 -40 24 -111 25 -208 2 -92 -3 -138 -35 -303 -11
+-59 -19 -112 -17 -118 2 -5 86 -43 188 -84 218 -88 312 -147 442 -278 181
+-182 300 -411 344 -660 15 -90 21 -277 10 -347 -3 -19 -8 -51 -10 -70 -33
+-251 -158 -494 -355 -690 -170 -168 -292 -240 -531 -311 -125 -37 -172 -43
+-357 -43 -146 -1 -153 -2 -154 -21 -4 -141 -57 -405 -104 -527 -7 -17 7 -18
+201 -18 287 0 405 15 599 76 351 110 611 281 849 557 166 194 319 490 372 722
+1 6 9 39 17 75 28 122 43 266 41 395 -3 149 -9 202 -48 401 -21 107 -108 322
+-188 464 -138 248 -381 494 -645 654 l-63 37 -1 92 c0 51 -3 106 -5 122 -2 17
+-7 50 -10 75 -4 25 -8 52 -9 60 -6 49 -52 208 -83 285 -170 434 -520 768 -962
+918 -179 61 -310 82 -510 82 -114 -1 -167 -4 -273 -20 -77 -11 -233 -56 -314
+-91 -45 -20 -87 -34 -92 -32 -5 1 -40 41 -77 88 -241 300 -559 525 -922 654
+-80 28 -207 63 -262 72 -19 3 -37 7 -40 9 -3 2 -33 7 -65 10 -33 4 -69 9 -80
+12 -23 6 -381 13 -386 9z"/>
+<path d="M2978 7475 c-2 -2 -33 -6 -69 -9 -437 -41 -892 -261 -1223 -591 -311
+-310 -505 -695 -581 -1155 -20 -116 -23 -251 -12 -539 l2 -44 -76 -46 c-125
+-76 -228 -158 -345 -275 -289 -291 -466 -648 -521 -1051 -10 -76 -10 -392 0
+-464 11 -81 34 -188 58 -266 11 -38 21 -74 23 -80 7 -34 65 -170 105 -248 177
+-348 455 -622 806 -796 124 -62 320 -137 379 -146 12 -2 59 -11 106 -20 133
+-25 368 -28 2420 -28 1952 -1 2363 3 2460 23 30 6 69 13 85 16 163 27 397 120
+575 227 217 131 439 353 595 595 82 127 191 386 211 502 3 14 9 39 14 55 40
+136 56 437 31 595 -16 101 -50 246 -67 293 -8 20 -14 40 -14 45 0 15 -34 111
+-68 192 -108 256 -273 493 -463 661 -41 36 -126 100 -189 142 -63 42 -122 82
+-132 89 -13 11 -17 38 -21 143 -6 152 -44 351 -86 450 -5 11 -19 45 -31 75
+-36 91 -169 324 -199 350 -3 3 -31 34 -61 70 -258 305 -616 495 -1030 546 -55
+7 -278 7 -335 0 -161 -19 -310 -58 -446 -116 -60 -25 -74 -28 -81 -17 -43 79
+-261 304 -390 404 l-66 52 -30 -72 c-63 -153 -89 -287 -88 -457 l1 -125 56
+-70 c31 -38 75 -98 98 -133 40 -60 231 -419 231 -434 0 -17 19 -4 145 94 242
+188 344 241 560 289 121 27 318 26 391 -2 13 -4 24 -7 24 -4 0 7 165 -52 220
+-80 98 -49 216 -133 274 -195 87 -95 177 -240 227 -367 58 -147 72 -336 38
+-528 -25 -142 -32 -186 -33 -208 -1 -14 22 -28 99 -58 257 -102 442 -215 539
+-328 12 -14 35 -41 52 -60 227 -263 332 -613 287 -961 -38 -300 -146 -519
+-370 -751 -163 -168 -425 -307 -633 -335 -25 -3 -49 -8 -53 -11 -20 -12 -481
+-15 -2297 -15 -1779 0 -2227 3 -2315 16 -160 24 -348 96 -485 184 -418 271
+-643 777 -559 1255 26 147 27 152 53 220 85 226 232 418 442 575 73 55 230
+140 304 165 91 32 243 86 245 89 2 2 -14 73 -36 158 -52 211 -71 334 -72 470
+0 273 73 530 221 772 29 48 58 93 65 100 7 7 25 31 42 53 77 105 264 266 400
+346 207 121 448 194 678 204 56 2 57 3 63 47 12 82 60 264 101 381 25 71 42
+132 38 135 -6 6 -281 12 -287 7z"/>
+</g>
+</svg>
diff --git a/skyquake/plugins/composer/src/src/assets/juju-catalog.json b/skyquake/plugins/composer/src/src/assets/juju-catalog.json
new file mode 100644 (file)
index 0000000..9fe0ceb
--- /dev/null
@@ -0,0 +1,936 @@
+[
+       {
+               "id": "GUID-1",
+               "name": "RIFT.ware™ NS Descriptors Catalog",
+               "short-name": "rift.ware-nsd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "nsd",
+               "descriptors": [
+                       {
+                               "id": "9c450720-d670-11e5-a5c7-6cb3113b406f",
+                               "config-primitive": [
+                                       {
+                                               "vnf-primitive-group": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b152c2e6-d34c-11e5-8463-6cb3113b406f",
+                                                               "primitive": [
+                                                                       {
+                                                                               "name": "create-update-user",
+                                                                               "index": 1
+                                                                       }
+                                                               ],
+                                                               "vnfd-name": "cwims_vnfd"
+                                                       }
+                                               ],
+                                               "name": "Add User"
+                                       },
+                                       {
+                                               "vnf-primitive-group": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b152c2e6-d34c-11e5-8463-6cb3113b406f",
+                                                               "primitive": [
+                                                                       {
+                                                                               "name": "delete-user",
+                                                                               "index": 1
+                                                                       }
+                                                               ],
+                                                               "vnfd-name": "cwims_vnfd"
+                                                       }
+                                               ],
+                                               "name": "Delete User"
+                                       },
+                                       {
+                                               "vnf-primitive-group": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b152c2e6-d34c-11e5-8463-6cb3113b406f",
+                                                               "primitive": [
+                                                                       {
+                                                                               "name": "config",
+                                                                               "index": 1
+                                                                       }
+                                                               ],
+                                                               "vnfd-name": "cwims_vnfd"
+                                                       }
+                                               ],
+                                               "name": "Update Domain"
+                                       }
+                               ],
+                               "description": "NS Clearewater IMS only",
+                               "vendor": "RIFT.io",
+                               "name": "cwims_juju_nsd",
+                               "input-parameter-xpath": [
+                                       {
+                                               "label": "net-corp-vlan",
+                                               "default-value": 55,
+                                               "xpath": "/nsd:nsd-catalog/nsd:nsd[nsd:id=9c450720-d670-11e5-a5c7-6cb3113b406f]/nsd:vld[nsd:id=9c4646c6-d670-11e5-a5c7-6cb3113b406f]/nsd:provider-network/manotypes:segmentation_id"
+                                       }
+                               ],
+                               "version": 1,
+                               "short-name": "cwims_juju_nsd",
+                               "vld": [
+                                       {
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b152c2e6-d34c-11e5-8463-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "cwims_vnfd/cp0"
+                                                       }
+                                               ],
+                                               "id": "9c4646c6-d670-11e5-a5c7-6cb3113b406f",
+                                               "provider-network": {
+                                                       "overlay-type": "VLAN",
+                                                       "physical-network": "physnet1"
+                                               },
+                                               "description": "Link from cwims to ELAN",
+                                               "vendor": "RIFT.io",
+                                               "name": "net-corp",
+                                               "version": 1,
+                                               "short-name": "net-corp",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "vnf-configuration": {
+                                                       "config-type": "juju",
+                                                       "initial-config-primitive": [
+                                                               {
+                                                                       "parameter": [
+                                                                               {
+                                                                                       "value": "<rw_mgmt_ip>",
+                                                                                       "name": "proxied_ip"
+                                                                               }
+                                                                       ],
+                                                                       "seq": 1,
+                                                                       "name": "config"
+                                                               }
+                                                       ],
+                                                       "juju": {
+                                                               "charm": "clearwater-aio-proxy"
+                                                       },
+                                                       "config-primitive": [
+                                                               {
+                                                                       "parameter": [
+                                                                               {
+                                                                                       "data-type": "string",
+                                                                                       "name": "base_number"
+                                                                               },
+                                                                               {
+                                                                                       "data-type": "string",
+                                                                                       "name": "home_domain"
+                                                                               },
+                                                                               {
+                                                                                       "data-type": "integer",
+                                                                                       "name": "number_count"
+                                                                               },
+                                                                               {
+                                                                                       "data-type": "string",
+                                                                                       "name": "password"
+                                                                               }
+                                                                       ],
+                                                                       "name": "config"
+                                                               },
+                                                               {
+                                                                       "parameter": [
+                                                                               {
+                                                                                       "data-type": "string",
+                                                                                       "name": "number",
+                                                                                       "mandatory": "true"
+                                                                               },
+                                                                               {
+                                                                                       "data-type": "string",
+                                                                                       "name": "password",
+                                                                                       "mandatory": "true"
+                                                                               }
+                                                                       ],
+                                                                       "name": "create-update-user"
+                                                               },
+                                                               {
+                                                                       "parameter": [
+                                                                               {
+                                                                                       "data-type": "string",
+                                                                                       "name": "number",
+                                                                                       "mandatory": "true"
+                                                                               }
+                                                                       ],
+                                                                       "name": "delete-user"
+                                                               }
+                                                       ],
+                                                       "input-params": {
+                                                               "config-priority": 1,
+                                                               "config-delay": 0
+                                                       }
+                                               },
+                                               "vnfd-id-ref": "b152c2e6-d34c-11e5-8463-6cb3113b406f",
+                                               "member-vnf-index": 1
+                                       }
+                               ],
+                               "meta": "{\"instance-ref-count\": 5}"
+                       },
+                       {
+                               "id": "9d887e58-d50f-11e5-80c8-6cb3113b406f",
+                               "config-primitive": [
+                                       {
+                                               "user-defined-script": "/home/rift/.install/usr/bin/add_corporation.py",
+                                               "parameter": [
+                                                       {
+                                                               "data-type": "string",
+                                                               "name": "Corporation Name",
+                                                               "mandatory": "true"
+                                                       },
+                                                       {
+                                                               "data-type": "integer",
+                                                               "default-value": 1,
+                                                               "name": "Tunnel Key",
+                                                               "mandatory": "true"
+                                                       }
+                                               ],
+                                               "name": "Add Corporation",
+                                               "parameter-group": [
+                                                       {
+                                                               "parameter": [
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.1.1",
+                                                                               "name": "Corp. Gateway",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.1.0/24",
+                                                                               "name": "Corp. Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "eth3",
+                                                                               "name": "Interface Name",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.255.255.0/24",
+                                                                               "name": "Local Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": 0,
+                                                                               "name": "Local Network Area",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "integer",
+                                                                               "default-value": 101,
+                                                                               "name": "Vlan ID",
+                                                                               "mandatory": "true"
+                                                                       }
+                                                               ],
+                                                               "name": "PE1",
+                                                               "mandatory": "false"
+                                                       },
+                                                       {
+                                                               "parameter": [
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.2.1",
+                                                                               "name": "Corp. Gateway",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.2.0/24",
+                                                                               "name": "Corp. Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "eth3",
+                                                                               "name": "Interface Name",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.255.255.0/24",
+                                                                               "name": "Local Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": 0,
+                                                                               "name": "Local Network Area",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "integer",
+                                                                               "default-value": 102,
+                                                                               "name": "Vlan ID",
+                                                                               "mandatory": "true"
+                                                                       }
+                                                               ],
+                                                               "name": "PE2",
+                                                               "mandatory": "false"
+                                                       },
+                                                       {
+                                                               "parameter": [
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.4.1",
+                                                                               "name": "Corp. Gateway",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.4.0/24",
+                                                                               "name": "Corp. Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "eth4",
+                                                                               "name": "Interface Name",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.255.255.0/24",
+                                                                               "name": "Local Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": 0,
+                                                                               "name": "Local Network Area",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "integer",
+                                                                               "default-value": 108,
+                                                                               "name": "Vlan ID",
+                                                                               "mandatory": "true"
+                                                                       }
+                                                               ],
+                                                               "name": "PE3",
+                                                               "mandatory": "false"
+                                                       }
+                                               ]
+                                       },
+                                       {
+                                               "user-defined-script": "/home/rift/.install/usr/bin/add_corporation.py",
+                                               "parameter": [
+                                                       {
+                                                               "data-type": "string",
+                                                               "name": "Corporation Name",
+                                                               "mandatory": "true"
+                                                       },
+                                                       {
+                                                               "data-type": "integer",
+                                                               "default-value": 10,
+                                                               "name": "Tunnel Key",
+                                                               "mandatory": "true"
+                                                       }
+                                               ],
+                                               "name": "Add SP Test Corporation",
+                                               "parameter-group": [
+                                                       {
+                                                               "parameter": [
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.1.1",
+                                                                               "name": "Corp. Gateway",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.1.0/24",
+                                                                               "name": "Corp. Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "eth3",
+                                                                               "name": "Interface Name",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.255.255.0/24",
+                                                                               "name": "Local Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": 0,
+                                                                               "name": "Local Network Area",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "integer",
+                                                                               "default-value": 3000,
+                                                                               "name": "Vlan ID",
+                                                                               "mandatory": "true"
+                                                                       }
+                                                               ],
+                                                               "name": "PE1",
+                                                               "mandatory": "false"
+                                                       },
+                                                       {
+                                                               "parameter": [
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.2.1",
+                                                                               "name": "Corp. Gateway",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.2.0/24",
+                                                                               "name": "Corp. Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "eth3",
+                                                                               "name": "Interface Name",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.255.255.0/24",
+                                                                               "name": "Local Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": 0,
+                                                                               "name": "Local Network Area",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "integer",
+                                                                               "default-value": 3000,
+                                                                               "name": "Vlan ID",
+                                                                               "mandatory": "true"
+                                                                       }
+                                                               ],
+                                                               "name": "PE2",
+                                                               "mandatory": "false"
+                                                       },
+                                                       {
+                                                               "parameter": [
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.3.1",
+                                                                               "name": "Corp. Gateway",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.0.3.0/24",
+                                                                               "name": "Corp. Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "eth3",
+                                                                               "name": "Interface Name",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": "10.255.255.0/24",
+                                                                               "name": "Local Network",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "string",
+                                                                               "default-value": 0,
+                                                                               "name": "Local Network Area",
+                                                                               "mandatory": "true"
+                                                                       },
+                                                                       {
+                                                                               "data-type": "integer",
+                                                                               "default-value": 3000,
+                                                                               "name": "Vlan ID",
+                                                                               "mandatory": "true"
+                                                                       }
+                                                               ],
+                                                               "name": "PE3",
+                                                               "mandatory": "false"
+                                                       }
+                                               ]
+                                       }
+                               ],
+                               "description": "6wind turborouter only",
+                               "vendor": "6Wind",
+                               "name": "tr_juju_nsd",
+                               "version": 1,
+                               "short-name": "tr_juju_nsd",
+                               "vld": [
+                                       {
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b14795b0-d34c-11e5-8e51-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "turborouter_vnfd/cp0"
+                                                       }
+                                               ],
+                                               "id": "9d8a7b4a-d50f-11e5-80c8-6cb3113b406f",
+                                               "description": "Link from TR to ELAN",
+                                               "vendor": "RIFT.io",
+                                               "name": "Link1",
+                                               "version": 1,
+                                               "short-name": "Link1",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "vnf-configuration": {
+                                                       "config-type": "juju",
+                                                       "initial-config-primitive": [
+                                                               {
+                                                                       "parameter": [
+                                                                               {
+                                                                                       "value": "6windos",
+                                                                                       "name": "pass"
+                                                                               },
+                                                                               {
+                                                                                       "value": "root",
+                                                                                       "name": "user"
+                                                                               },
+                                                                               {
+                                                                                       "value": "<rw_mgmt_ip>",
+                                                                                       "name": "vpe-router"
+                                                                               }
+                                                                       ],
+                                                                       "seq": 1,
+                                                                       "name": "config"
+                                                               },
+                                                               {
+                                                                       "parameter": [
+                                                                               {
+                                                                                       "value": "10.10.10.2/30",
+                                                                                       "name": "cidr"
+                                                                               },
+                                                                               {
+                                                                                       "value": "eth1",
+                                                                                       "name": "iface-name"
+                                                                               }
+                                                                       ],
+                                                                       "seq": 2,
+                                                                       "name": "configure-interface"
+                                                               }
+                                                       ],
+                                                       "juju": {
+                                                               "charm": "vpe-router"
+                                                       },
+                                                       "input-params": {
+                                                               "config-priority": 0,
+                                                               "config-delay": 0
+                                                       }
+                                               },
+                                               "vnfd-id-ref": "b14795b0-d34c-11e5-8e51-6cb3113b406f",
+                                               "member-vnf-index": 1
+                                       }
+                               ],
+                               "meta": {
+                                       "instance-ref-count": 4
+                               }
+                       },
+                       {
+                               "id": "b53910e0-d34c-11e5-b34f-6cb3113b406f",
+                               "description": "NS Vrouter-only",
+                               "vendor": "RIFT.io",
+                               "name": "vrouter_nsd",
+                               "version": 1,
+                               "short-name": "vrouter_nsd",
+                               "vld": [
+                                       {
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b3ebcd0e-d34c-11e5-b72f-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "vrouter_vnfd/cp0"
+                                                       }
+                                               ],
+                                               "id": "b5505bb0-d34c-11e5-b34f-6cb3113b406f",
+                                               "description": "Link from Vrouter to ELAN",
+                                               "vendor": "RIFT.io",
+                                               "name": "Link1",
+                                               "version": 1,
+                                               "short-name": "Link1",
+                                               "type": "ELAN"
+                                       },
+                                       {
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "b3ebcd0e-d34c-11e5-b72f-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "vrouter_vnfd/cp1"
+                                                       }
+                                               ],
+                                               "id": "b5508324-d34c-11e5-b34f-6cb3113b406f",
+                                               "description": "Link from Vrouter to ELAN",
+                                               "vendor": "RIFT.io",
+                                               "name": "Link2",
+                                               "version": 1,
+                                               "short-name": "Link2",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "vnfd-id-ref": "b3ebcd0e-d34c-11e5-b72f-6cb3113b406f",
+                                               "member-vnf-index": 1
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-2",
+               "name": "RIFT.ware™ VNF Descriptors Catalog",
+               "short-name": "rift.ware-vnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "vnfd",
+               "meta": {
+                       "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_3\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <g> <path d=\"M58.852,62.447l-4.662-1.033c-0.047-3.138-0.719-6.168-1.996-9.007l3.606-2.92c0.858-0.695,0.99-1.954,0.296-2.813 l-4.521-5.584c-0.334-0.413-0.818-0.675-1.346-0.731c-0.525-0.057-1.056,0.102-1.468,0.435L45.25,43.64v0 c-2.486-1.907-5.277-3.259-8.297-4.019v-4.458c0-1.104-0.896-2-2-2H27.77c-1.104,0-2,0.896-2,2v4.461 c-3.08,0.777-5.922,2.171-8.447,4.144l-3.545-2.82c-0.415-0.33-0.94-0.479-1.472-0.422c-0.527,0.06-1.009,0.327-1.339,0.743 l-4.472,5.623c-0.688,0.864-0.544,2.123,0.32,2.81l3.642,2.896v0c-1.25,2.848-1.895,5.88-1.916,9.011l-4.666,1.078 c-1.076,0.249-1.747,1.322-1.499,2.398l1.616,7.001c0.249,1.077,1.325,1.747,2.399,1.499l4.813-1.111v0 c1.429,2.681,3.344,5.017,5.691,6.943l-2.17,4.55c-0.476,0.997-0.054,2.19,0.943,2.666l6.484,3.094 c0.271,0.129,0.566,0.195,0.861,0.195c0.226,0,0.451-0.038,0.668-0.115c0.5-0.177,0.909-0.545,1.138-1.024l2.198-4.611 c2.923,0.563,5.966,0.554,8.879-0.033l2.236,4.585c0.484,0.994,1.685,1.403,2.675,0.921l6.456-3.148 c0.992-0.484,1.405-1.682,0.921-2.674l-2.206-4.524c2.335-1.946,4.231-4.301,5.639-6.999l4.812,1.067 c1.076,0.237,2.146-0.441,2.385-1.52l1.556-7.014c0.115-0.518,0.02-1.06-0.266-1.508C59.82,62.878,59.369,62.562,58.852,62.447z M40.18,61.761c0,4.859-3.953,8.812-8.813,8.812c-4.858,0-8.811-3.953-8.811-8.812s3.952-8.812,8.811-8.812 C36.227,52.949,40.18,56.902,40.18,61.761z\"/> <path d=\"M64.268,45.324c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.826,0.353,3.736,0.345,5.551-0.021l1.07,2.195 c0.484,0.992,1.682,1.405,2.675,0.921l2.691-1.313c0.477-0.233,0.842-0.646,1.015-1.147c0.172-0.501,0.139-1.051-0.095-1.528 l-1.052-2.155c1.458-1.214,2.645-2.686,3.527-4.377l2.278,0.504c1.075,0.238,2.146-0.442,2.386-1.52l0.647-2.923 c0.238-1.078-0.442-2.146-1.521-2.385l-2.184-0.484c-0.028-1.962-0.449-3.857-1.248-5.632l1.673-1.355 c0.412-0.334,0.675-0.818,0.73-1.345s-0.102-1.056-0.436-1.468l-1.884-2.327c-0.697-0.859-1.957-0.99-2.813-0.295l-1.614,1.307 c-1.554-1.193-3.299-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.04 c-1.927,0.486-3.703,1.358-5.28,2.592l-1.634-1.298c-0.862-0.687-2.12-0.543-2.81,0.32l-1.864,2.344 c-0.33,0.416-0.481,0.945-0.422,1.472c0.061,0.527,0.327,1.009,0.743,1.339l1.69,1.345c-0.78,1.779-1.184,3.676-1.197,5.636 l-2.189,0.505c-0.517,0.119-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51l0.675,2.918 c0.249,1.076,1.323,1.747,2.398,1.498l2.28-0.527c0.892,1.676,2.089,3.137,3.559,4.343l-1.035,2.17 c-0.228,0.479-0.257,1.028-0.08,1.528c0.178,0.5,0.546,0.91,1.024,1.138l2.703,1.289C63.686,45.261,63.979,45.324,64.268,45.324z M64.334,27.961c0-3.039,2.473-5.51,5.512-5.51c3.038,0,5.51,2.472,5.51,5.51c0,3.039-2.472,5.511-5.51,5.511 C66.807,33.472,64.334,31,64.334,27.961z\"/> <path d=\"M96.107,66.441l-2.182-0.484c-0.028-1.961-0.449-3.856-1.25-5.632l1.675-1.355c0.412-0.334,0.675-0.818,0.73-1.346 c0.056-0.527-0.102-1.056-0.436-1.468l-1.885-2.327c-0.695-0.859-1.956-0.99-2.813-0.295l-1.614,1.307 c-1.555-1.193-3.3-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.041 c-1.929,0.486-3.706,1.358-5.282,2.592l-0.001,0l-1.631-1.298c-0.415-0.331-0.938-0.482-1.472-0.422 c-0.527,0.06-1.009,0.327-1.339,0.742l-1.863,2.343c-0.688,0.865-0.544,2.123,0.32,2.811l1.691,1.345 c-0.782,1.784-1.186,3.68-1.199,5.636l-2.188,0.505c-0.517,0.12-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51 l0.675,2.918c0.249,1.076,1.327,1.744,2.397,1.498l2.281-0.526c0.893,1.677,2.09,3.138,3.558,4.343h0.001l-1.035,2.168 c-0.229,0.479-0.258,1.029-0.081,1.529c0.178,0.5,0.546,0.909,1.024,1.138l2.702,1.289c0.278,0.132,0.571,0.195,0.86,0.195 c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.828,0.353,3.739,0.347,5.552-0.021l1.071,2.194 c0.484,0.992,1.682,1.405,2.675,0.921l2.69-1.312c0.477-0.233,0.842-0.645,1.014-1.147c0.173-0.501,0.14-1.051-0.093-1.528 l-1.052-2.155c1.459-1.215,2.645-2.688,3.525-4.377l2.278,0.505c0.52,0.116,1.061,0.02,1.508-0.266 c0.447-0.285,0.763-0.736,0.878-1.254l0.647-2.923C97.866,67.748,97.186,66.681,96.107,66.441z M85.162,66.174 c0,3.039-2.471,5.511-5.508,5.511c-3.039,0-5.512-2.472-5.512-5.511c0-3.039,2.473-5.511,5.512-5.511 C82.691,60.664,85.162,63.136,85.162,66.174z\"/> </g> </svg> "
+               },
+               "descriptors": [
+                       {
+                               "id": "b14795b0-d34c-11e5-8e51-6cb3113b406f",
+                               "description": "This is a 6Wind TurboRouter VNF",
+                               "vendor": "6Wind",
+                               "name": "turborouter_vnfd",
+                               "version": 1,
+                               "short-name": "turborouter_vnfd",
+                               "vdu": [
+                                       {
+                                               "id": "b1481ec2-d34c-11e5-8e51-6cb3113b406f",
+                                               "count": 1,
+                                               "name": "iovdu",
+                                               "vm-flavor": {
+                                                       "memory-mb": 4096,
+                                                       "vcpu-count": 2,
+                                                       "storage-gb": 40
+                                               },
+                                               "image": "turbo-router-riftio-5.img.qcow2",
+                                               "external-interface": [
+                                                       {
+                                                               "vnfd-connection-point-ref": "turborouter_vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               },
+                                                               "name": "eth1"
+                                                       },
+                                                       {
+                                                               "vnfd-connection-point-ref": "turborouter_vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               },
+                                                               "name": "eth2"
+                                                       }
+                                               ],
+                                               "cloud-init": "#cloud-config\n"
+                                       }
+                               ],
+                               "mgmt-interface": {
+                                       "vdu-id": "b1481ec2-d34c-11e5-8e51-6cb3113b406f",
+                                       "port": 80
+                               },
+                               "connection-point": [
+                                       {
+                                               "type": "VPORT",
+                                               "name": "turborouter_vnfd/cp0"
+                                       },
+                                       {
+                                               "type": "VPORT",
+                                               "name": "turborouter_vnfd/cp1"
+                                       }
+                               ],
+                               "monitoring-param": [
+                                       {
+                                               "id": 1,
+                                               "units": "KB",
+                                               "description": "Memory usage of turborouter",
+                                               "name": "Total memory",
+                                               "group-tag": "Group1",
+                                               "widget-type": "COUNTER",
+                                               "http-endpoint-ref": "rest/info",
+                                               "value-type": "INT",
+                                               "json-query-method": "JSONPATH",
+                                               "json-query-params": {
+                                                       "json-path": "$.system.mem_total"
+                                               }
+                                       }
+                               ],
+                               "http-endpoint": [
+                                       {
+                                               "username": "root",
+                                               "polling_interval_secs": 3,
+                                               "password": "6windos",
+                                               "path": "rest/info",
+                                               "port": 80
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "b152c2e6-d34c-11e5-8463-6cb3113b406f",
+                               "description": "This is a Clearwater IMS VNF",
+                               "vendor": "Clearwater",
+                               "name": "cwims_vnfd",
+                               "version": 1,
+                               "short-name": "cwims_vnfd",
+                               "vdu": [
+                                       {
+                                               "id": "b1530f76-d34c-11e5-8463-6cb3113b406f",
+                                               "count": 1,
+                                               "name": "iovdu",
+                                               "vm-flavor": {
+                                                       "memory-mb": 4096,
+                                                       "vcpu-count": 2,
+                                                       "storage-gb": 40
+                                               },
+                                               "image": "cw-aio.qcow2",
+                                               "external-interface": [
+                                                       {
+                                                               "vnfd-connection-point-ref": "cwims_vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               },
+                                                               "name": "eth1"
+                                                       }
+                                               ],
+                                               "cloud-init": "#cloud-config\n"
+                                       }
+                               ],
+                               "mgmt-interface": {
+                                       "vdu-id": "b1530f76-d34c-11e5-8463-6cb3113b406f",
+                                       "dashboard-params": {
+                                               "path": "/",
+                                               "port": 80
+                                       },
+                                       "port": 80
+                               },
+                               "connection-point": [
+                                       {
+                                               "type": "VPORT",
+                                               "name": "cwims_vnfd/cp0"
+                                       }
+                               ],
+                               "http-endpoint": [
+                                       {
+                                               "username": "vyatta",
+                                               "password": "vyatta",
+                                               "path": "rest/app/gui/dashboard/sysinfo",
+                                               "polling_interval_secs": 2
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "b3ebcd0e-d34c-11e5-b72f-6cb3113b406f",
+                               "description": "This is a Brocade vRouter VNF",
+                               "vendor": "Brocade",
+                               "name": "vrouter_vnfd",
+                               "version": 1,
+                               "short-name": "vrouter_vnfd",
+                               "vdu": [
+                                       {
+                                               "id": "b3ecbd5e-d34c-11e5-b72f-6cb3113b406f",
+                                               "count": 1,
+                                               "name": "iovdu",
+                                               "vm-flavor": {
+                                                       "memory-mb": 8192,
+                                                       "vcpu-count": 4,
+                                                       "storage-gb": 40
+                                               },
+                                               "image": "vyatta-7.qcow2",
+                                               "external-interface": [
+                                                       {
+                                                               "vnfd-connection-point-ref": "vrouter_vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               },
+                                                               "name": "eth0"
+                                                       },
+                                                       {
+                                                               "vnfd-connection-point-ref": "vrouter_vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               },
+                                                               "name": "eth1"
+                                                       }
+                                               ],
+                                               "cloud-init": "#cloud-config\n"
+                                       }
+                               ],
+                               "mgmt-interface": {
+                                       "vdu-id": "b3ecbd5e-d34c-11e5-b72f-6cb3113b406f",
+                                       "dashboard-params": {
+                                               "path": "/",
+                                               "port": 80
+                                       },
+                                       "port": 80
+                               },
+                               "connection-point": [
+                                       {
+                                               "type": "VPORT",
+                                               "name": "vrouter_vnfd/cp0"
+                                       },
+                                       {
+                                               "type": "VPORT",
+                                               "name": "vrouter_vnfd/cp1"
+                                       }
+                               ],
+                               "monitoring-param": [
+                                       {
+                                               "id": 1,
+                                               "units": "KB",
+                                               "description": "Memory usage of vrouter",
+                                               "name": "Total memory",
+                                               "group-tag": "Group1",
+                                               "widget-type": "COUNTER",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/sysinfo",
+                                               "value-type": "INT",
+                                               "json-query-method": "JSONPATH",
+                                               "json-query-params": {
+                                                       "json-path": "$.system.mem_total"
+                                               }
+                                       },
+                                       {
+                                               "id": 2,
+                                               "units": "%",
+                                               "description": "Memory utilization of vrouter",
+                                               "name": "Memory utilization",
+                                               "numeric-constraints": {
+                                                       "max-value": 100,
+                                                       "min-value": 0
+                                               },
+                                               "group-tag": "Group1",
+                                               "widget-type": "GAUGE",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/sysinfo",
+                                               "value-type": "DECIMAL",
+                                               "json-query-method": "JSONPATH",
+                                               "json-query-params": {
+                                                       "json-path": "$.system.mem"
+                                               }
+                                       },
+                                       {
+                                               "id": 3,
+                                               "units": "%",
+                                               "description": "CPU utilization (all) of vrouter",
+                                               "name": "CPU utilization",
+                                               "numeric-constraints": {
+                                                       "max-value": 100,
+                                                       "min-value": 0
+                                               },
+                                               "group-tag": "Group1",
+                                               "widget-type": "GAUGE",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/sysinfo",
+                                               "value-type": "DECIMAL",
+                                               "json-query-method": "JSONPATH",
+                                               "json-query-params": {
+                                                       "json-path": "$.system.cpu[0].usage"
+                                               }
+                                       },
+                                       {
+                                               "id": 4,
+                                               "units": "bytes",
+                                               "description": "Incoming bytes at interface",
+                                               "name": "Interface[dp0s4] Rx",
+                                               "group-tag": "Group2",
+                                               "widget-type": "COUNTER",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+                                               "value-type": "INT",
+                                               "json-query-method": "OBJECTPATH",
+                                               "json-query-params": {
+                                                       "object-path": "$..interfaces[@.name is 'dp0s4']['in']"
+                                               }
+                                       },
+                                       {
+                                               "id": 5,
+                                               "units": "bytes",
+                                               "description": "Outgoing bytes at interface",
+                                               "name": "Interface[dp0s4] Tx",
+                                               "group-tag": "Group2",
+                                               "widget-type": "COUNTER",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+                                               "value-type": "INT",
+                                               "json-query-method": "OBJECTPATH",
+                                               "json-query-params": {
+                                                       "object-path": "$..interfaces[@.name is 'dp0s4']['out']"
+                                               }
+                                       },
+                                       {
+                                               "id": 6,
+                                               "units": "bytes",
+                                               "description": "Incoming bytes at interface",
+                                               "name": "Interface[dp0s5] Rx",
+                                               "group-tag": "Group3",
+                                               "widget-type": "COUNTER",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+                                               "value-type": "INT",
+                                               "json-query-method": "OBJECTPATH",
+                                               "json-query-params": {
+                                                       "object-path": "$..interfaces[@.name is 'dp0s5']['in']"
+                                               }
+                                       },
+                                       {
+                                               "id": 7,
+                                               "units": "bytes",
+                                               "description": "Outgoing bytes at interface",
+                                               "name": "Interface[dp0s5] Tx",
+                                               "group-tag": "Group3",
+                                               "widget-type": "COUNTER",
+                                               "http-endpoint-ref": "rest/app/gui/dashboard/interfaces",
+                                               "value-type": "INT",
+                                               "json-query-method": "OBJECTPATH",
+                                               "json-query-params": {
+                                                       "object-path": "$..interfaces[@.name is 'dp0s5']['out']"
+                                               }
+                                       }
+                               ],
+                               "http-endpoint": [
+                                       {
+                                               "username": "vyatta",
+                                               "polling_interval_secs": 3,
+                                               "password": "vyatta",
+                                               "path": "rest/app/gui/dashboard/interfaces",
+                                               "port": 80
+                                       },
+                                       {
+                                               "username": "vyatta",
+                                               "polling_interval_secs": 3,
+                                               "password": "vyatta",
+                                               "path": "rest/app/gui/dashboard/sysinfo",
+                                               "port": 80
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-3",
+               "name": "RIFT.ware™ PNF Descriptors Catalog",
+               "short-name": "rift.ware-pnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "pnfd",
+               "meta": {
+                       "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_4\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <path d=\"M86.334,47.444V35.759H13.666v11.686h3.561v5.111h-3.561v11.686h72.668V52.556h-4.108v-5.111H86.334z M26.628,59.454h-5.051 v-4.941h5.051V59.454z M26.628,52.404h-5.051v-4.941h5.051V52.404z M26.628,45.486h-5.051v-4.941h5.051V45.486z M34.094,59.454 h-5.051v-4.941h5.051V59.454z M34.094,52.404h-5.051v-4.941h5.051V52.404z M34.094,45.486h-5.051v-4.941h5.051V45.486z M41.452,59.454h-5.051v-4.941h5.051V59.454z M41.452,52.404h-5.051v-4.941h5.051V52.404z M41.452,45.486h-5.051v-4.941h5.051 V45.486z M48.733,59.454h-5.051v-4.941h5.051V59.454z M48.733,52.404h-5.051v-4.941h5.051V52.404z M48.733,45.486h-5.051v-4.941 h5.051V45.486z M56.2,59.454h-5.051v-4.941H56.2V59.454z M56.2,52.404h-5.051v-4.941H56.2V52.404z M56.2,45.486h-5.051v-4.941H56.2 V45.486z M63.558,59.454h-5.05v-4.941h5.05V59.454z M63.558,52.404h-5.05v-4.941h5.05V52.404z M63.558,45.486h-5.05v-4.941h5.05 V45.486z M74.858,59.312h-6.521v-3.013h6.521V59.312z M71.572,50.854c-2.875,0-5.204-2.33-5.204-5.203s2.329-5.203,5.204-5.203 s5.204,2.33,5.204,5.203S74.446,50.854,71.572,50.854z M74.858,45.618c0,1.801-1.46,3.261-3.261,3.261 c-1.8,0-3.261-1.46-3.261-3.261s1.46-3.26,3.261-3.26C73.398,42.358,74.858,43.817,74.858,45.618z\"/> </svg>"
+               },
+               "descriptors": []
+       }
+]
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/assets/onvelocity-color-theme.json b/skyquake/plugins/composer/src/src/assets/onvelocity-color-theme.json
new file mode 100644 (file)
index 0000000..f4f488f
--- /dev/null
@@ -0,0 +1,33 @@
+{
+       "nsd": {
+               "primary": "#2AA198",
+               "secondary": "#19615C"
+       },
+       "vld": {
+               "primary": "#CB4B16",
+               "secondary": "#8B330F"
+       },
+       "vdu": {
+               "primary": "#b58900",
+               "secondary": "#755900"
+       },
+       "vnfd": {
+               "primary": "#268BD2",
+               "secondary": "#0F3752"
+       },
+       "constituent-vnfd": {
+               "primary": "#268BD2",
+               "secondary": "#0F3752"
+       },
+       "vnffgd": {
+               "primary": "#859900",
+               "secondary": "#4E5900"
+       },
+       "common": {
+               "primary": "black",
+               "secondary": "white",
+               "background": "white",
+               "foreground": "black"
+       }
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/assets/ping-pong-catalog.json b/skyquake/plugins/composer/src/src/assets/ping-pong-catalog.json
new file mode 100644 (file)
index 0000000..7ae2e35
--- /dev/null
@@ -0,0 +1,767 @@
+[
+       {
+               "id": "GUID-1",
+               "name": "RIFT.ware™ NS Descriptors Catalog",
+               "short-name": "rift.ware-nsd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "nsd",
+               "descriptors": [
+                       {
+                               "id": "ba1dfbcc-626b-11e5-998d-6cb3113b406f",
+                               "name": "ping-pong-nsd",
+                               "short-name": "ping-pong-nsd",
+                               "vendor": "RIFT.io",
+                               "description": "Toy NS",
+                               "version": "1.0",
+                               "logo": "data:image/png;base64,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",
+                               "connection-point": [
+                                       {
+                                               "name": "ping-pong-nsd/cp0"
+                                       },
+                                       {
+                                               "name": "ping-pong-nsd/cp1"
+                                       }
+                               ],
+                               "vld": [
+                                       {
+                                               "id": "ba1c03a8-626b-11e5-998d-6cb3113b406f",
+                                               "name": "ping-pong-vld",
+                                               "short-name": "ping-pong-vld",
+                                               "vendor": "RIFT.io",
+                                               "description": "Toy VL",
+                                               "version": "1.0",
+                                               "type": "ELAN",
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1"
+                                                       },
+                                                       {
+                                                               "member-vnf-index-ref": 2,
+                                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1"
+                                                       }
+                                               ],
+                                               "provider-network": {
+                                                       "name": "physnet1",
+                                                       "overlay-type": "VLAN"
+                                               }
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "member-vnf-index": 1,
+                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f"
+                                       },
+                                       {
+                                               "member-vnf-index": 2,
+                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f"
+                                       }
+                               ],
+                               "vnffgd": [
+                                       {
+                                               "id": "e733efb1-6d52-4d97-839e-90c063239d6a",
+                                               "name": "vnffgd-2",
+                                               "short-name": "FG-1",
+                                               "vendor": "",
+                                               "description": "",
+                                               "version": "",
+                                               "rsp": [
+                                                       {
+                                                               "id": "d671ee1d-0076-40a4-b83d-ef5abf000322",
+                                                               "name": "rsp-1"
+                                                       }
+                                               ],
+                                               "classifier": [
+                                                       {
+                                                               "id": "387b9233-7fc3-4e69-9172-597d630a7345",
+                                                               "name": "classifier-2",
+                                                               "rsp-id-ref": "d671ee1d-0076-40a4-b83d-ef5abf000322",
+                                                               "member-vnf-index-ref": "",
+                                                               "vnfd-id-ref": "",
+                                                               "vnfd-connection-point-ref": "",
+                                                               "match-attributes": [
+                                                                       {
+                                                                               "id": "5d8ed8f9-f6b7-4edb-938a-7b14748c3e52",
+                                                                               "ip-proto": "111",
+                                                                               "source-ip-address": "222",
+                                                                               "destination-ip-address": "333",
+                                                                               "source-port": "444",
+                                                                               "destination-port": "555"
+                                                                       }
+                                                               ]
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "test1-626b-11e5-998d-6cb3113b406f",
+                               "name": "TEST ping-pong-nsd",
+                               "short-name": "test-ping-pong-nsd",
+                               "vendor": "RIFT.io",
+                               "description": "TEST NS",
+                               "version": "1.0",
+                               "meta": "{\"instance-ref-count\": 4}",
+                               "connection-point": [
+                                       {
+                                               "name": "ping-pong-nsd/cp0"
+                                       },
+                                       {
+                                               "name": "ping-pong-nsd/cp1"
+                                       }
+                               ],
+                               "vld": [
+                                       {
+                                               "id": "test1-ba1c03a8-626b-11e5-998d-6cb3113b406f",
+                                               "name": "test1-ping-pong-vld",
+                                               "short-name": "test1-ping-pong-vld",
+                                               "vendor": "RIFT.io",
+                                               "description": "test1 VL",
+                                               "version": "1.0",
+                                               "type": "ELAN",
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1"
+                                                       },
+                                                       {
+                                                               "member-vnf-index-ref": 2,
+                                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1"
+                                                       }
+                                               ],
+                                               "provider-network": {
+                                                       "name": "physnet1",
+                                                       "overlay-type": "VLAN"
+                                               }
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "member-vnf-index": 1,
+                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f"
+                                       },
+                                       {
+                                               "member-vnf-index": 2,
+                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f"
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-2",
+               "name": "RIFT.ware™ VNF Descriptors Catalog",
+               "short-name": "rift.ware-vnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "vnfd",
+               "descriptors": [
+                       {
+                               "id": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                               "name": "ping-vnfd",
+                               "short-name": "ping-vnfd",
+                               "vendor": "RIFT.io",
+                               "description": "This is an example RIFT.ware VNF",
+                               "version": "1.0",
+                               "logo": "data:image/png;base64,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",
+                               "internal-vld": [
+                                       {
+                                               "id": "ba1478fe-626b-11e5-998d-6cb3113b406f",
+                                               "name": "fabric",
+                                               "short-name": "fabric",
+                                               "description": "Virtual link for internal fabric",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "connection-point": [
+                                       {
+                                               "name": "ping-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "ping-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "ba14a504-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "ba153744-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "ba153744-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                               "name": "pong-vnfd",
+                               "short-name": "pong-vnfd",
+                               "vendor": "RIFT.io",
+                               "description": "This is an example RIFT.ware VNF",
+                               "version": "1.0",
+                               "logo": "data:image/png;base64,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",
+                               "internal-vld": [
+                                       {
+                                               "id": "ba195068-626b-11e5-998d-6cb3113b406f",
+                                               "name": "fabric",
+                                               "short-name": "fabric",
+                                               "description": "Virtual link for internal fabric",
+                                               "type": "ELAN",
+                                               "internal-connection-point-ref": [
+                                                       "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                       "ba198696-626b-11e5-998d-6cb3113b406f"
+                                               ]
+                                       }
+                               ],
+                               "connection-point": [
+                                       {
+                                               "name": "pong-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "pong-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "1-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "ba198696-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "ba198696-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       },
+                                       {
+                                               "id": "2-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "21-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "22-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "21-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "22-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "c55e8e6d-ed13-465f-809d-838878c70d1d",
+                               "name": "vnfd-2",
+                               "short-name": "SF Aware",
+                               "vendor": "",
+                               "logo": "",
+                               "description": "A simple VNF descriptor w/ one VDU",
+                               "version": "0.1.0",
+                               "service-function-chain": "SF",
+                               "service-function-type": "",
+                               "meta": "{\"containerPositionMap\":{}}",
+                               "mgmt-interface": {
+                                       "port": "",
+                                       "dashboard-params": {
+                                               "path": "",
+                                               "https": "",
+                                               "port": ""
+                                       }
+                               },
+                               "connection-point": [
+                                       {
+                                               "name": "ping-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "ping-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "7ea4bb66-82ff-453c-a0db-96099a797d25",
+                                               "name": "vdu-2",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "009a6284-523b-4630-a050-dcf4937c0658",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "99d5fd31-de1f-457d-ac39-80dfb4c33b2f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "776c0ec7-ce00-465d-a837-667975353183",
+                               "name": "vnfd-3",
+                               "short-name": "Classifier",
+                               "vendor": "",
+                               "logo": "",
+                               "description": "A simple VNF descriptor w/ one VDU",
+                               "version": "0.1.0",
+                               "service-function-chain": "CLASSIFIER",
+                               "service-function-type": "",
+                               "meta": "{\"containerPositionMap\":{}}",
+                               "mgmt-interface": {
+                                       "port": "",
+                                       "dashboard-params": {
+                                               "path": "",
+                                               "https": "",
+                                               "port": ""
+                                       }
+                               },
+                               "connection-point": [
+                                       {
+                                               "name": "ping-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "ping-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "7f9d96e7-37b5-46d2-91b1-8d670db72d0b",
+                                               "name": "vdu-3",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "38ef6b13-f4cc-4153-a662-dc7b804ef202",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "5c07545e-94d0-4551-a704-a8e47ab28fa5",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-3",
+               "name": "RIFT.ware™ PNF Descriptors Catalog",
+               "short-name": "rift.ware-pnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "pnfd",
+               "descriptors": []
+       }
+]
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/assets/ping-vrouter-pong-catalog.json b/skyquake/plugins/composer/src/src/assets/ping-vrouter-pong-catalog.json
new file mode 100644 (file)
index 0000000..136a571
--- /dev/null
@@ -0,0 +1,504 @@
+[
+  {
+    "id": "GUID-1",
+    "name": "RIFT.ware™ NS Descriptors Catalog",
+    "short-name": "rift.ware-nsd-cat",
+    "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+    "vendor": "RIFT.io",
+    "version": "",
+    "created-on": "",
+    "type": "nsd",
+    "descriptors": [
+      {
+        "description": "Toy NS Ping-Vrouter-Pong",
+        "constituent-vnfd": [
+          {
+            "member-vnf-index": 1,
+            "vnfd-id-ref": "7cae6ff6-9263-11e5-b7df-001b21b98a89"
+          },
+          {
+            "member-vnf-index": 2,
+            "vnfd-id-ref": "a4dea522-9263-11e5-ad06-001b21b98a89"
+          },
+          {
+            "member-vnf-index": 3,
+            "vnfd-id-ref": "7cb0375a-9263-11e5-b7df-001b21b98a89"
+          }
+        ],
+        "version": 1,
+        "vld": [
+          {
+            "description": "Link from ping to vrouter",
+            "type": "ELAN",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 1,
+                "vnfd-connection-point-ref": "ping_vnfd/cp0",
+                "vnfd-id-ref": "7cae6ff6-9263-11e5-b7df-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp0",
+                "vnfd-id-ref": "a4dea522-9263-11e5-ad06-001b21b98a89"
+              }
+            ],
+            "version": 1,
+            "vendor": "RIFT.io",
+            "name": "Link1",
+            "short-name": "Link1",
+            "id": "23afa0c8-92d1-11e5-9a9f-001b21b98a89"
+          },
+          {
+            "description": "Link from vrouter to pong",
+            "type": "ELAN",
+            "vnfd-connection-point-ref": [
+              {
+                "member-vnf-index-ref": 2,
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp1",
+                "vnfd-id-ref": "a4dea522-9263-11e5-ad06-001b21b98a89"
+              },
+              {
+                "member-vnf-index-ref": 3,
+                "vnfd-connection-point-ref": "pong_vnfd/cp0",
+                "vnfd-id-ref": "7cb0375a-9263-11e5-b7df-001b21b98a89"
+              }
+            ],
+            "version": 1,
+            "vendor": "RIFT.io",
+            "name": "Link2",
+            "short-name": "Link2",
+            "id": "23afe542-92d1-11e5-9a9f-001b21b98a89"
+          }
+        ],
+        "vendor": "RIFT.io",
+        "name": "ping_vrouter_pong_nsd",
+        "short-name": "ping_vrouter_pong_nsd",
+        "id": "23a28e4c-92d1-11e5-9a9f-001b21b98a89"
+      }
+    ]
+  },
+  {
+    "id": "GUID-2",
+    "name": "RIFT.ware™ VNF Descriptors Catalog",
+    "short-name": "rift.ware-vnfd-cat",
+    "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+    "vendor": "RIFT.io",
+    "version": "",
+    "created-on": "",
+    "type": "vnfd",
+    "descriptors": [
+      {
+        "vdu": [
+          {
+            "image": "Fedora-x86_64-20-20131211.1-sda-ping.qcow2",
+            "host-epa": {
+              "cpu-socket-count": "PREFER_TWO",
+              "cpu-vendor": "PREFER_INTEL",
+              "cpu-feature": [
+                "PREFER_AES",
+                "PREFER_CAT"
+              ],
+              "cpu-arch": "PREFER_X86_64",
+              "cpu-model": "PREFER_SANDYBRIDGE"
+            },
+            "hypervisor-epa": {
+              "type": "PREFER_KVM"
+            },
+            "external-interface": [
+              {
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "name": "eth0",
+                "vnfd-connection-point-ref": "ping_vnfd/cp0"
+              }
+            ],
+            "count": 2,
+            "internal-interface": [
+              {
+                "vdu-internal-connection-point-ref": "7cafe53e-9263-11e5-b7df-001b21b98a89",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "name": "eth0"
+              }
+            ],
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nruncmd:\n  - [ systemctl, daemon-reload ]\n  - [ systemctl, enable, ping.service ]\n  - [ systemctl, start, --no-block, ping.service ]\n  - [ ifup, eth1 ]\n  - [ ifup, eth2 ]\n",
+            "internal-connection-point": [
+              {
+                "type": "VPORT",
+                "id": "7cafe53e-9263-11e5-b7df-001b21b98a89"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "vcpu-count": 2,
+              "storage-gb": 40
+            },
+            "guest-epa": {
+              "mempage-size": "PREFER_LARGE",
+              "cpu-thread-pinning-policy": "AVOID",
+              "trusted-execution": "true",
+              "numa-node-policy": {
+                "node": [
+                  {
+                    "vcpu": [
+                      0,
+                      1
+                    ],
+                    "memory-mb": 8192,
+                    "id": 0
+                  },
+                  {
+                    "vcpu": [
+                      2,
+                      3
+                    ],
+                    "memory-mb": 8192,
+                    "id": 1
+                  }
+                ],
+                "node-cnt": 2,
+                "mem-policy": "PREFERRED"
+              },
+              "cpu-pinning-policy": "DEDICATED"
+            },
+            "name": "iovdu",
+            "vswitch-epa": {
+              "ovs-acceleration": "DISABLED",
+              "ovs-offload": "DISABLED"
+            },
+            "id": "7caf476e-9263-11e5-b7df-001b21b98a89"
+          }
+        ],
+        "description": "This is an example RIFT.ware VNF",
+        "connection-point": [
+          {
+            "type": "VPORT",
+            "name": "ping_vnfd/cp0"
+          }
+        ],
+        "monitoring-param": [
+          {
+            "units": "packets",
+            "description": "no of ping requests",
+            "current-value": 0,
+            "min-value": 0,
+            "path": "api/v1/ping/stats",
+            "id": 1,
+            "widget-type": "COUNTER",
+            "name": "ping-request-tx-count",
+            "max-value": 4292967295,
+            "group-tag": "Group1"
+          },
+          {
+            "units": "packets",
+            "description": "no of ping responses",
+            "current-value": 0,
+            "min-value": 0,
+            "path": "api/v1/ping/stats",
+            "id": 2,
+            "widget-type": "COUNTER",
+            "name": "ping-response-rx-count",
+            "max-value": 4292967295,
+            "group-tag": "Group1"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "7caf476e-9263-11e5-b7df-001b21b98a89",
+          "port": 18888
+        },
+        "version": 1,
+        "internal-vld": [
+          {
+            "description": "Virtual link for internal fabric",
+            "type": "ELAN",
+            "internal-connection-point-ref": [
+              "7cafe53e-9263-11e5-b7df-001b21b98a89"
+            ],
+            "name": "fabric",
+            "short-name": "fabric",
+            "id": "7caead0e-9263-11e5-b7df-001b21b98a89"
+          }
+        ],
+        "vendor": "RIFT.io",
+        "name": "ping_vnfd",
+        "short-name": "ping_vnfd",
+        "id": "7cae6ff6-9263-11e5-b7df-001b21b98a89"
+      },
+      {
+        "vdu": [
+          {
+            "image": "Fedora-x86_64-20-20131211.1-sda-pong.qcow2",
+            "host-epa": {
+              "cpu-socket-count": "PREFER_TWO",
+              "cpu-vendor": "PREFER_INTEL",
+              "cpu-feature": [
+                "PREFER_AES",
+                "PREFER_CAT"
+              ],
+              "cpu-arch": "PREFER_X86_64",
+              "cpu-model": "PREFER_SANDYBRIDGE"
+            },
+            "hypervisor-epa": {
+              "type": "PREFER_KVM"
+            },
+            "external-interface": [
+              {
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "name": "eth0",
+                "vnfd-connection-point-ref": "pong_vnfd/cp0"
+              }
+            ],
+            "count": 2,
+            "internal-interface": [
+              {
+                "vdu-internal-connection-point-ref": "7cb0ab18-9263-11e5-b7df-001b21b98a89",
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "name": "eth0"
+              }
+            ],
+            "cloud-init": "#cloud-config\npassword: fedora\nchpasswd: { expire: False }\nssh_pwauth: True\nruncmd:\n  - [ systemctl, daemon-reload ]\n  - [ systemctl, enable, pong.service ]\n  - [ systemctl, start, --no-block, pong.service ]\n  - [ ifup, eth1 ]\n  - [ ifup, eth2 ]\n",
+            "internal-connection-point": [
+              {
+                "type": "VPORT",
+                "id": "7cb0ab18-9263-11e5-b7df-001b21b98a89"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "vcpu-count": 2,
+              "storage-gb": 40
+            },
+            "guest-epa": {
+              "mempage-size": "PREFER_LARGE",
+              "cpu-thread-pinning-policy": "AVOID",
+              "trusted-execution": "true",
+              "numa-node-policy": {
+                "node": [
+                  {
+                    "vcpu": [
+                      0,
+                      1
+                    ],
+                    "memory-mb": 8192,
+                    "id": 0
+                  },
+                  {
+                    "vcpu": [
+                      2,
+                      3
+                    ],
+                    "memory-mb": 8192,
+                    "id": 1
+                  }
+                ],
+                "node-cnt": 2,
+                "mem-policy": "PREFERRED"
+              },
+              "cpu-pinning-policy": "DEDICATED"
+            },
+            "name": "iovdu",
+            "vswitch-epa": {
+              "ovs-acceleration": "DISABLED",
+              "ovs-offload": "DISABLED"
+            },
+            "id": "7cb0832c-9263-11e5-b7df-001b21b98a89"
+          }
+        ],
+        "description": "This is an example RIFT.ware VNF",
+        "connection-point": [
+          {
+            "type": "VPORT",
+            "name": "pong_vnfd/cp0"
+          }
+        ],
+        "monitoring-param": [
+          {
+            "units": "packets",
+            "description": "no of ping requests",
+            "current-value": 0,
+            "min-value": 0,
+            "path": "api/v1/pong/stats",
+            "id": 1,
+            "widget-type": "COUNTER",
+            "name": "ping-request-rx-count",
+            "max-value": 4292967295,
+            "group-tag": "Group1"
+          },
+          {
+            "units": "packets",
+            "description": "no of ping responses",
+            "current-value": 0,
+            "min-value": 0,
+            "path": "api/v1/pong/stats",
+            "id": 2,
+            "widget-type": "COUNTER",
+            "name": "ping-response-tx-count",
+            "max-value": 4292967295,
+            "group-tag": "Group1"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "7cb0832c-9263-11e5-b7df-001b21b98a89",
+          "port": 18889
+        },
+        "version": 1,
+        "internal-vld": [
+          {
+            "description": "Virtual link for internal fabric",
+            "type": "ELAN",
+            "internal-connection-point-ref": [
+              "7cb0ab18-9263-11e5-b7df-001b21b98a89"
+            ],
+            "name": "fabric",
+            "short-name": "fabric",
+            "id": "7cb048bc-9263-11e5-b7df-001b21b98a89"
+          }
+        ],
+        "vendor": "RIFT.io",
+        "name": "pong_vnfd",
+        "short-name": "pong_vnfd",
+        "id": "7cb0375a-9263-11e5-b7df-001b21b98a89"
+      },
+      {
+        "vdu": [
+          {
+            "image": "vyatta_snp.qcow2",
+            "host-epa": {
+              "cpu-socket-count": "PREFER_TWO",
+              "cpu-vendor": "PREFER_INTEL",
+              "cpu-feature": [
+                "PREFER_AES",
+                "PREFER_CAT"
+              ],
+              "cpu-arch": "PREFER_X86_64",
+              "cpu-model": "PREFER_SANDYBRIDGE"
+            },
+            "hypervisor-epa": {
+              "type": "PREFER_KVM"
+            },
+            "cloud-init": "#cloud-config\n",
+            "external-interface": [
+              {
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "name": "eth0",
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp0"
+              },
+              {
+                "virtual-interface": {
+                  "type": "VIRTIO"
+                },
+                "name": "eth1",
+                "vnfd-connection-point-ref": "vrouter_vnfd/cp1"
+              }
+            ],
+            "vm-flavor": {
+              "memory-mb": 4096,
+              "vcpu-count": 2,
+              "storage-gb": 40
+            },
+            "guest-epa": {
+              "mempage-size": "PREFER_LARGE",
+              "cpu-thread-pinning-policy": "AVOID",
+              "trusted-execution": "true",
+              "numa-node-policy": {
+                "node": [
+                  {
+                    "vcpu": [
+                      0,
+                      1
+                    ],
+                    "memory-mb": 8192,
+                    "id": 0
+                  },
+                  {
+                    "vcpu": [
+                      2,
+                      3
+                    ],
+                    "memory-mb": 8192,
+                    "id": 1
+                  }
+                ],
+                "node-cnt": 2,
+                "mem-policy": "PREFERRED"
+              },
+              "cpu-pinning-policy": "DEDICATED"
+            },
+            "name": "iovdu",
+            "count": 2,
+            "vswitch-epa": {
+              "ovs-acceleration": "DISABLED",
+              "ovs-offload": "DISABLED"
+            },
+            "id": "a4df6142-9263-11e5-ad06-001b21b98a89"
+          }
+        ],
+        "description": "This is a Brocade vRouter VNF",
+        "connection-point": [
+          {
+            "type": "VPORT",
+            "name": "vrouter_vnfd/cp0"
+          },
+          {
+            "type": "VPORT",
+            "name": "vrouter_vnfd/cp1"
+          }
+        ],
+        "monitoring-param": [
+          {
+            "units": "packets",
+            "description": "no of tx pkts",
+            "current-value": 0,
+            "min-value": 0,
+            "path": "api/v1/ping/stats",
+            "id": 1,
+            "widget-type": "COUNTER",
+            "name": "tx-count",
+            "max-value": 4292967295,
+            "group-tag": "Group1"
+          },
+          {
+            "units": "packets",
+            "description": "no of rx packets",
+            "current-value": 0,
+            "min-value": 0,
+            "path": "api/v1/ping/stats",
+            "id": 2,
+            "widget-type": "COUNTER",
+            "name": "rx-count",
+            "max-value": 4292967295,
+            "group-tag": "Group1"
+          }
+        ],
+        "mgmt-interface": {
+          "vdu-id": "a4df6142-9263-11e5-ad06-001b21b98a89",
+          "port": 18888
+        },
+        "version": 1,
+        "vendor": "Brocade",
+        "name": "vrouter_vnfd",
+        "short-name": "vrouter_vnfd",
+        "id": "a4dea522-9263-11e5-ad06-001b21b98a89"
+      }
+    ]
+  },
+  {
+    "id": "GUID-3",
+    "name": "RIFT.ware™ PNF Descriptors Catalog",
+    "short-name": "rift.ware-pnfd-cat",
+    "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+    "vendor": "RIFT.io",
+    "version": "",
+    "created-on": "",
+    "type": "pnfd",
+    "descriptors": []
+  }
+]
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/assets/rift.ware-color-theme.json b/skyquake/plugins/composer/src/src/assets/rift.ware-color-theme.json
new file mode 100644 (file)
index 0000000..deadd18
--- /dev/null
@@ -0,0 +1,37 @@
+{
+       "nsd": {
+               "primary": "#6c71c4",
+               "secondary": "#6c71c4"
+       },
+       "vld": {
+               "primary": "#073642",
+               "secondary": "#073642"
+       },
+       "internal-vld": {
+               "primary": "#073642",
+               "secondary": "#073642"
+       },
+       "vdu": {
+               "primary": "#859900",
+               "secondary": "#859900"
+       },
+       "vnfd": {
+               "primary": "#268bd2",
+               "secondary": "#268bd2"
+       },
+       "constituent-vnfd": {
+               "primary": "#268bd2",
+               "secondary": "#268bd2"
+       },
+       "vnffgd": {
+               "primary": "#2aa198",
+               "secondary": "#2aa198"
+       },
+       "common": {
+               "primary": "black",
+               "secondary": "white",
+               "background": "white",
+               "foreground": "black"
+       }
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/components/Button.js b/skyquake/plugins/composer/src/src/components/Button.js
new file mode 100644 (file)
index 0000000..7a5a7f5
--- /dev/null
@@ -0,0 +1,69 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 12/1/15.
+ */
+'use strict';
+
+import guid from '../libraries/guid'
+import React from 'react'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import SelectionManager from '../libraries/SelectionManager'
+
+import '../styles/Button.scss'
+
+const Button = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState: function () {
+               return {};
+       },
+       getDefaultProps: function () {
+               return {
+                       className: '',
+                       label: null,
+                       title: null,
+                       src: null,
+                       onClick: () => {}
+               };
+       },
+       componentWillMount: function () {
+       },
+       componentDidMount: function () {
+       },
+       componentDidUpdate: function () {
+       },
+       componentWillUnmount: function () {
+       },
+       render() {
+               const src = this.props.src;
+               const label = this.props.label;
+               const title = this.props.title;
+               const draggable = this.props.draggable;
+               const className = ClassNames(this.props.className, 'Button');
+               return (
+                       <div className={className} onClick={this.props.onClick} title={title} draggable={draggable} onDragStart={this.props.onDragStart}>
+                               <img src={src} />
+                               <span>{label}</span>
+                       </div>
+               );
+       }
+});
+
+export default Button;
diff --git a/skyquake/plugins/composer/src/src/components/CanvasPanel.js b/skyquake/plugins/composer/src/src/components/CanvasPanel.js
new file mode 100644 (file)
index 0000000..6b04bd9
--- /dev/null
@@ -0,0 +1,196 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import cc from 'change-case'
+import React from 'react'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import utils from '../libraries/utils'
+import messages from './messages'
+import DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'
+import CatalogItemCanvasEditor from './CatalogItemCanvasEditor'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import CanvasEditorActions from '../actions/CanvasEditorActions'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import CanvasZoom from './CanvasZoom'
+import CanvasPanelTray from './CanvasPanelTray'
+import EditForwardingGraphPaths from './EditorForwardingGraph/EditForwardingGraphPaths'
+import SelectionManager from '../libraries/SelectionManager'
+import DescriptorModelIconFactory from '../libraries/model/IconFactory'
+
+import '../styles/CanvasPanel.scss'
+
+const CanvasPanel = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {};
+       },
+       getDefaultProps() {
+               return {
+                       title: '',
+                       layout: {
+                               left: 300,
+                               right: 300
+                       },
+                       showMore: false,
+                       containers: []
+               };
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+               SelectionManager.refreshOutline();
+       },
+       componentWillUnmount() {
+       },
+       render() {
+               var style = {
+                       left: this.props.layout.left
+               };
+               var req = require.context("../", true, /^\.\/.*\.svg$/);
+               const hasItem = this.props.containers.length !== 0;
+               const isEditingNSD = DescriptorModelFactory.isNetworkService(this.props.containers[0]);
+               const hasNoCatalogs = this.props.hasNoCatalogs;
+               const bodyComponent = hasItem ? <CatalogItemCanvasEditor zoom={this.props.zoom} isShowingMoreInfo={this.props.showMore} containers={this.props.containers}/> : messages.canvasWelcome();
+               return (
+                       <div id="canvasPanelDiv" className="CanvasPanel" style={style} onDragOver={this.onDragOver} onDrop={this.onDrop}>
+                               <div onDoubleClick={this.onDblClickOpenFullScreen}  className="CanvasPanelHeader panel-header" data-resizable="limit_bottom">
+                                       <h1>
+                                               {hasItem ? <img src={req('./' + DescriptorModelIconFactory.getUrlForType(this.props.containers[0].type, 'black'))} width="20px" /> : null}
+                                               <span className="model-name">{this.props.title}</span>
+                                       </h1>
+                               </div>
+                               <div className="CanvasPanelBody panel-body" style={{marginRight: this.props.layout.right, bottom: this.props.layout.bottom}} >
+                                       {hasNoCatalogs ? null : bodyComponent}
+                               </div>
+                               <CanvasZoom zoom={this.props.zoom} style={{bottom: this.props.layout.bottom + 20}}/>
+                               <CanvasPanelTray layout={this.props.layout} show={isEditingNSD}>
+                                       <EditForwardingGraphPaths containers={this.props.containers} />
+                               </CanvasPanelTray>
+                       </div>
+               );
+       },
+       onDragOver(event) {
+               const isDraggingFiles = _.contains(event.dataTransfer.types, 'Files');
+               if (!isDraggingFiles) {
+                       event.preventDefault();
+                       event.dataTransfer.dropEffect = 'copy';
+               }
+       },
+       onDrop(event) {
+               // given a drop event determine which action to take in the canvas:
+               // open item or add item to an existing, already opened nsd
+               // note: nsd is the only editable container
+               const data = utils.parseJSONIgnoreErrors(event.dataTransfer.getData('text'));
+               if (data.type === 'catalog-item') {
+                       this.handleDropCatalogItem(event, data);
+               } else if (data.type === 'action') {
+                       this.handleDropCanvasAction(event, data);
+               }
+       },
+       handleDropCanvasAction(event, data) {
+               const action = cc.camel('on-' + data.action);
+               if (typeof this[action] === 'function') {
+                       if (this[action]({clientX: event.clientX, clientY: event.clientY})) {
+                               event.preventDefault();
+                       }
+               } else {
+                       console.warn(`no action defined for drop event ${data.action}. Did you forget to add CanvasPanel.${action}() event handler?`);
+               }
+       },
+       handleDropCatalogItem(event, data) {
+               let openItem = null;
+               const currentItem = this.props.containers[0];
+               if (data.item.uiState.type === 'nsd') {
+                       // if item is an nsd then open the descriptor in the canvas
+                       openItem = data.item;
+                       // if item is a vnfd or pnfd then check if the current item is an nsd
+               } else if (DescriptorModelFactory.isNetworkService(currentItem)) {
+                       // so add the item to the nsd and re-render the canvas
+                       switch (data.item.uiState.type) {
+                       case 'vnfd':
+                               this.onAddVnfd(data.item, {clientX: event.clientX, clientY: event.clientY});
+                               break;
+                       case 'pnfd':
+                               this.onAddPnfd(data.item, {clientX: event.clientX, clientY: event.clientY});
+                               break;
+                       default:
+                               console.warn(`Unknown catalog-item type. Expect type "nsd", "vnfd" or "pnfd" but got ${data.item.uiState.type}.`);
+                       }
+               } else {
+                       // otherwise the default action is to open the item
+                       openItem = data.item;
+               }
+               if (openItem) {
+                       event.preventDefault();
+                       CatalogItemsActions.editCatalogItem(openItem);
+               }
+       },
+       onAddVdu(dropCoordinates) {
+               const currentItem = this.props.containers[0];
+               if (DescriptorModelFactory.isVirtualNetworkFunction(currentItem)) {
+                       const vdu = currentItem.createVdu();
+                       vdu.uiState.dropCoordinates = dropCoordinates;
+                       CatalogItemsActions.catalogItemDescriptorChanged(currentItem);
+               }
+       },
+       onAddVld(dropCoordinates) {
+               const currentItem = this.props.containers[0];
+               if (DescriptorModelFactory.isNetworkService(currentItem) || DescriptorModelFactory.isVirtualNetworkFunction(currentItem)) {
+                       const vld = currentItem.createVld();
+                       vld.uiState.dropCoordinates = dropCoordinates;
+                       CatalogItemsActions.catalogItemDescriptorChanged(currentItem);
+               }
+       },
+       onAddVnffgd(dropCoordinates) {
+               const currentItem = this.props.containers[0];
+               if (DescriptorModelFactory.isNetworkService(currentItem)) {
+                       const vld = currentItem.createVnffgd();
+                       vld.uiState.dropCoordinates = dropCoordinates;
+                       CatalogItemsActions.catalogItemDescriptorChanged(currentItem);
+               }
+       },
+       onAddVnfd(model, dropCoordinates) {
+               const currentItem = this.props.containers[0];
+               if (DescriptorModelFactory.isNetworkService(currentItem) || DescriptorModelFactory.isVirtualNetworkFunction(currentItem)) {
+                       const vnfd = DescriptorModelFactory.newVirtualNetworkFunction(model);
+                       const cvnfd = currentItem.createConstituentVnfdForVnfd(vnfd);
+                       cvnfd.uiState.dropCoordinates = dropCoordinates;
+                       CatalogItemsActions.catalogItemDescriptorChanged(currentItem);
+               }
+       },
+       onAddPnfd(model, dropCoordinates) {
+               const currentItem = this.props.containers[0];
+               if (DescriptorModelFactory.isNetworkService(currentItem)) {
+                       const pnfd = DescriptorModelFactory.newPhysicalNetworkFunction(model);
+                       pnfd.uiState.dropCoordinates = dropCoordinates;
+                       currentItem.createPnfd(pnfd);
+                       CatalogItemsActions.catalogItemDescriptorChanged(currentItem);
+               }
+       },
+       onDblClickOpenFullScreen(event) {
+               event.stopPropagation();
+               ComposerAppActions.enterFullScreenMode();
+       }
+});
+
+export default CanvasPanel;
diff --git a/skyquake/plugins/composer/src/src/components/CanvasPanelTray.js b/skyquake/plugins/composer/src/src/components/CanvasPanelTray.js
new file mode 100644 (file)
index 0000000..57f29a0
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * Created by onvelocity on 2/4/16.
+ */
+'use strict';
+import React from 'react'
+import ClassNames from 'classnames'
+import ResizableManager from '../libraries/ResizableManager'
+import CanvasPanelTrayActions from '../actions/CanvasPanelTrayActions'
+import '../styles/CanvasPanelTray.scss'
+const uiTransient = {
+       isResizing: false
+};
+export default function (props) {
+       const style = {
+               height: Math.max(0, props.layout.bottom),
+               right: props.layout.right,
+               display: props.show ? false : 'none'
+       };
+       const classNames = ClassNames('CanvasPanelTray', {'-with-transitions': !document.body.classList.contains('resizing')});
+       function onClickToggleOpenClose(event) {
+               if (event.defaultPrevented) return;
+               event.preventDefault();
+               // don't toggle if the user was resizing
+               if (!uiTransient.isResizing) {
+                       CanvasPanelTrayActions.toggleOpenClose();
+               }
+               event.target.removeEventListener('mousemove', onMouseMove, true);
+       }
+       function onMouseDown(event) {
+               uiTransient.isResizing = false;
+               event.target.addEventListener('mousemove', onMouseMove, true);
+       }
+       function onMouseMove() {
+               uiTransient.isResizing = ResizableManager.isResizing();
+       }
+       // note 25px is the height of the h1
+       const isOpen = style.height > 25;
+       return (
+               <div className={classNames} data-resizable="top" data-resizable-handle-offset="4" style={style}>
+                       <h1 data-open-close-icon={isOpen ? 'open' : 'closed'} onMouseDownCapture={onMouseDown} onClick={onClickToggleOpenClose}>Forwarding Graphs</h1>
+                       <div className="tray-body">
+                               {props.children}
+                       </div>
+               </div>
+       );
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/components/CanvasZoom.js b/skyquake/plugins/composer/src/src/components/CanvasZoom.js
new file mode 100644 (file)
index 0000000..a2aa526
--- /dev/null
@@ -0,0 +1,74 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react'
+import Range from './Range'
+import numeral from 'numeral'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CanvasEditorActions from '../actions/CanvasEditorActions'
+import SelectionManager from '../libraries/SelectionManager'
+
+import '../styles/CanvasZoom.scss'
+
+const CanvasZoom = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState: function () {
+               return {};
+       },
+       getDefaultProps: function () {
+               return {
+                       min: 25,
+                       max: 200,
+                       zoom: 100,
+                       defaultZoom: 100
+               };
+       },
+       componentWillMount: function () {
+       },
+       componentDidMount: function () {
+       },
+       componentDidUpdate: function () {
+       },
+       componentWillUnmount: function () {
+       },
+       render() {
+               const zoom = this.props.zoom || this.props.defaultZoom
+               const displayValue = numeral(zoom).format('0.0') + '%';
+               return (
+                       <div ref="canvasZoom" className="CanvasZoom" style={this.props.style} onClick={event => event.preventDefault()}>
+                               <Range
+                                          value={zoom} min={this.props.min} max={this.props.max}
+                                          title="Zoom the canvas. Double Click to reset to 100%."
+                                          onChange={this.onChange} onDoubleClick={this.onDblClick} />
+                               <span>{displayValue}</span>
+                       </div>
+               );
+       },
+       onChange(event) {
+               const zoom = event.target.value;
+               CanvasEditorActions.setCanvasZoom(zoom);
+       },
+       onDblClick() {
+               const zoom = this.props.defaultZoom;
+               CanvasEditorActions.setCanvasZoom(zoom);
+       }
+});
+
+export default CanvasZoom;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogFilter.js b/skyquake/plugins/composer/src/src/components/CatalogFilter.js
new file mode 100644 (file)
index 0000000..6ae460e
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 12/2/15.
+ */
+'use strict';
+
+import React from 'react'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CatalogFilterActions from '../actions/CatalogFilterActions'
+import NSDicon from '../../../node_modules/open-iconic/svg/map.svg'
+import VNFDicon from '../../../node_modules/open-iconic/svg/map-marker.svg'
+import Isvg from 'react-inlinesvg';
+import '../styles/CatalogFilter.scss'
+
+const CatalogFilter = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState: function () {
+               return {};
+       },
+       getDefaultProps: function () {
+               return {filterByType: 'nsd'};
+       },
+       componentWillMount: function () {
+       },
+       componentDidMount: function () {
+       },
+       componentDidUpdate: function () {
+       },
+       componentWillUnmount: function () {
+       },
+       render() {
+               const clickFilterByType = function (event) {
+                       CatalogFilterActions.filterByType(event.currentTarget.value);
+               };
+
+               return (
+                       <div className="CatalogFilter">
+                               <button className={ClassNames('CatalogFilterNSD', {'-selected': this.props.filterByType === 'nsd'})}
+                                               value="nsd" onClick={clickFilterByType}><svg width="8" height="8" viewBox="0 0 8 8"><path  transform="scale(0.018) translate(-50,5)" d='M325.55,87.34c0,34.54-27.71,62.55-61.89,62.55s-61.89-28-61.89-62.55S229.48,24.8,263.66,24.8,325.55,52.8,325.55,87.34Zm-220.1,96.09c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S139.63,183.43,105.45,183.43ZM259,235.18c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S293.23,235.18,259,235.18Zm153.6-51.74c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S446.83,183.43,412.64,183.43ZM213,127.14l-66,80.5m116.59-57.75v85.29m42.76-104.42,64,64.68'></path></svg>NSD
+                               </button>
+                               <button className={ClassNames('CatalogFilterVNFD', {'-selected': this.props.filterByType === 'vnfd'})}
+                                               value="vnfd" onClick={clickFilterByType}><svg><circle cx="50%" cy="50%" r="6" /></svg>VNFD
+                               </button>
+                       </div>
+               );
+       }
+});
+
+export default CatalogFilter;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogItemCanvasEditor.js b/skyquake/plugins/composer/src/src/components/CatalogItemCanvasEditor.js
new file mode 100644 (file)
index 0000000..097596d
--- /dev/null
@@ -0,0 +1,83 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react'
+import ReactDOM from 'react-dom'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import DescriptorGraph from '../libraries/graph/DescriptorGraph'
+import ComposerAppStore from '../stores/ComposerAppStore'
+
+import '../styles/CatalogItemCanvasEditor.scss'
+import '../styles/DescriptorGraph.scss'
+
+const CatalogItemCanvasEditor = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {
+                       graph: null
+               };
+       },
+       getDefaultProps() {
+               return {
+                       zoom: 100,
+                       containers: [],
+                       isShowingMoreInfo: false
+               };
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+               const element = ReactDOM.findDOMNode(this.refs.descriptorGraph);
+               const options = {
+                       zoom: this.props.zoom
+               };
+               const graph = new DescriptorGraph(element, options);
+               graph.containers = this.props.containers;
+               this.setState({graph: graph});
+       },
+       componentDidUpdate() {
+               this.state.graph.containers = this.props.containers;
+               const isNSD = this.props.containers[0] && this.props.containers[0].uiState.type === 'nsd';
+               if (isNSD) {
+                       this.state.graph.showMoreInfo = this.props.isShowingMoreInfo;
+               } else {
+                       this.state.graph.showMoreInfo = true;
+               }
+               this.state.graph.update();
+       },
+       componentWillUnmount() {
+               this.state.graph.destroy();
+       },
+       render() {
+               const graph = this.state.graph;
+               if (graph) {
+                       graph.zoom(this.props.zoom);
+               }
+               return (
+                       <div data-offset-parent="true" className="CatalogItemCanvasEditor">
+                               <div key="outline-indicator" data-outline-indicator="true"></div>
+                               <div id='canvas-dropzone' style={{visibility: 'hidden'}}></div>
+                               <div ref="descriptorGraph" className="DescriptorGraph"></div>
+                       </div>
+               );
+       }
+});
+
+export default CatalogItemCanvasEditor;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogItemDetailsEditor.js b/skyquake/plugins/composer/src/src/components/CatalogItemDetailsEditor.js
new file mode 100644 (file)
index 0000000..752d678
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import EditDescriptorModelProperties from './EditDescriptorModelProperties'
+
+const CatalogItemDetailsEditor = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {};
+       },
+       getDefaultProps() {
+               return {
+                       container: null,
+                       width: 0
+               };
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+       },
+       render() {
+
+               const container = this.props.container || {model: {}, uiState: {}};
+               if (!(container && container.model && container.uiState)) {
+                       return null;
+               }
+
+               return (
+                       <div className="CatalogItemDetailsEditor">
+                               <form name="details-descriptor-editor-form">
+                                       <div className="properties-group">
+                                               <EditDescriptorModelProperties container={this.props.container} width={this.props.width} />
+                                       </div>
+                               </form>
+                       </div>
+               );
+
+       }
+});
+
+export default CatalogItemDetailsEditor;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogItems.js b/skyquake/plugins/composer/src/src/components/CatalogItems.js
new file mode 100644 (file)
index 0000000..c86f087
--- /dev/null
@@ -0,0 +1,152 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import UID from '../libraries/UniqueId'
+import React from 'react'
+import messages from './messages'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CatalogDataStore from '../stores/CatalogDataStore'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import SelectionManager from '../libraries/SelectionManager'
+
+import '../styles/CatalogItems.scss'
+import imgFile from 'file!../images/vendor-riftio.png'
+
+const CatalogItems = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return CatalogDataStore.getState();
+       },
+       getDefaultProps() {
+               return {
+                       filterByType: 'nsd'
+               };
+       },
+       componentWillMount() {
+               CatalogDataStore.listen(this.onChange);
+       },
+       componentDidMount() {
+               // async actions creator will dispatch loadCatalogsSuccess and loadCatalogsError messages
+               CatalogDataStore.loadCatalogs().catch(e => console.warn('unable to load catalogs', e));
+       },
+       componentWillUnmount() {
+               CatalogDataStore.unlisten(this.onChange);
+       },
+       onChange(state) {
+               this.setState(state);
+       },
+       renderVersion(version) {
+               if (version) {
+                       return (<span className='version'>{version}</span>);
+               } // else return null by default
+       },
+       handleImageError(e) {
+               console.log('Bad logo path, using default');
+               e.target.src = require('style/img/catalog-default.svg');
+       },
+       render() {
+               const self = this;
+               const onDragStart = function(event) {
+                       const data = {type: 'catalog-item', item: this};
+                       event.dataTransfer.effectAllowed = 'copy';
+                       event.dataTransfer.setData('text', JSON.stringify(data));
+                       ComposerAppActions.setDragState(data);
+               };
+               const onDblClickCatalogItem = function () {
+                       CatalogItemsActions.editCatalogItem(this);
+               };
+               const onClickCatalogItem = function () {
+                       // single clicking an item is handled by ComposerApp::onClick handler
+                       //CatalogItemsActions.selectCatalogItem(this);
+               };
+               const cleanDataURI = this.cleanDataURI;
+               const items = this.getCatalogItems().map(function (d) {
+                       const isNSD = d.uiState.type === 'nsd';
+                       const isVNFD = d.uiState.type === 'vnfd';
+                       const isDeleted = d.uiState.deleted;
+                       const isModified = d.uiState.modified;
+                       const isSelected = SelectionManager.isSelected(d);
+                       const isOpenForEdit = d.uiState.isOpenForEdit;
+                       const spanClassNames = ClassNames({'-is-selected': isSelected, '-is-open-for-edit': isOpenForEdit});
+                       const sectionClassNames = ClassNames('catalog-item', {'-is-modified': isModified, '-is-deleted': isDeleted});
+                       const instanceCount = d.uiState['instance-ref-count'];
+                       const instanceCountLabel = isNSD && instanceCount ? <span>({instanceCount})</span> : null;
+                       let type;
+                       if(isNSD) {
+                               type = 'nsd';
+                       }
+                       if(isVNFD) {
+                               type = 'vnfd';
+                       }
+                       return (
+                               <li key={d.id} data-uid={UID.from(d)} onClick={onClickCatalogItem.bind(d)} onDoubleClick={onDblClickCatalogItem.bind(d)}>
+                                       <div className={spanClassNames + ' ' + type}>
+                                               <div className={sectionClassNames} id={d.id} draggable="true" onDragStart={onDragStart.bind(d)}>
+                                                       {isModified ? <div className="-is-modified-indicator" title="This descriptor has changes."></div> : null}
+                                                       <div className="type-header">{type}</div>
+                                                       <dl>
+                                                               <dt className="name">{d.name} {instanceCountLabel}</dt>
+                                                               <dd className="logo">
+                                                               <img className="logo" src={cleanDataURI(d['logo'], type, d.id)} draggable="false"  onError={self.handleImageError} />
+                                                               </dd>
+                                                               <dd className="short-name" title={d.name}>{d['short-name']}</dd>
+                                                               <dd className="description">{d.description}</dd>
+                                                               <dd className="vendor">{d.vendor || d.provider} {self.renderVersion(d.version)}</dd>
+                                                       </dl>
+                                               </div>
+                                       </div>
+                                       {isOpenForEdit ? <div className="-is-open-for-edit-indicator" title="This descriptor is open in the canvas."></div> : null}
+                               </li>
+                       );
+               });
+               return (
+                       <div className="CatalogItems" data-offset-parent="true">
+                               <ul>
+                                       {items.length ? items : messages.catalogWelcome}
+                               </ul>
+                       </div>
+               );
+       },
+       cleanDataURI(imageString, type, id) {
+               if (/\bbase64\b/g.test(imageString)) {
+                       return imageString;
+               } else if (/<\?xml\b/g.test(imageString)) {
+                       const imgStr = imageString.substring(imageString.indexOf('<?xml'));
+                       return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr);
+               } else if (/\.(svg|png|gif|jpeg|jpg)$/.test(imageString)) {
+                       return 'assets/logos/' + type + '/' + id + '/' + imageString;
+                       // return require('../images/logos/' + imageString);
+               }
+               if(type == 'nsd' || type == 'vnfd') {
+                       return require('style/img/catalog-'+type+'-default.svg');
+               }
+               return require('style/img/catalog-default.svg');
+       },
+       getCatalogItems() {
+               const catalogFilter = (d) => {return d.type === this.props.filterByType};
+               return this.state.catalogs.filter(catalogFilter).reduce((result, catalog) => {
+                       return result.concat(catalog.descriptors);
+               }, []);
+       }
+});
+
+export default CatalogItems;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogPackageManager.js b/skyquake/plugins/composer/src/src/components/CatalogPackageManager.js
new file mode 100644 (file)
index 0000000..c0b996c
--- /dev/null
@@ -0,0 +1,122 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react'
+import moment from 'moment'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CatalogPackageManagerStore from '../stores/CatalogPackageManagerStore'
+import CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'
+import Button from './Button'
+
+import '../styles/CatalogPackageManager.scss'
+// import imgVideoFileType from '../images/video167.svg'
+// import imgZipFileType from '../images/zipped2.svg'
+// import imgUnknownFileType from '../images/file87.svg'
+import imgCancel from '../../../node_modules/open-iconic/svg/circle-x.svg'
+
+const CatalogPackageManager = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return CatalogPackageManagerStore.getState();
+       },
+       getDefaultProps() {
+               return {};
+       },
+       componentWillMount() {
+               CatalogPackageManagerStore.listen(this.onChange);
+       },
+       componentDidMount() {
+       },
+       onChange(state) {
+               this.setState(state);
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+               CatalogPackageManagerStore.unlisten(this.onChange);
+       },
+       render() {
+               function getIndicator(download) {
+                       if (download.pending) {
+                               return (
+                                       <div className="file-progress-indicator">
+                                               <div className="file-progress-indicator-value" style={{width: (download.progress || 0) + '%'}}></div>
+                                       </div>
+                               );
+                       }
+               }
+               function getDownloadLink(download) {
+                       if (download.success) {
+                               const now = moment();
+                               const duration = moment.duration(moment(download.urlValidUntil).diff(now));
+                               return (
+                                       <div className="file-download">
+                                               <a className="file-download-link" href={download.url}>Download Package</a>
+                                               <span>expires&nbsp;</span> {duration.humanize(true)}
+
+                                       </div>
+                               );
+                       }
+               }
+
+               function getMessage(catalogPackage) {
+                       if (catalogPackage.success && catalogPackage.url) {
+                               return getDownloadLink(catalogPackage);
+                       }
+                       return (
+                               <div className="message">{catalogPackage.message}</div>
+                       );
+               }
+
+               var createItem = function (catalogPackage) {
+                       const onClickRemove = function () {
+                               CatalogPackageManagerActions.removeCatalogPackage(catalogPackage);
+                       };
+                       const classNames = ClassNames('item', {'-error': catalogPackage.error, '-success': catalogPackage.success});
+                       return (
+                               <div ref="catalogPackage" className={classNames} key={catalogPackage.id}>
+                                       <div className="item-body">
+                                               <h2 title={catalogPackage.name}>{catalogPackage.name}</h2>
+                                               <img src={catalogPackage.icon} />
+                                               {getIndicator(catalogPackage)}
+                                               {getMessage(catalogPackage)}
+                                       </div>
+                                       <div className="item-actions">
+                                               <Button className="action-remove-catalog-package" onClick={onClickRemove} src={imgCancel} />
+                                       </div>
+                               </div>
+                       );
+               };
+
+               const packages = this.state.packages || [];
+               return (
+                       <div className="CatalogPackageManager">
+                               <div className="items">
+                                       {packages.map(createItem)}
+                               </div>
+                       </div>
+               );
+
+       }
+
+});
+
+export default CatalogPackageManager;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogPanel.js b/skyquake/plugins/composer/src/src/components/CatalogPanel.js
new file mode 100644 (file)
index 0000000..535a928
--- /dev/null
@@ -0,0 +1,201 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import React from 'react'
+import ReactDOM from 'react-dom'
+import messages from './messages'
+import ClassNames from 'classnames'
+import UploadDropZone from '../libraries/CatalogPackageManagerUploadDropZone'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import DropTarget from './DropTarget'
+import DropZonePanel from './DropZonePanel'
+import CatalogItems from './CatalogItems'
+import CatalogFilter from './CatalogFilter'
+import CatalogPanelTray from './CatalogPanelTray'
+import CatalogPanelToolbar from './CatalogPanelToolbar'
+import CatalogPackageManager from './CatalogPackageManager'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import ComposerAppStore from '../stores/ComposerAppStore'
+import CatalogPanelStore from '../stores/CatalogPanelStore'
+import LoadingIndicator from './LoadingIndicator'
+import SelectionManager from '../libraries/SelectionManager'
+
+import '../styles/CatalogPanel.scss'
+
+const createDropZone = function (action, clickable, dropTarget) {
+       const dropZone = new UploadDropZone(ReactDOM.findDOMNode(dropTarget), [clickable], action);
+       dropZone.on('dragover', this.onDragOver);
+       dropZone.on('dragend', this.onDragEnd);
+       dropZone.on('addedfile', this.onFileAdded);
+       return dropZone;
+};
+
+const uiTransientState = {
+       isDrop: false,
+       isDragging: false,
+       isDraggingFiles: false,
+       timeoutId: 0
+};
+
+const CatalogPanel = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return CatalogPanelStore.getState();
+       },
+       getDefaultProps() {
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+               CatalogPanelStore.listen(this.onChange);
+               document.body.addEventListener('dragover', this.onDragOver);
+               document.body.addEventListener('dragend', this.onDragEnd);
+               window.addEventListener('dragend', this.onDragEnd);
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+               CatalogPanelStore.unlisten(this.onChange);
+               document.body.removeEventListener('dragover', this.onDragOver);
+               document.body.removeEventListener('dragend', this.onDragEnd);
+               window.removeEventListener('dragend', this.onDragEnd);
+       },
+       render() {
+
+               const onDropCatalogItem = e => {
+                       e.preventDefault();
+                       clearTimeout(uiTransientState.timeoutId);
+                       uiTransientState.isDragging = false;
+                       uiTransientState.isDrop = true;
+                       const item = JSON.parse(e.dataTransfer.getData('text')).item;
+                       CatalogItemsActions.exportSelectedCatalogItems(item);
+                       CatalogPanelTrayActions.open();
+               };
+
+               const onDropUpdatePackage = e => {
+                       e.preventDefault();
+                       clearTimeout(uiTransientState.timeoutId);
+                       uiTransientState.isDragging = false;
+                       uiTransientState.isDrop = true;
+                       CatalogPanelTrayActions.open();
+               };
+
+               const onDropOnboardPackage = e => {
+                       e.preventDefault();
+                       clearTimeout(uiTransientState.timeoutId);
+                       uiTransientState.isDragging = false;
+                       uiTransientState.isDrop = true;
+                       CatalogPanelTrayActions.open();
+               };
+
+               const isDraggingItem = uiTransientState.isDragging && !uiTransientState.isDraggingFiles;
+               const isDraggingFiles = uiTransientState.isDragging && uiTransientState.isDraggingFiles;
+               const updateDropZone = createDropZone.bind(this, UploadDropZone.ACTIONS.update, '.action-update-catalog-package');
+               const onboardDropZone = createDropZone.bind(this, UploadDropZone.ACTIONS.onboard, '.action-onboard-catalog-package');
+               const className = ClassNames('CatalogPanel', {'-is-tray-open': this.state.isTrayOpen});
+               const hasNoCatalogs = this.props.hasNoCatalogs;
+               const isLoading = this.props.isLoading;
+               return (
+                       <div className={className} data-resizable="right" data-resizable-handle-offset="0 6" style={{width: this.props.layout.left}}>
+                               <CatalogPanelToolbar />
+                               <div className="CatalogPanelBody">
+                                       {(() => {
+                                               if (isLoading) {
+                                                       return (
+                                                               <div className="LoaderWrapper">
+                                                                       <LoadingIndicator />
+                                                               </div>
+                                                       )
+                                               }
+                                               if (hasNoCatalogs) {
+                                                       return messages.catalogWelcome;
+                                               }
+                                               return (
+                                                       <div>
+                                                               <CatalogFilter filterByType={this.props.filterByType} />
+                                                               <CatalogItems filterByType={this.props.filterByType} />
+                                                       </div>
+                                               );
+                                       })()}
+                               </div>
+                               <CatalogPanelTray show={this.state.isTrayOpen}>
+                                       <DropZonePanel show={isDraggingItem} title="Drop catalog item to export.">
+                                               <DropTarget className="action-export-catalog-items" onDrop={onDropCatalogItem}>
+                                                       <span>Export catalog item.</span>
+                                               </DropTarget>
+                                       </DropZonePanel>
+                                       <DropZonePanel show={isDraggingFiles}>
+                                               <DropTarget className="action-onboard-catalog-package" dropZone={onboardDropZone} onDrop={onDropOnboardPackage}>
+                                                       <span>On-board new catalog package.</span>
+                                               </DropTarget>
+                                               <DropTarget className="action-update-catalog-package" dropZone={updateDropZone} onDrop={onDropUpdatePackage}>
+                                                       <span>Update existing catalog package.</span>
+                                               </DropTarget>
+                                       </DropZonePanel>
+                                       <CatalogPackageManager />
+                               </CatalogPanelTray>
+                       </div>
+               );
+
+       },
+       onChange(state) {
+               this.setState(state);
+       },
+       onDragOver(e) {
+               // NOTE do not call preventDefault here - see DropTarget
+               if (!uiTransientState.isDragging) {
+                       uiTransientState.isDrop = false;
+                       uiTransientState.isDragging = true;
+                       uiTransientState.wasTrayOpen = this.state.isTrayOpen;
+                       uiTransientState.isDraggingFiles = _.contains(e.dataTransfer.types, 'Files');
+                       const dragState = ComposerAppStore.getState().drag || {};
+                       if (uiTransientState.isDraggingFiles || (dragState.type === 'catalog-item')) {
+                               CatalogPanelTrayActions.open();
+                       }
+               }
+               e.dataTransfer.dropEffect = 'none';
+               // the drag-end event does not fire on drag events that originate
+               // outside of the browser, e.g. dragging files from desktop, so
+               // we use this debounced callback to simulate a drag-end event
+               clearTimeout(uiTransientState.timeoutId);
+               uiTransientState.timeoutId = setTimeout(() => {
+                       this.onDragEnd();
+               }, 400);
+       },
+       onDragEnd() {
+               clearTimeout(uiTransientState.timeoutId);
+               if (uiTransientState.isDragging) {
+                       uiTransientState.isDragging = false;
+                       if (uiTransientState.isDrop || uiTransientState.wasTrayOpen) {
+                               CatalogPanelTrayActions.open();
+                       } else {
+                               CatalogPanelTrayActions.close();
+                       }
+               }
+       },
+       onFileAdded() {
+               CatalogPanelTrayActions.open();
+       }
+});
+
+export default CatalogPanel;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogPanelToolbar.js b/skyquake/plugins/composer/src/src/components/CatalogPanelToolbar.js
new file mode 100644 (file)
index 0000000..5e3e3c0
--- /dev/null
@@ -0,0 +1,105 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react'
+import Button from './Button'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+
+import '../styles/CatalogPanelToolbar.scss'
+
+import imgAdd from '../../../node_modules/open-iconic/svg/plus.svg'
+import imgCopy from '../../../node_modules/open-iconic/svg/layers.svg'
+import imgOnboard from '../../../node_modules/open-iconic/svg/cloud-upload.svg'
+import imgUpdate from '../../../node_modules/open-iconic/svg/rain.svg'
+import imgDownload from '../../../node_modules/open-iconic/svg/cloud-download.svg'
+import imgDelete from '../../../node_modules/open-iconic/svg/trash.svg'
+
+const CatalogHeader = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {};
+       },
+       getDefaultProps() {
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+       },
+       render() {
+               return (
+                       <div className="CatalogPanelToolbar">
+                               <h1>Descriptor Catalogs</h1>
+                               <div className="btn-bar">
+                                       <div className="btn-group">
+                                               <Button type="image" title="OnBoard a catalog package" className="action-onboard-catalog-package" onClick={this.onClickOnBoardCatalog} src={imgOnboard} />
+                                               <Button type="image" title="Update a catalog package" className="action-update-catalog-package" onClick={this.onClickUpdateCatalog} src={imgUpdate} />
+                                               <Button type="image" title="Export selected catalog item(s)" className="action-export-catalog-items" onClick={this.onClickExportCatalogItems} src={imgDownload} />
+                                       </div>
+                                       <div className="btn-group">
+                                               <div className="menu">
+                                                       <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} />
+                                                       <div className="sub-menu">
+                                                               <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} label="Add NSD" />
+                                                               <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'vnfd')} src={imgAdd} label="Add VNFD" />
+                                                       </div>
+                                               </div>
+                                               <Button type="image" title="Copy catalog item" className="action-copy-catalog-item" onClick={this.onClickDuplicateCatalogItem} src={imgCopy} />
+                                       </div>
+                                       <div className="btn-group">
+                                               <Button type="image" title="Delete catalog item" className="action-delete-catalog-item" onClick = {this.onClickDeleteCatalogItem} src={imgDelete} />
+                                       </div>
+                               </div>
+                       </div>
+               );
+       },
+       onClickUpdateCatalog() {
+               //CatalogPanelTrayActions.open();
+               // note CatalogPackageManagerUploadDropZone wired our btn
+               // click event to the DropZone.js configuration and will
+               // open the tray when/if files are added to the drop zone
+       },
+       onClickOnBoardCatalog() {
+               //CatalogPanelTrayActions.open();
+               // note CatalogPackageManagerUploadDropZone wired our btn
+               // click event to the DropZone.js configuration and will
+               // open the tray when/if files are added to the drop zone
+       },
+       onClickDeleteCatalogItem() {
+               CatalogItemsActions.deleteSelectedCatalogItem();
+       },
+       onClickCreateCatalogItem(type) {
+               CatalogItemsActions.createCatalogItem(type);
+       },
+       onClickDuplicateCatalogItem() {
+               CatalogItemsActions.duplicateSelectedCatalogItem();
+       },
+       onClickExportCatalogItems() {
+               CatalogPanelTrayActions.open();
+               CatalogItemsActions.exportSelectedCatalogItems();
+       }
+});
+
+export default CatalogHeader;
diff --git a/skyquake/plugins/composer/src/src/components/CatalogPanelTray.js b/skyquake/plugins/composer/src/src/components/CatalogPanelTray.js
new file mode 100644 (file)
index 0000000..4e4356e
--- /dev/null
@@ -0,0 +1,72 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react';
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'
+
+import '../styles/CatalogPanelTray.scss'
+
+const CatalogPanelTray = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {
+                       isDragging: false
+               };
+       },
+       getDefaultProps() {
+               return {show: false};
+       },
+       preventResizeCursor(e) {
+               e.stopPropagation();
+               document.body.style.cursor = '';
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+       },
+       onDragOver() {
+               this.setState({isDragging: true});
+       },
+       onDragLeave() {
+               this.setState({isDragging: false});
+       },
+       render() {
+               const classNames = ClassNames('CatalogPanelTray', {
+                       '-close': !this.props.show,
+                       '-is-dragging': this.state.isDragging
+               });
+               return (
+                       <div className={classNames} onMouseMove={this.preventResizeCursor} onDragOver={this.onDragOver} onDragLeave={this.onDragLeave}>
+                               <h1 data-open-close-icon={this.props.show ? 'open' : 'closed'} onClick={CatalogPanelTrayActions.toggleOpenClose}>Catalog Package Manager</h1>
+                               <div className="tray-body">
+                                       {this.props.children}
+                               </div>
+                       </div>
+               );
+       }
+});
+
+export default CatalogPanelTray;
diff --git a/skyquake/plugins/composer/src/src/components/ComposerApp.js b/skyquake/plugins/composer/src/src/components/ComposerApp.js
new file mode 100644 (file)
index 0000000..9e6daa4
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+window['RIFT_wareLaunchpadComposerVersion'] = `semver 0.0.79`;
+
+import 'es5-shim'
+import 'babel-polyfill'
+import alt from '../alt'
+import UID from '../libraries/UniqueId'
+import utils from '../libraries/utils'
+import React from 'react'
+import ReactDOM from 'react-dom'
+import Crouton from 'react-crouton'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import DeletionManager from '../libraries/DeletionManager'
+import SelectionManager from '../libraries/SelectionManager'
+import ResizableManager from '../libraries/ResizableManager'
+import DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'
+import DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'
+import RiftHeader from './RiftHeader'
+import CanvasPanel from './CanvasPanel'
+import CatalogPanel from './CatalogPanel'
+import DetailsPanel from './DetailsPanel'
+import ModalOverlay from './ModalOverlay'
+import ComposerAppToolbar from './ComposerAppToolbar'
+import PanelResizeAction from '../actions/PanelResizeAction'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import ComposerAppStore from '../stores/ComposerAppStore'
+import CatalogDataStore from '../stores/CatalogDataStore'
+import TooltipManager from '../libraries/TooltipManager'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import CommonUtils from 'utils/utils.js'
+
+import 'normalize.css'
+import '../styles/AppRoot.scss'
+import 'style/layout.scss'
+
+const resizeManager = new ResizableManager(window);
+
+const clearLocalStorage = utils.getSearchParams(window.location).hasOwnProperty('clearLocalStorage');
+
+const preventDefault = e => e.preventDefault();
+const clearDragState = () => ComposerAppActions.setDragState(null);
+
+const ComposerApp = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return ComposerAppStore.getState();
+       },
+       getDefaultProps() {
+               return {};
+       },
+       componentWillMount() {
+               if (clearLocalStorage) {
+                       window.localStorage.clear();
+               }
+               this.state.isLoading = CatalogDataStore.getState().isLoading;
+               ComposerAppStore.listen(this.onChange);
+               CatalogDataStore.listen(this.onCatalogDataChanged);
+               window.addEventListener('resize', this.resize);
+               window.onbeforeunload = this.onBeforeUnload;
+               // prevent browser from downloading any drop outside of our specific drop zones
+               window.addEventListener('dragover', preventDefault);
+               window.addEventListener('drop', preventDefault);
+               // ensure drags initiated in the app clear the state on drop
+               window.addEventListener('drop', clearDragState);
+               DeletionManager.addEventListeners();
+       },
+       componentWillUnmount() {
+               window.removeEventListener('resize', this.resize);
+               window.removeEventListener('dragover', preventDefault);
+               window.removeEventListener('drop', preventDefault);
+               window.removeEventListener('drop', clearDragState);
+               // resizeManager automatically registered its event handlers
+               resizeManager.removeAllEventListeners();
+               ComposerAppStore.unlisten(this.onChange);
+               CatalogDataStore.unlisten(this.onCatalogDataChanged);
+               DeletionManager.removeEventListeners();
+               TooltipManager.removeEventListeners();
+       },
+       componentDidMount() {
+               resizeManager.addAllEventListeners();
+               const snapshot = window.localStorage.getItem('composer');
+               if (snapshot) {
+                       alt.bootstrap(snapshot);
+               }
+               document.body.addEventListener('keydown', (event) => {
+                       // prevent details editor form from blowing up the app
+                       const ENTER_KEY = 13;
+                       if (event.which === ENTER_KEY) {
+                               event.preventDefault();
+                               return false;
+                       }
+               });
+               const appRootElement = ReactDOM.findDOMNode(this.refs.appRoot);
+               TooltipManager.addEventListeners(appRootElement);
+               SelectionManager.onClearSelection = () => {
+                       if (this.state.item) {
+                               CatalogItemsActions.catalogItemMetaDataChanged.defer(this.state.item);
+                       }
+               };
+       },
+       componentDidUpdate() {
+               if (this.state.fullScreenMode) {
+                       document.body.classList.add('-is-full-screen');
+               } else {
+                       document.body.classList.remove('-is-full-screen');
+               }
+               SelectionManager.refreshOutline();
+       },
+       resize(e) {
+               PanelResizeAction.resize(e);
+       },
+       getModel() {
+               let html;
+               let self = this;
+               DescriptorModelMetaFactory.init().then(function(){
+
+                       self.setState({
+                               hasModel: true
+                       })
+               });
+       },
+       render() {
+               let html = null;
+               let self = this;
+               if(this.state.hasModel) {
+
+                       function onClickUpdateSelection(event) {
+                               if (event.defaultPrevented) {
+                                       return
+                               }
+                               const element = SelectionManager.getClosestElementWithUID(event.target);
+                               if (element) {
+                                       SelectionManager.select(element);
+                                       SelectionManager.refreshOutline();
+                                       event.preventDefault();
+                               } else {
+                                       SelectionManager.clearSelectionAndRemoveOutline();
+                               }
+                       }
+
+                       let cpNumber = 0;
+                       let AppHeader = (<div className="AppHeader">
+                                                               <RiftHeader />
+                                                       </div>);
+                       // AppHeader = null;
+                       const classNames = ClassNames('ComposerApp');
+                       const isNew = self.state.item && self.state.item.uiState.isNew;
+                       const hasItem = self.state.item && self.state.item.uiState;
+                       const isModified = self.state.item && self.state.item.uiState.modified;
+                       const isEditingNSD = self.state.item && self.state.item.uiState && /nsd/.test(self.state.item.uiState.type);
+                       const isEditingVNFD = self.state.item && self.state.item.uiState && /vnfd/.test(self.state.item.uiState.type);
+                       const containers = [self.state.item].reduce(DescriptorModelFactory.buildCatalogItemFactory(CatalogDataStore.getState().catalogs), []);
+
+                       containers.filter(d => DescriptorModelFactory.isConnectionPoint(d)).forEach(d => {
+                               d.cpNumber = ++cpNumber;
+                               containers.filter(d => DescriptorModelFactory.isVnfdConnectionPointRef(d)).filter(ref => ref.key === d.key).forEach(ref => ref.cpNumber = d.cpNumber);
+                       });
+                       const canvasTitle = containers.length ? containers[0].model.name : '';
+                       const hasNoCatalogs = CatalogDataStore.getState().catalogs.length === 0;
+                       const isLoading = self.state.isLoading;
+
+                       html = (
+                               <div ref="appRoot" id="RIFT_wareLaunchpadComposerAppRoot" className="AppRoot" onClick={onClickUpdateSelection}>
+                                       <i className="corner-accent top left" />
+                                       <i className="corner-accent top right" />
+                                       <i className="corner-accent bottom left" />
+                                       <i className="corner-accent bottom right" />
+                                       {AppHeader}
+                                       <Crouton id={Date.now()} type={self.state.messageType} message={self.state.message} onDismiss={ComposerAppActions.clearError} />
+                                       <div className="AppBody">
+                                               <div className={classNames}>
+                                                       <CatalogPanel layout={self.state.layout}
+                                                                                 isLoading={isLoading}
+                                                                                 hasNoCatalogs={hasNoCatalogs}
+                                                                                 filterByType={self.state.filterCatalogByTypeValue} />
+                                                       <CanvasPanel layout={self.state.layout}
+                                                                                hasNoCatalogs={hasNoCatalogs}
+                                                                                showMore={self.state.showMore}
+                                                                                containers={containers}
+                                                                                title={canvasTitle}
+                                                                                zoom={self.state.zoom} />
+                                                       <DetailsPanel layout={self.state.layout}
+                                                                                 hasNoCatalogs={hasNoCatalogs}
+                                                                                 showMore={self.state.showMore}
+                                                                                 containers={containers}
+                                                                                 showJSONViewer={self.state.showJSONViewer} />
+                                                       <ComposerAppToolbar layout={self.state.layout}
+                                                                                               showMore={self.state.showMore}
+                                                                                               isEditingNSD={isEditingNSD}
+                                                                                               isEditingVNFD={isEditingVNFD}
+                                                                                               isModified={isModified}
+                                                                                               isNew={isNew}
+                                                                                               disabled={!hasItem}
+                                                                                               onClick={event => event.stopPropagation()}/>
+                                               </div>
+                                       </div>
+                                       <ModalOverlay />
+                               </div>
+                       );
+               } else {
+                       this.getModel();
+               }
+               return html;
+       },
+       onChange(state) {
+               this.setState(state);
+       },
+       onCatalogDataChanged(catalogDataState) {
+               const catalogs = catalogDataState.catalogs;
+               const unsavedChanges = catalogs.reduce((result, catalog) => {
+                       if (result) {
+                               return result;
+                       }
+                       return catalog.descriptors.reduce((result, descriptor) => {
+                               if (result) {
+                                       return result;
+                               }
+                               return descriptor.uiState.modified;
+                       }, false);
+               }, false);
+               this.setState({
+                       unsavedChanges: unsavedChanges,
+                       isLoading: catalogDataState.isLoading
+               });
+       },
+       onBeforeUnload() {
+               // https://trello.com/c/c8v321Xx/160-prompt-user-to-save-changes
+               //const snapshot = alt.takeSnapshot();
+               //window.localStorage.setItem('composer', snapshot);
+               if (this.state.unsavedChanges) {
+                       return 'You have unsaved changes. If you do not onboard (or update) your changes they will be lost.';
+               }
+       }
+
+});
+
+export default ComposerApp;
diff --git a/skyquake/plugins/composer/src/src/components/ComposerAppToolbar.js b/skyquake/plugins/composer/src/src/components/ComposerAppToolbar.js
new file mode 100644 (file)
index 0000000..8515182
--- /dev/null
@@ -0,0 +1,186 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import React from 'react'
+import messages from './messages'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import Button from './Button'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import CanvasEditorActions from '../actions/CanvasEditorActions'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import SelectionManager from '../libraries/SelectionManager'
+import DeletionManager from '../libraries/DeletionManager'
+
+import '../styles/ComposerAppToolbar.scss'
+
+import imgSave from '../../../node_modules/open-iconic/svg/data-transfer-upload.svg'
+import imgCancel from '../../../node_modules/open-iconic/svg/circle-x.svg'
+import imgLayout from '../../../node_modules/open-iconic/svg/grid-three-up.svg'
+import imgVLD from '../../../node_modules/open-iconic/svg/link-intact.svg'
+import imgJSONViewer from '../../../node_modules/open-iconic/svg/code.svg'
+import imgFG from '../../../node_modules/open-iconic/svg/infinity.svg'
+import imgDelete from '../../../node_modules/open-iconic/svg/trash.svg'
+import imgVDU from '../../../node_modules/open-iconic/svg/laptop.svg'
+
+const ComposerAppToolbar = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {};
+       },
+       getDefaultProps() {
+               return {
+                       disabled: true,
+                       showMore: false,
+                       layout: {left: 300},
+                       isModified: false,
+                       isEditingNSD: false,
+                       isEditingVNFD: false,
+                       showJSONViewer: false,
+                       isNew: false
+               };
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+       },
+       onClickSave(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CatalogItemsActions.saveCatalogItem();
+       },
+       onClickCancel(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CatalogItemsActions.cancelCatalogItemChanges();
+       },
+       onClickToggleShowMoreInfo(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CanvasEditorActions.toggleShowMoreInfo();
+       },
+       onClickAutoLayout(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CanvasEditorActions.applyDefaultLayout();
+       },
+       onClickAddVld(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CanvasEditorActions.addVirtualLinkDescriptor();
+       },
+       onClickAddVnffg(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CanvasEditorActions.addForwardingGraphDescriptor();
+       },
+       onClickAddVdu(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               CanvasEditorActions.addVirtualDeploymentDescriptor();
+       },
+       onDragStartAddVdu(event) {
+               const data = {type: 'action', action: 'add-vdu'};
+               event.dataTransfer.effectAllowed = 'copy';
+               event.dataTransfer.setData('text', JSON.stringify(data));
+               ComposerAppActions.setDragState(data);
+       },
+       onDragStartAddVld(event) {
+               const data = {type: 'action', action: 'add-vld'};
+               event.dataTransfer.effectAllowed = 'copy';
+               event.dataTransfer.setData('text', JSON.stringify(data));
+               ComposerAppActions.setDragState(data);
+       },
+       onDragStartAddVnffg(event) {
+               const data = {type: 'action', action: 'add-vnffgd'};
+               event.dataTransfer.effectAllowed = 'copy';
+               event.dataTransfer.setData('text', JSON.stringify(data));
+               ComposerAppActions.setDragState(data);
+       },
+       onClickDeleteSelected(event) {
+               event.preventDefault();
+               event.stopPropagation();
+               DeletionManager.deleteSelected(event);
+       },
+       toggleJSONViewer(event) {
+               event.preventDefault();
+               if (this.props.showJSONViewer) {
+                       ComposerAppActions.closeJsonViewer();
+               } else {
+                       ComposerAppActions.closeJsonViewer();
+                       ComposerAppActions.showJsonViewer.defer();
+               }
+       },
+       render() {
+               const style = {left: this.props.layout.left};
+               const saveClasses = ClassNames('ComposerAppSave', {'primary-action': this.props.isModified || this.props.isNew});
+               const cancelClasses = ClassNames('ComposerAppCancel', {'secondary-action': this.props.isModified});
+               if (this.props.disabled) {
+                       return (
+                               <div className="ComposerAppToolbar" style={style}></div>
+                       );
+               }
+               const hasSelection = SelectionManager.getSelections().length > 0;
+               return (
+                       <div className="ComposerAppToolbar" style={style}>
+                               {(()=>{
+                                       if (this.props.isEditingNSD || this.props.isEditingVNFD) {
+                                               return (
+                                                       <div className="FileActions">
+                                                               <Button className={saveClasses} onClick={this.onClickSave} label={messages.getSaveActionLabel(this.props.isNew)} src={imgSave} />
+                                                               <Button className={cancelClasses} onClick={this.onClickCancel} label="Cancel" src={imgCancel} />
+                                                               <Button className="ComposerAppToggleJSONViewerAction" onClick={this.toggleJSONViewer} label="YAML Viewer" src={imgJSONViewer} />
+                                                       </div>
+                                               );
+                                       }
+                               })()}
+                               <div className="LayoutActions">
+                                       <Button className="action-auto-layout" onClick={this.onClickAutoLayout} label="Auto Layout" src={imgLayout} />
+                                       {this.props.isEditingNSD ||
+                                               this.props.isEditingVNFD ? <Button className="action-add-vld"
+                                                                                                                  draggable="true"
+                                                                                                                  label={this.props.isEditingNSD ? 'Add VLD' : 'Add IVLD'}
+                                                                                                                  src={imgVLD}
+                                                                                                                  onDragStart={this.onDragStartAddVld}
+                                                                                                                  onClick={this.onClickAddVld} /> : null}
+                                       {this.props.isEditingNSD ? <Button className="action-add-vnffg"
+                                                                                                          draggable="true"
+                                                                                                          label="Add VNFFG"
+                                                                                                          src={imgFG}
+                                                                                                          onDragStart={this.onDragStartAddVnffg}
+                                                                                                          onClick={this.onClickAddVnffg} /> : null}
+                                       {this.props.isEditingVNFD ? <Button className="action-add-vdu"
+                                                                                                               draggable="true"
+                                                                                                               label="Add VDU"
+                                                                                                               src={imgVDU}
+                                                                                                               onDragStart={this.onDragStartAddVdu}
+                                                                                                               onClick={this.onClickAddVdu} /> : null}
+                                       <Button type="image" title="Delete selected items" className="action-delete-selected-items" disabled={!hasSelection} onClick = {this.onClickDeleteSelected} src={imgDelete} label="Delete" />
+                               </div>
+                       </div>
+               );
+       }
+});
+
+export default ComposerAppToolbar;
diff --git a/skyquake/plugins/composer/src/src/components/ContentEditableDiv.js b/skyquake/plugins/composer/src/src/components/ContentEditableDiv.js
new file mode 100644 (file)
index 0000000..7a540a8
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * Created by onvelocity on 2/13/16.
+ */
+'use strict';
+import React from 'react'
+import ClassNames from 'classnames'
+export default function ContentEditableDiv (props) {
+
+       const fontWidth = parseFloat(props.fontWidth) || 15;
+       const size = props.autoPadRight ? Math.max(50, String(props.name).length * fontWidth) : 0;
+       const style = {borderColor: 'transparent', background: 'transparent'};
+       if (size) {
+               style.paddingRight = size;
+       }
+
+       return (
+               <div className={ClassNames('ContentEditableDiv', {'-is-disabled': props.disabled})}><input {...props} style={style} /></div>
+       );
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/components/DetailsPanel.js b/skyquake/plugins/composer/src/src/components/DetailsPanel.js
new file mode 100644 (file)
index 0000000..a20679f
--- /dev/null
@@ -0,0 +1,76 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import React from 'react';
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import messages from './messages'
+import serializers from '../libraries/model/DescriptorModelSerializer'
+import JSONViewer from 'widgets/JSONViewer/JSONViewer';
+import PopupWindow from './PopupWindow'
+import CatalogItemDetailsEditor from './CatalogItemDetailsEditor'
+import SelectionManager from '../libraries/SelectionManager'
+
+import '../styles/DetailsPanel.scss'
+
+const DetailsPanel = React.createClass({
+       mixins: [PureRenderMixin, SelectionManager.reactPauseResumeMixin],
+       getInitialState() {
+               return {};
+       },
+       getDefaultProps() {
+               return {
+                       containers: [],
+                       showJSONViewer: false
+               };
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+               SelectionManager.refreshOutline();
+       },
+       componentWillUnmount() {
+       },
+       render() {
+               let json = '{}';
+               let bodyComponent =  messages.detailsWelcome();
+               const selected = this.props.containers.filter(d => SelectionManager.isSelected(d));
+               const selectedContainer = selected[0];
+               if (selectedContainer) {
+                       bodyComponent = <CatalogItemDetailsEditor container={selectedContainer} width={this.props.layout.right} />;
+                       const edit = _.cloneDeep(selectedContainer.model);
+                       json = serializers.serialize(edit) || edit;
+               }
+               const jsonViewerTitle = selectedContainer ? selectedContainer.model.name : 'nothing selected';
+               const hasNoCatalogs = this.props.hasNoCatalogs;
+               return (
+                       <div className="DetailsPanel" data-resizable="left" data-resizable-handle-offset="0 5" style={{width: this.props.layout.right}} onClick={event => event.preventDefault()}>
+                               <div className="DetailsPanelBody">
+                                       {hasNoCatalogs ? null : bodyComponent}
+                               </div>
+                               <PopupWindow show={this.props.showJSONViewer} title={jsonViewerTitle}><JSONViewer json={json}/></PopupWindow>
+                       </div>
+               );
+       }
+});
+
+export default DetailsPanel;
diff --git a/skyquake/plugins/composer/src/src/components/DropTarget.js b/skyquake/plugins/composer/src/src/components/DropTarget.js
new file mode 100644 (file)
index 0000000..3f17b30
--- /dev/null
@@ -0,0 +1,82 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/6/15.
+ */
+'use strict';
+
+import React from 'react'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import ClassNames from 'classnames'
+
+const DropTarget = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {isDragHover: false};
+       },
+       getDefaultProps() {
+               return {onDrop: () => {}, dropZone: null, className: 'DropTarget'};
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+               if (this.props.dropZone) {
+                       const dropTarget = this;
+                       const dropZone = this.props.dropZone(dropTarget);
+                       dropZone.on('dragover', this.onDragOver);
+                       dropZone.on('dragleave', this.onDragLeave);
+                       dropZone.on('dragend', this.onDragEnd);
+                       dropZone.on('drop', this.onDrop);
+               }
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+       },
+       render() {
+               const classNames = ClassNames(this.props.className, 'dnd-target', {'-drag-hover': this.state.isDragHover});
+               return (
+                               <div className={classNames}
+                                        onDrop={this.onDrop}
+                                        onDragEnd={this.onDragEnd}
+                                        onMouseOut={this.onDragEnd}
+                                        onDragExit={this.onDragEnd}
+                                        onDragOver={this.onDragOver}
+                                        onDragLeave={this.onDragLeave}>{this.props.children}</div>
+               );
+       },
+       onDragOver(e) {
+               // NOTE calling preventDefault makes this a valid drop target
+               e.preventDefault();
+               e.dataTransfer.dropEffect = 'copy';
+               this.setState({isDragHover: true});
+       },
+       onDragLeave() {
+               this.setState({isDragHover: false});
+       },
+       onDragEnd() {
+               this.setState({isDragHover: false});
+       },
+       onDrop(e) {
+               this.setState({isDragHover: false});
+               this.props.onDrop(e);
+       }
+});
+
+export default DropTarget;
diff --git a/skyquake/plugins/composer/src/src/components/DropZonePanel.js b/skyquake/plugins/composer/src/src/components/DropZonePanel.js
new file mode 100644 (file)
index 0000000..210f2ba
--- /dev/null
@@ -0,0 +1,59 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/6/15.
+ */
+'use strict';
+
+import React from 'react'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import ClassNames from 'classnames'
+
+import '../styles/DropZonePanel.scss'
+
+const DropZonePanel = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return {};
+       },
+       getDefaultProps() {
+               return {show: false, className: 'DropZonePanel', title: 'Drop files to upload.'};
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+       },
+       render() {
+               const classNames = ClassNames(this.props.className, {'-close': !this.props.show});
+               return (
+                       <div className={classNames}>
+                               <div className="dz-default dz-message">
+                                       <span>{this.props.title}</span>
+                               </div>
+                               {this.props.children}
+                       </div>
+               );
+       }
+});
+
+export default DropZonePanel;
diff --git a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
new file mode 100644 (file)
index 0000000..36e7445
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 1/18/16.
+ *
+ * This class generates the form fields used to edit the CONFD JSON model.
+ */
+'use strict';
+
+import _ from 'lodash'
+import utils from '../libraries/utils'
+import React from 'react'
+import ClassNames from 'classnames'
+import changeCase from 'change-case'
+import toggle from '../libraries/ToggleElementHandler'
+import Button from './Button'
+import Property from '../libraries/model/DescriptorModelMetaProperty'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import DESCRIPTOR_MODEL_FIELDS from '../libraries/model/DescriptorModelFields'
+import DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'
+import SelectionManager from '../libraries/SelectionManager'
+import DeletionManager from '../libraries/DeletionManager'
+import DescriptorModelIconFactory from '../libraries/model/IconFactory'
+import getEventPath from '../libraries/getEventPath'
+
+import imgAdd from '../../../node_modules/open-iconic/svg/plus.svg'
+import imgRemove from '../../../node_modules/open-iconic/svg/trash.svg'
+
+import '../styles/EditDescriptorModelProperties.scss'
+
+function getDescriptorMetaBasicForType(type) {
+       const basicPropertiesFilter = d => _.contains(DESCRIPTOR_MODEL_FIELDS[type], d.name);
+       return DescriptorModelMetaFactory.getModelMetaForType(type, basicPropertiesFilter) || {properties: []};
+}
+
+function getDescriptorMetaAdvancedForType(type) {
+       const advPropertiesFilter = d => !_.contains(DESCRIPTOR_MODEL_FIELDS[type], d.name);
+       return DescriptorModelMetaFactory.getModelMetaForType(type, advPropertiesFilter) || {properties: []};
+}
+
+function getTitle(model = {}) {
+       if (typeof model['short-name'] === 'string' && model['short-name']) {
+               return model['short-name'];
+       }
+       if (typeof model.name === 'string' && model.name) {
+               return model.name;
+       }
+       if (model.uiState && typeof model.uiState.displayName === 'string' && model.uiState.displayName) {
+               return model.uiState.displayName
+       }
+       if (typeof model.id === 'string') {
+               return model.id;
+       }
+}
+
+export default function EditDescriptorModelProperties(props) {
+
+       const container = props.container;
+
+       if (!(DescriptorModelFactory.isContainer(container))) {
+               return
+       }
+
+       function startEditing() {
+               DeletionManager.removeEventListeners();
+       }
+
+       function endEditing() {
+               DeletionManager.addEventListeners();
+       }
+
+       function onClickSelectItem(property, path, value, event) {
+               event.preventDefault();
+               const root = this.getRoot();
+               if (SelectionManager.select(value)) {
+                       CatalogItemsActions.catalogItemMetaDataChanged(root.model);
+               }
+       }
+
+       function onFocusPropertyFormInputElement(property, path, value, event) {
+
+               event.preventDefault();
+               startEditing();
+
+               function removeIsFocusedClass(event) {
+                       event.target.removeEventListener('blur', removeIsFocusedClass);
+                       Array.from(document.querySelectorAll('.-is-focused')).forEach(d => d.classList.remove('-is-focused'));
+               }
+
+               removeIsFocusedClass(event);
+
+               const propertyWrapper = getEventPath(event).reduce((parent, element) => {
+                       if (parent) {
+                               return parent;
+                       }
+                       if (!element.classList) {
+                               return false;
+                       }
+                       if (element.classList.contains('property')) {
+                               return element;
+                       }
+               }, false);
+
+               if (propertyWrapper) {
+                       propertyWrapper.classList.add('-is-focused');
+                       event.target.addEventListener('blur', removeIsFocusedClass);
+               }
+
+       }
+
+       function buildAddPropertyAction(container, property, path) {
+               function onClickAddProperty(property, path, event) {
+                       event.preventDefault();
+                       //SelectionManager.resume();
+                       const create = Property.getContainerCreateMethod(property, this);
+                       if (create) {
+                               const model = null;
+                               create(model, path, property);
+                       } else {
+                               const name = path.join('.');
+                               const value = Property.createModelInstance(property);
+                               utils.assignPathValue(this.model, name, value);
+                       }
+                       CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+               }
+               return (
+                               <Button className="inline-hint" onClick={onClickAddProperty.bind(container, property, path)} label="Add" src={imgAdd} />
+               );
+       }
+
+       function buildRemovePropertyAction(container, property, path) {
+               function onClickRemoveProperty(property, path, event) {
+                       event.preventDefault();
+                       const name = path.join('.');
+                       const removeMethod = Property.getContainerMethod(property, this, 'remove');
+                       if (removeMethod) {
+                               removeMethod(utils.resolvePath(this.model, name));
+                       } else {
+                               utils.removePathValue(this.model, name);
+                       }
+                       CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+               }
+               return (
+                       <Button className="remove-property-action inline-hint" title="Remove" onClick={onClickRemoveProperty.bind(container, property, path)} label="Remove" src={imgRemove}/>
+               );
+       }
+
+       function onFormFieldValueChanged(event) {
+               if (DescriptorModelFactory.isContainer(this)) {
+                       event.preventDefault();
+                       const name = event.target.name;
+                       const value = event.target.value;
+                       utils.assignPathValue(this.model, name, value);
+                       CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+               }
+       }
+
+       function buildField(container, property, path, value, fieldKey) {
+
+               const name = path.join('.');
+               const isEditable = true;
+               const isGuid = Property.isGuid(property);
+               const onChange = onFormFieldValueChanged.bind(container);
+               const isEnumeration = Property.isEnumeration(property);
+               const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
+               const placeholder = changeCase.title(property.name);
+               const className = ClassNames(property.name + '-input', {'-is-guid': isGuid});
+               if (isEnumeration) {
+                       const enumeration = Property.getEnumeration(property, value);
+                       const options = enumeration.map((d, i) => {
+                               // note yangforge generates values for enums but the system does not use them
+                               // so we categorically ignore them
+                               // https://trello.com/c/uzEwVx6W/230-bug-enum-should-not-use-index-only-name
+                               //return <option key={fieldKey + ':' + i} value={d.value}>{d.name}</option>;
+                               return <option key={fieldKey.toString() + ':' + i} value={d.name}>{d.name}</option>;
+                       });
+                       const isValueSet = enumeration.filter(d => d.isSelected).length > 0;
+                       if (!isValueSet || property.cardinality === '0..1') {
+                               const noValueDisplayText = changeCase.title(property.name);
+                               options.unshift(<option key={'(value-not-in-enum)' + fieldKey.toString()} value="" placeholder={placeholder}>{noValueDisplayText}</option>);
+                       }
+                       return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} readOnly={!isEditable}>{options}</select>;
+               }
+
+               if (property['preserve-line-breaks']) {
+                       return <textarea key={fieldKey.toString()} cols="5" id={fieldKey.toString()} name={name} value={value} placeholder={placeholder} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!isEditable} />;
+               }
+
+               return <input key={fieldKey.toString()}
+                                         id={fieldKey.toString()}
+                                         type="text"
+                                         name={name}
+                                         value={value}
+                                         className={className}
+                                         placeholder={placeholder}
+                                         onChange={onChange}
+                                         onFocus={onFocus}
+                                         onBlur={endEditing}
+                                         onMouseDown={startEditing}
+                                         onMouseOver={startEditing}
+                                         onMouseOut={endEditing}
+                                         onMouseLeave={endEditing}
+                                         readOnly={!isEditable}
+               />;
+
+       }
+
+       function buildElement(container, property, valuePath, value) {
+               return property.properties.map((property, index) => {
+                       let childValue;
+                       const childPath = valuePath.slice();
+                       if (typeof value === 'object') {
+                               childValue = value[property.name];
+                       }
+                       childPath.push(property.name);
+
+                       return build(container, property, childPath, childValue);
+
+               });
+       }
+
+       function buildChoice(container, property, path, value, key) {
+
+               function onFormFieldValueChanged(event) {
+                       if (DescriptorModelFactory.isContainer(this)) {
+
+                               event.preventDefault();
+
+                               const name = event.target.name;
+                               const value = event.target.value;
+
+                               /*
+                                       Transient State is stored for convenience in the uiState field.
+                                       The choice yang type uses case elements to describe the "options".
+                                       A choice can only ever have one option selected which allows
+                                       the system to determine which type is selected by the name of
+                                       the element contained within the field.
+                                */
+
+                               //const stateExample = {
+                               //      uiState: {
+                               //              choice: {
+                               //                      'conf-config': {
+                               //                              selected: 'rest',
+                               //                              'case': {
+                               //                                      rest: {},
+                               //                                      netconf: {},
+                               //                                      script: {}
+                               //                              }
+                               //                      }
+                               //              }
+                               //      }
+                               //};
+
+                               const statePath = ['uiState.choice'].concat(name);
+                               const stateObject = utils.resolvePath(this.model, statePath.join('.')) || {};
+                               // write state back to the model so the new state objects are captured
+                               utils.assignPathValue(this.model, statePath.join('.'), stateObject);
+
+                               // write the current choice value into the state
+                               const choiceObject = utils.resolvePath(this.model, [name, stateObject.selected].join('.'));
+                               if (choiceObject) {
+                                       utils.assignPathValue(stateObject, ['case', stateObject.selected].join('.'), _.cloneDeep(choiceObject));
+                               }
+
+                               // remove the current choice value from the model
+                               utils.removePathValue(this.model, [name, stateObject.selected].join('.'));
+
+                               // get any state for the new selected choice
+                               const newChoiceObject = utils.resolvePath(stateObject, ['case', value].join('.')) || {};
+
+                               // assign new choice value to the model
+                               utils.assignPathValue(this.model, [name, value].join('.'), newChoiceObject);
+
+                               // update the selected name
+                               utils.assignPathValue(this.model, statePath.concat('selected').join('.'), value);
+
+                               CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+                       }
+               }
+
+               const caseByNameMap = {};
+
+               const onChange = onFormFieldValueChanged.bind(container);
+
+               const cases = property.properties.map(d => {
+                       if (d.type === 'case') {
+                               caseByNameMap[d.name] = d.properties[0];
+                               return {optionName: d.name, optionTitle: d.description};
+                       }
+                       caseByNameMap[d.name] = d;
+                       return {optionName: d.name};
+               });
+
+               const options = [{optionName: ''}].concat(cases).map((d, i) => {
+                       return (
+                               <option key={i} value={d.optionName} title={d.optionTitle}>
+                                       {d.optionName}
+                                       {i ? null : changeCase.title(property.name)}
+                               </option>
+                       );
+               });
+
+               const selectName = path.join('.');
+               const selectedOptionPath = ['uiState.choice', selectName, 'selected'].join('.');
+               const selectedOptionValue = utils.resolvePath(container.model, selectedOptionPath);
+               const valueProperty = caseByNameMap[selectedOptionValue] || {properties: []};
+
+               const valueResponse = valueProperty.properties.map((d, i) => {
+                       const childPath = path.concat(valueProperty.name, d.name);
+                       const childValue = utils.resolvePath(container.model, childPath.join('.'));
+                       return (
+                               <div key={childPath.concat('info', i).join(':')}>
+                                       {build(container, d, childPath, childValue, props)}
+                               </div>
+                       );
+               });
+
+               const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
+
+               return (
+                       <div key={key} className="choice">
+                               <select key={Date.now()} className={ClassNames({'-value-not-set': !selectedOptionValue})} name={selectName} value={selectedOptionValue} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing}>
+                                       {options}
+                               </select>
+                               {valueResponse}
+                       </div>
+               );
+
+       }
+
+       function buildSimpleListItem(container, property, path, value, key, index) {
+               // todo need to abstract this better
+               const title = getTitle(value);
+               var req = require.context("../", true, /\.svg/);
+               return (
+                       <div>
+                               <a href="#select-list-item" key={Date.now()} className={property.name + '-list-item simple-list-item '} onClick={onClickSelectItem.bind(container, property, path, value)}>
+                                       <img src={req('./' + DescriptorModelIconFactory.getUrlForType(property.name))} width="20px" />
+                                       <span>{title}</span>
+                               </a>
+                               {buildRemovePropertyAction(container, property, path)}
+                       </div>
+               );
+       }
+
+       function buildRemoveListItem(container, property, valuePath, fieldKey, index) {
+               const className = ClassNames(property.name + '-remove actions');
+               return (
+                       <div key={fieldKey.concat(index).join(':')} className={className}>
+                               <h3>
+                                       <span className={property.type + '-name name'}>{changeCase.title(property.name)}</span>
+                                       <span className="info">{index + 1}</span>
+                                       {buildRemovePropertyAction(container, property, valuePath)}
+                               </h3>
+                       </div>
+               );
+       }
+
+       function buildLeafListItem(container, property, valuePath, value, key, index) {
+               // look at the type to determine how to parse the value
+               return (
+                       <div>
+                               {buildRemoveListItem(container, property, valuePath, key, index)}
+                               {buildField(container, property, valuePath, value, key)}
+                       </div>
+
+               );
+       }
+
+       function build(container, property, path, value, props = {}) {
+
+               const fields = [];
+               const isLeaf = Property.isLeaf(property);
+               const isArray = Property.isArray(property);
+               const isObject = Property.isObject(property);
+               const isLeafList = Property.isLeafList(property);
+               const fieldKey = [container.id].concat(path);
+               const isRequired = Property.isRequired(property);
+               const title = changeCase.titleCase(property.name);
+               const columnCount = property.properties.length || 1;
+               const isColumnar = isArray && (Math.round(props.width / columnCount) > 155);
+               const classNames = {'-is-required': isRequired, '-is-columnar': isColumnar};
+
+               if (!property.properties && isObject) {
+                       const uiState = DescriptorModelMetaFactory.getModelMetaForType(property.name) || {};
+                       property.properties = uiState.properties;
+               }
+
+               const hasProperties = _.isArray(property.properties) && property.properties.length;
+               const isMissingDescriptorMeta = !hasProperties && !Property.isLeaf(property);
+
+               // ensure value is not undefined for non-leaf property types
+               if (isObject) {
+                       if (typeof value !== 'object') {
+                               value = isArray ? [] : {};
+                       }
+               }
+               const valueAsArray = _.isArray(value) ? value : isLeafList && typeof value === 'undefined' ? [] : [value];
+
+               const isMetaField = property.name === 'meta';
+               const isCVNFD = property.name === 'constituent-vnfd';
+               const isSimpleListView = Property.isSimpleList(property);
+
+               valueAsArray.forEach((value, index) => {
+
+                       let field;
+                       const key = fieldKey.slice();
+                       const valuePath = path.slice();
+
+                       if (isArray) {
+                               valuePath.push(index);
+                               key.push(index);
+                       }
+
+                       if (isMetaField) {
+                               if (typeof value === 'object') {
+                                       value = JSON.stringify(value, undefined, 12);
+                               } else if (typeof value !== 'string') {
+                                       value = '{}';
+                               }
+                       }
+
+                       if (isMissingDescriptorMeta) {
+                               field = <span key={key.concat('warning').join(':')} className="warning">No Descriptor Meta for {property.name}</span>;
+                       } else if (property.type === 'choice') {
+                               field = buildChoice(container, property, valuePath, value, key.join(':'));
+                       } else if (isSimpleListView) {
+                               field = buildSimpleListItem(container, property, valuePath, value, key, index);
+                       } else if (isLeafList) {
+                               field = buildLeafListItem(container, property, valuePath, value, key, index);
+                       } else if (hasProperties) {
+                               field = buildElement(container, property, valuePath, value, key.join(':'))
+                       } else {
+                               field = buildField(container, property, valuePath, value, key.join(':'));
+                       }
+
+                       function onClickLeaf(property, path, value, event) {
+                               if (event.isDefaultPrevented()) {
+                                       return;
+                               }
+                               event.preventDefault();
+                               event.stopPropagation();
+                               this.getRoot().uiState.focusedPropertyPath = path.join('.');
+                               console.log('property selected', path.join('.'));
+                               ComposerAppActions.propertySelected([path.join('.')]);
+                       }
+
+                       const clickHandler = isLeaf ? onClickLeaf : () => {};
+                       const isContainerList = isArray && !(isSimpleListView || isLeafList);
+
+                       fields.push(
+                               <div key={fieldKey.concat(['property-content', index]).join(':')}
+                                        className={ClassNames('property-content', {'simple-list': isSimpleListView})}
+                                        onClick={clickHandler.bind(container, property, valuePath, value)}>
+                                       {isContainerList ? buildRemoveListItem(container, property, valuePath, fieldKey, index) : null}
+                                       {field}
+                               </div>
+                       );
+
+               });
+
+               classNames['-is-leaf'] = isLeaf;
+               classNames['-is-array'] = isArray;
+               classNames['cols-' + columnCount] = isColumnar;
+
+               if (property.type === 'choice') {
+                       value = utils.resolvePath(container.model, ['uiState.choice'].concat(path, 'selected').join('.'));
+               }
+
+               let displayValue = typeof value === 'object' ? '' : value;
+               const displayValueInfo = isArray ? valueAsArray.filter(d => typeof d !== 'undefined').length + ' items' : '';
+
+               const onFocus = isLeaf ? event => event.target.classList.add('-is-focused') : false;
+
+               return (
+                       <div key={fieldKey.join(':')} className={ClassNames(property.type + '-property property', classNames)} onFocus={onFocus}>
+                               <h3 className="property-label">
+                                       <label htmlFor={fieldKey.join(':')}>
+                                               <span className={property.type + '-name name'}>{title}</span>
+                                               <small>
+                                                       <span className={property.type + '-info info'}>{displayValueInfo}</span>
+                                                       <span className={property.type + '-value value'}>{displayValue}</span>
+                                               </small>
+                                               {isArray ? buildAddPropertyAction(container, property, path.concat(valueAsArray.length)) : null}
+                                       </label>
+                               </h3>
+                               <span className={property.type + '-description description'}>{property.description}</span>
+                               <val className="property-value">
+                                       {isCVNFD ? <span className={property.type + '-tip tip'}>Drag a VNFD from the Catalog to add more.</span> : null}
+                                       {fields}
+                               </val>
+                       </div>
+               );
+
+       }
+
+       const containerType = container.uiState['qualified-type'] || container.uiState.type;
+       const basicProperties = getDescriptorMetaBasicForType(containerType).properties;
+
+       function buildBasicGroup() {
+               if (basicProperties.length === 0) {
+                       return null;
+               }
+               return (
+                       <div className="basic-properties-group">
+                               <h2>Basic</h2>
+                               <div>
+                                       {basicProperties.map(property => {
+                                               const path = [property.name];
+                                               const value = container.model[property.name];
+                                               return build(container, property, path, value);
+                                       })}
+                               </div>
+                       </div>
+               );
+       }
+
+       function buildAdvancedGroup() {
+               const properties = getDescriptorMetaAdvancedForType(containerType).properties;
+               if (properties.length === 0) {
+                       return null;
+               }
+               const hasBasicFields = basicProperties.length > 0;
+               const closeGroup = basicProperties.length > 0;
+               return (
+                       <div className="advanced-properties-group">
+                               <h1 data-toggle={closeGroup ? 'true' : 'false'} className={ClassNames({'-is-toggled': closeGroup})} onClick={toggle} style={{display: hasBasicFields ? 'block' : 'none'}}>
+                                       <a className="toggle-show-more" href="#show-more-properties">more&hellip;</a>
+                                       <a className="toggle-show-less" href="#show-more-properties">less&hellip;</a>
+                               </h1>
+                               <div className="toggleable">
+                                       {properties.map(property => {
+                                               const path = [property.name];
+                                               const value = container.model[property.name];
+                                               return build(container, property, path, value, {toggle: true, width: props.width});
+                                       })}
+                               </div>
+                               <div className="toggle-bottom-spacer" style={{visibility: 'hidden', 'height': '50%', position: 'absolute'}}>We need this so when the user closes the panel it won't shift away and scare the bj out of them!</div>
+                       </div>
+               );
+       }
+
+       function buildMoreLess(d, i) {
+               return (
+                       <span key={'bread-crumb-part-' + i}>
+                               <a href="#select-item" onClick={onClickSelectItem.bind(d, null, null, d)}>{d.title}</a>
+                               <i> / </i>
+                       </span>
+               );
+       }
+
+       const path = [];
+       if (container.parent) {
+               path.push(container.parent);
+       }
+       path.push(container);
+
+       return (
+               <div className="EditDescriptorModelProperties -is-tree-view">
+                       <h1>{path.map(buildMoreLess)}</h1>
+                       {buildBasicGroup()}
+                       {buildAdvancedGroup()}
+               </div>
+       );
+
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/ConnectionPointSelector.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/ConnectionPointSelector.js
new file mode 100644 (file)
index 0000000..2c0877a
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * Created by onvelocity on 3/4/16.
+ */
+'use strict';
+import React from 'react'
+import ClassNames from 'classnames'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
+import onHoverHighlightConnectionPoint from './onHoverHighlightConnectionPoint'
+import '../../styles/ConnectionPointSelector.scss'
+export default function ConnectionPointSelector(props) {
+
+       const containers = props.containers || [];
+       const serviceChain = props.serviceChain || 'SF';
+       const connectionPointStyle = props.style || {};
+       const isDisabled = props.isDisabled;
+       const disabledMessage = props.disabledMessage || '';
+
+       // events
+       const onExitEditPathMode = props.onExitEditPathMode || (() => {});
+       const onAddConnectionPointRef = props.onAddConnectionPointRef || (() => {});
+
+       function mapConnectionPoint(connector) {
+               const cpNumber = connector.cpNumber;
+               return (
+                       <div key={connector.uid} className={ClassNames(connector.className, 'connection-point')} style={connectionPointStyle}
+                                onClick={onAddConnectionPointRef.bind(null, connector)}
+                                onMouseEnter={onHoverHighlightConnectionPoint.bind(null, cpNumber)}
+                                onMouseLeave={onHoverHighlightConnectionPoint.bind(null, cpNumber)}><small>cp{cpNumber}</small></div>
+               );
+       }
+
+       function mapConnectionPointsForConstituentVnfd(cvnfd, i) {
+               return (
+                       <div key={i} className={ClassNames(cvnfd.className, 'vnfd')}>
+                               <small className="vnfd-title">{cvnfd.title}</small>
+                               <div className="connectors">
+                                       {cvnfd.connectors.map(mapConnectionPoint)}
+                               </div>
+                       </div>
+               );
+       }
+
+       if (isDisabled) {
+               return (<div>{disabledMessage}</div>)
+       }
+
+       return (
+               <div className="ConnectionPointSelector selection">
+                       <div className="vnfd-list">
+                               {containers.filter(d => DescriptorModelFactory.isConstituentVnfdWithServiceChain(d, serviceChain)).map(mapConnectionPointsForConstituentVnfd)}
+                               <small className="Button"
+                                          onClick={onExitEditPathMode}>done
+                               </small>
+                       </div>
+               </div>
+       )
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/EditForwardingGraphPaths.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/EditForwardingGraphPaths.js
new file mode 100644 (file)
index 0000000..0f39d30
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 2/4/16.
+ */
+
+'use strict';
+
+import d3 from 'd3'
+import React from 'react'
+import Range from '../Range'
+import Button from '../Button'
+import ClassNames from 'classnames'
+import changeCase from 'change-case'
+import LayoutRow from '../LayoutRow'
+import SelectionManager from '../../libraries/SelectionManager'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import CanvasEditorActions from '../../actions/CanvasEditorActions'
+import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
+import ComposerAppActions from '../../actions/ComposerAppActions'
+import DescriptorModelMetaFactory from '../../libraries/model/DescriptorModelMetaFactory'
+import ComposerAppStore from '../../stores/ComposerAppStore'
+import DeletionManager from '../../libraries/DeletionManager'
+import ContentEditableDiv from '../ContentEditableDiv'
+import TooltipManager from '../../libraries/TooltipManager'
+import HighlightRecordServicePaths from '../../libraries/graph/HighlightRecordServicePaths'
+import mapClassifier from './mapClassifier'
+import mapRecordServicePath from './mapRecordServicePath'
+import onCutDelegateToRemove from './onCutDelegateToRemove'
+import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
+
+import '../../styles/EditForwardingGraphPaths.scss'
+
+import imgNSD from '../../images/default-catalog-icon.svg'
+import imgFG from '../../../../node_modules/open-iconic/svg/infinity.svg'
+import imgRemove from '../../../../node_modules/open-iconic/svg/trash.svg'
+import imgAdd from '../../../../node_modules/open-iconic/svg/plus.svg'
+import imgConnection from '../../../../node_modules/open-iconic/svg/random.svg'
+import imgClassifier from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
+import imgReorder from '../../../../node_modules/open-iconic/svg/menu.svg'
+
+function mapFG(fg, i) {
+
+       const context = this;
+       context.vnffg = fg;
+
+       const colors = fg.colors;
+       const stylePrimary = {borderColor: colors.primary};
+       const styleSecondary = {borderColor: colors.secondary};
+
+       context.stylePrimary = stylePrimary;
+       context.styleSecondary = styleSecondary;
+
+       const rspMap = fg.rsp.reduce((map, rsp) => {
+               map[rsp.id] = rsp;
+               rsp.classifier = [];
+               return map;
+       }, {});
+
+       fg.classifier.forEach(classifier => {
+               const rsp = rspMap[classifier.model['rsp-id-ref']];
+               if (rsp) {
+                       rsp.classifier.push(classifier);
+               }
+       });
+
+       function onClickRemoveForwardingGraph(fg, event) {
+               event.preventDefault();
+               const root = fg.getRoot();
+               fg.remove();
+               CatalogItemsActions.catalogItemDescriptorChanged(root);
+       }
+
+       function onClickAddClassifier(context, fg, event) {
+               event.preventDefault();
+               fg.createClassifier();
+               CatalogItemsActions.catalogItemDescriptorChanged(fg.getRoot());
+       }
+
+       function onClickToggleShowAllFGPaths(fg, event) {
+               //event.preventDefault();
+               event.stopPropagation();
+               fg.uiState.showPaths = event.target.checked;
+               fg.rsp.forEach(rsp => rsp.uiState.showPath = event.target.checked);
+               CatalogItemsActions.catalogItemMetaDataChanged(fg.getRoot().model);
+       }
+
+       if (!fg.uiState.hasOwnProperty('showPaths')) {
+               fg.uiState.showPaths = true;
+               fg.rsp.forEach(d => d.uiState.showPath = true);
+       }
+
+       const toggleSelectAllPaths = (
+               <input type="checkbox" name={'show-path' + fg.uid} checked={fg.uiState.showPaths} onChange={() => {}} onClick={onClickToggleShowAllFGPaths.bind(null, fg)} />
+       );
+
+       const srpFactory = DescriptorModelFactory.newRecordServicePathFactory({}, fg);
+       srpFactory.uid = fg.uid + i;
+
+       const hasServiceFunctionVNFDs = context.containers.filter(d => DescriptorModelFactory.isConstituentVnfdWithServiceChain(d, 'SF')).length > 0;
+
+       return (
+               <div key={i} className={fg.className} data-uid={fg.uid} data-offset-width="true" onClick={onClickSelectAndShowInDetailsPanel.bind(null, fg)} onCut={onCutDelegateToRemove.bind(null, fg)}>
+                       <div key="outline-indicator" data-outline-indicator="true"></div>
+                       <div className="header-actions">
+                               <Button className="remove-forwarding-graph" title="Remove" onClick={onClickRemoveForwardingGraph.bind(null, fg)} src={imgRemove}/>
+                       </div>
+                       <LayoutRow primaryActionColumn={toggleSelectAllPaths} secondaryActionColumn={<img className="fg-icon" src={imgFG} width="20px" />}>
+                               <small>{fg.title}</small>
+                       </LayoutRow>
+                       <div>
+                               <h4>Rendered Service Paths</h4>
+                               {hasServiceFunctionVNFDs ? fg.recordServicePaths.concat(srpFactory).map(mapRecordServicePath.bind(null, context)) : <small className="no-service-function-chain-msg hint">A VNFD with the chain SF is required to build Rendered Service Paths.</small>}
+                       </div>
+                       <div>
+                               <h4>Classifiers</h4>
+                               {fg.classifier.map(mapClassifier.bind(null, context))}
+                               <div className="footer-actions">
+                                       <div className="row-action-column">
+                                               <Button className="create-new-classifier" src={imgAdd} width="20px" onClick={onClickAddClassifier.bind(null, context, fg)} label="Add Classifier" />
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       );
+
+}
+
+function mapNSD(nsd, i) {
+
+       const context = this;
+       context.nsd = nsd;
+
+       function onClickAddForwardingGraph(nsd, event) {
+               event.preventDefault();
+               nsd.createVnffgd();
+               CatalogItemsActions.catalogItemDescriptorChanged(nsd.getRoot());
+       }
+
+       const forwardingGraphs = nsd.forwardingGraphs.map(mapFG.bind(context));
+       if (forwardingGraphs.length === 0) {
+               forwardingGraphs.push(
+                       <div key="1" className="welcome-message">
+                               No Forwarding Graphs to model.
+                       </div>
+               );
+       }
+
+       return (
+               <div key={i} className={nsd.className}>
+                       {forwardingGraphs}
+                       <div className="footer-actions">
+                               <div className="row-action-column">
+                                       <Button className="create-new-forwarding-graph" src={imgAdd} width="20px" onClick={onClickAddForwardingGraph.bind(null, nsd)} label="Add new Forwarding Graph" />
+                               </div>
+                       </div>
+               </div>
+       );
+
+}
+
+const EditForwardingGraphPaths = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState: function () {
+               return ComposerAppStore.getState();
+       },
+       getDefaultProps: function () {
+               return {
+                       containers: []
+               };
+       },
+       componentWillMount: function () {
+       },
+       componentDidMount: function () {
+       },
+       componentDidUpdate: function () {
+       },
+       componentWillUnmount: function () {
+       },
+       render() {
+
+               const containers = this.props.containers;
+               const context = {
+                       component: this,
+                       containers: containers
+               };
+
+               const networkService = containers.filter(d => d.type === 'nsd');
+               if (networkService.length === 0) {
+                       return <p className="welcome-message">No <img src={imgNSD} width="20px" /> NSD open in the canvas. Try opening an NSD.</p>;
+               }
+
+               return (
+                       <div className="EditForwardingGraphPaths -with-transitions" data-offset-parent="true">
+                               <div key="outline-indicator" data-outline-indicator="true"></div>
+                               {containers.filter(d => d.type === 'nsd').map(mapNSD.bind(context))}
+                       </div>
+               );
+
+       }
+});
+
+export default EditForwardingGraphPaths;
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/EditableProperty.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/EditableProperty.js
new file mode 100644 (file)
index 0000000..66d29da
--- /dev/null
@@ -0,0 +1,16 @@
+/**
+ * Created by onvelocity on 3/3/16.
+ */
+'use strict';
+import React from 'react'
+import ClassNames from 'classnames'
+import '../../styles/EditableProperty.scss'
+export default function EditableProperty(props) {
+       return (
+               <div className={ClassNames('EditableProperty', 'property', {'-is-disabled': props.disabled})}>
+                       <h3 className="property-label">{props.title}</h3>
+                       <div className="property-description">{props.description}</div>
+                       <val className="property-value"><div className="property-content">{props.children}</div></val>
+               </div>
+       )
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapClassifier.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapClassifier.js
new file mode 100644 (file)
index 0000000..bcd1918
--- /dev/null
@@ -0,0 +1,203 @@
+/**
+ * Created by onvelocity on 3/2/16.
+ */
+
+'use strict';
+
+import d3 from 'd3'
+import React from 'react'
+import Button from '../Button'
+import LayoutRow from '../LayoutRow'
+import ContentEditableDiv from '../ContentEditableDiv'
+import changeCase from 'change-case'
+import ClassNames from 'classnames'
+import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../../libraries/model/DescriptorModelMetaFactory'
+import HighlightRecordServicePaths from '../../libraries/graph/HighlightRecordServicePaths'
+import ComposerAppActions from '../../actions/ComposerAppActions'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import SelectionManager from '../../libraries/SelectionManager'
+import DeletionManager from '../../libraries/DeletionManager'
+import TooltipManager from '../../libraries/TooltipManager'
+import ConnectionPointSelector from './ConnectionPointSelector'
+import mapConnectionPoint from './mapConnectionPoint'
+import EditableProperty from './EditableProperty'
+import onCutDelegateToRemove from './onCutDelegateToRemove'
+import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
+import onFormInputChangedModifyContainerAndNotify from './onFormInputChangedModifyContainerAndNotify'
+
+import imgNSD from '../../images/default-catalog-icon.svg'
+import imgFG from '../../../../node_modules/open-iconic/svg/infinity.svg'
+import imgRemove from '../../../../node_modules/open-iconic/svg/trash.svg'
+import imgAdd from '../../../../node_modules/open-iconic/svg/plus.svg'
+import imgConnection from '../../../../node_modules/open-iconic/svg/random.svg'
+import imgClassifier from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
+import imgReorder from '../../../../node_modules/open-iconic/svg/menu.svg'
+
+export default function mapClassifier(context, classifier, i) {
+
+       // todo if a classifier is linked to an rsp then highlight it
+       //rsp.uiState.showPath = rsp.uiState.hasOwnProperty('showPath') ? rsp.uiState.showPath : true;
+
+       function onInputUpdateModel(context, attr, name, event) {
+               event.preventDefault();
+               attr.setFieldValue(name, event.target.value);
+               CatalogItemsActions.catalogItemDescriptorChanged(attr.getRoot());
+       }
+
+       function onClickAddNewMatchAttributes(context, classifier) {
+               event.preventDefault();
+               event.stopPropagation();
+               const newMatchAttr = classifier.createMatchAttributes();
+               SelectionManager.disableOutlineChanges();
+               CatalogItemsActions.catalogItemDescriptorChanged(classifier.getRoot());
+               setTimeout(() => {
+                       SelectionManager.enableOutlineChanges();
+                       SelectionManager.select(newMatchAttr);
+                       SelectionManager.refreshOutline();
+                       const input = Array.from(document.querySelectorAll(`tr[data-uid="${newMatchAttr.uid}"] input`)).forEach((element, index) => {
+                               // index 0 is hidden id field
+                               if (index === 1) {
+                                       element.focus();
+                               }
+                       });
+               }, 100);
+       }
+
+       function mapClassifierMatchAttributes(context, matchAttributes, key) {
+               const fields = matchAttributes.fieldNames.map((name, i) => {
+                       return (
+                               <td key={i} className={name + '-property'}>
+                                       <div className="match-attr-name">{name}</div>
+                                       <ContentEditableDiv value={matchAttributes.getFieldValue(name)}
+                                                                               onBlur={() => DeletionManager.addEventListeners()}
+                                                                               onClick={event => {
+                                                                                       event.preventDefault();
+                                                                                       SelectionManager.select(matchAttributes);
+                                                                                       SelectionManager.refreshOutline();
+                                                                               }}
+                                                                               onCut={event => {
+                                                                                       event.stopPropagation();
+                                                                               }}
+                                                                               onChange={onInputUpdateModel.bind(null, context, matchAttributes, name)}
+                                                                               className="match-attr-value"/>
+                               </td>
+                       );
+               });
+               return (
+                       <tr key={key}
+                               data-uid={matchAttributes.uid}
+                               onCut={event => {
+                                       event.stopPropagation();
+                                       matchAttributes.remove();
+                                       CatalogItemsActions.catalogItemDescriptorChanged(matchAttributes.getRoot());
+                                       SelectionManager.refreshOutline();
+                               }}>
+                               {fields}
+                       </tr>
+               )
+       }
+
+       function buildRecordServicePathSelector(classifier) {
+               const rspId = classifier.model['rsp-id-ref'];
+               const options = [{}].concat(classifier.parent.recordServicePaths).map((rsp, i) => {
+                       return (
+                               <option key={i} name="rsp-id-ref" value={rsp.id}>{rsp.title}</option>
+                       )
+               });
+               return (
+                       <select name="rsp-id-ref" value={rspId} onChange={onFormInputChangedModifyContainerAndNotify.bind(null, classifier)}>{options}</select>
+               )
+       }
+
+       function onClickExitPathEdithMode(component, event) {
+               event.preventDefault();
+               component.setState({editClassifierConnectionPointRef: false});
+       }
+
+       function onClickAddConnectionPointRef(component, classifier, connector, event) {
+               event.preventDefault();
+               classifier.addVnfdConnectionPoint(connector);
+               CatalogItemsActions.catalogItemDescriptorChanged(classifier.getRoot());
+       }
+
+       function onClickOpenConnectionPointSelector(component, classifier, event) {
+               component.setState({editClassifierConnectionPointRef: classifier.uid});
+               function closeAndRemoveHandler() {
+                       component.setState({editClassifierConnectionPointRef: false});
+                       document.body.removeEventListener('click', closeAndRemoveHandler, true);
+               }
+               document.body.addEventListener('click', closeAndRemoveHandler, true);
+       }
+
+       const attributeNames = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.vnffgd.classifier.match-attributes');
+
+       const selectedConnectionPoint = classifier.uiState.vnfdRef ? `${classifier.uiState.vnfdRef.name}/${classifier.vnfdConnectionPointRef.vnfdIndex}/${classifier.vnfdConnectionPointRef.vnfdConnectionPointName}` : '';
+
+       const isEditClassifierConnectionPointRef = context.component.state.editClassifierConnectionPointRef === classifier.uid;
+
+       const hasClassifierServiceFunctionVNFDs = context.containers.filter(d => DescriptorModelFactory.isConstituentVnfdWithServiceChain(d, 'CLASSIFIER')).length > 0;
+
+       return (
+               <LayoutRow key={classifier.uid}
+                                  data-uid={classifier.uid}
+                                  data-offset-width="true"
+                                  className={ClassNames('fg-classifier', classifier.className, {'-is-edit-classifier-connection-point-ref': isEditClassifierConnectionPointRef})}
+                                  onClick={onClickSelectAndShowInDetailsPanel.bind(null, classifier)}>
+                       <div className="classifier-properties">
+                               <div className="classifier-property">
+                                       <EditableProperty title="name">
+                                               <ContentEditableDiv name="name"
+                                                                                       value={classifier.name}
+                                                                                       autoPadRight="true"
+                                                                                       onBlur={() => DeletionManager.addEventListeners()}
+                                                                                       onChange={onFormInputChangedModifyContainerAndNotify.bind(null, classifier)}
+                                                                                       className="classifier-name" />
+                                       </EditableProperty>
+                               </div>
+                               <div className="classifier-property">
+                                       <EditableProperty title="path">
+                                               {buildRecordServicePathSelector(classifier)}
+                                       </EditableProperty>
+                               </div>
+                               <div className="classifier-property">
+                                       <EditableProperty title="connection point ref" disabled={!hasClassifierServiceFunctionVNFDs}>
+                                               <ContentEditableDiv autoPadRight="true"
+                                                                                       value={selectedConnectionPoint}
+                                                                                       disabled={!hasClassifierServiceFunctionVNFDs}
+                                                                                       onChange={() => {}}
+                                                                                       onClick={onClickOpenConnectionPointSelector.bind(null, context.component, classifier)} />
+                                       </EditableProperty>
+                                       <div className="select-connection-point-ref">
+                                               <ConnectionPointSelector containers={context.containers}
+                                                                                                style={context.styleSecondary}
+                                                                                                serviceChain="CLASSIFIER"
+                                                                                                isDisabled={!hasClassifierServiceFunctionVNFDs}
+                                                                                                onExitEditPathMode={onClickExitPathEdithMode.bind(null, context.component)}
+                                                                                                onAddConnectionPointRef={onClickAddConnectionPointRef.bind(null, context.component, classifier)}
+                                               />
+                                       </div>
+                                       {!hasClassifierServiceFunctionVNFDs ? <div className="hint">A VNFD with the chain CLASSIFIER is required to add a connection point ref.</div> : ''}
+                               </div>
+                       </div>
+                       <table className="classifier-match-attributes">
+                               <thead>
+                                       <tr>
+                                               {attributeNames.map((name, i) => <th key={i} className={ClassNames(name + '-property')}>{changeCase.title(name)}</th>)}
+                                       </tr>
+                               </thead>
+                               <tbody>
+                                       {classifier.matchAttributes.map(mapClassifierMatchAttributes.bind(null, context))}
+                               </tbody>
+                               <tfoot>
+                                       <tr className="xfooter-actions">
+                                               <th colSpan={attributeNames.length} className="row-action-column">
+                                                       <Button className="create-new-match-attributes" src={imgAdd} width="20px" onClick={onClickAddNewMatchAttributes.bind(null, context, classifier)} label="Add Match Attributes" />
+                                               </th>
+                                       </tr>
+                               </tfoot>
+                       </table>
+               </LayoutRow>
+       );
+
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapConnectionPoint.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapConnectionPoint.js
new file mode 100644 (file)
index 0000000..354f5f2
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * Created by onvelocity on 3/4/16.
+ */
+'use strict'
+import React from 'react'
+import onCutDelegateToRemove from './onCutDelegateToRemove'
+import onHoverHighlightConnectionPoint from './onHoverHighlightConnectionPoint'
+import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
+export default function mapConnectionPoint(style, addLine, cpRef, i) {
+       return (
+               <div key={cpRef.uid || i} className="rsp">
+                       {addLine ? <div className="rsp-line"></div> : null}
+                       <div className={cpRef.className} data-uid={cpRef.uid} style={style}
+                                onCut={onCutDelegateToRemove.bind(null, cpRef)}
+                                onMouseEnter={onHoverHighlightConnectionPoint.bind(null, cpRef.cpNumber)}
+                                onMouseLeave={onHoverHighlightConnectionPoint.bind(null, cpRef.cpNumber)}
+                                onClick={onClickSelectAndShowInDetailsPanel.bind(null, cpRef)}>
+                               <small>{cpRef.cpNumber || cpRef.vnfdConnectionPointName}</small>
+                       </div>
+               </div>
+       );
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapRecordServicePath.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/mapRecordServicePath.js
new file mode 100644 (file)
index 0000000..d5a6b00
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * Created by onvelocity on 3/2/16.
+ */
+
+'use strict';
+
+import d3 from 'd3'
+import React from 'react'
+import Button from '../Button'
+import LayoutRow from '../LayoutRow'
+import ContentEditableDiv from '../ContentEditableDiv'
+import EditableProperty from './EditableProperty'
+import changeCase from 'change-case'
+import ClassNames from 'classnames'
+import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../../libraries/model/DescriptorModelMetaFactory'
+import HighlightRecordServicePaths from '../../libraries/graph/HighlightRecordServicePaths'
+import ComposerAppActions from '../../actions/ComposerAppActions'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import SelectionManager from '../../libraries/SelectionManager'
+import DeletionManager from '../../libraries/DeletionManager'
+import TooltipManager from '../../libraries/TooltipManager'
+import mapConnectionPoint from './mapConnectionPoint'
+import ConnectionPointSelector from './ConnectionPointSelector'
+import onCutDelegateToRemove from './onCutDelegateToRemove'
+import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
+import onFormInputChangedModifyContainerAndNotify from './onFormInputChangedModifyContainerAndNotify'
+import onHoverHighlightConnectionPoint from './onHoverHighlightConnectionPoint'
+
+import imgNSD from '../../images/default-catalog-icon.svg'
+import imgFG from '../../../../node_modules/open-iconic/svg/infinity.svg'
+import imgRemove from '../../../../node_modules/open-iconic/svg/trash.svg'
+import imgAdd from '../../../../node_modules/open-iconic/svg/plus.svg'
+import imgConnection from '../../../../node_modules/open-iconic/svg/random.svg'
+import imgClassifier from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
+import imgReorder from '../../../../node_modules/open-iconic/svg/menu.svg'
+
+export default function mapRecordServicePath (context, rsp, i) {
+
+       rsp.uiState.showPath = rsp.uiState.hasOwnProperty('showPath') ? rsp.uiState.showPath : true;
+
+       function removeHighlighting() {
+               HighlightRecordServicePaths.removeHighlighting();
+       }
+
+       function highlightPath(rsp) {
+               HighlightRecordServicePaths.highlightPaths(rsp);
+       }
+
+       function onClickRemoveRecordServicePath(rsp, event) {
+               event.preventDefault();
+               const root = rsp.getRoot();
+               rsp.remove();
+               CatalogItemsActions.catalogItemDescriptorChanged(root);
+       }
+
+       function onClickEnterPathEdithMode(component, rspUid, event) {
+               event.preventDefault();
+               component.setState({editPathsMode: rspUid});
+       }
+
+       function onClickToggleRSPShowPath(rsp, event) {
+               // warn preventing default will undo the user's action
+               //event.preventDefault();
+               event.stopPropagation();
+               rsp.uiState.showPath = event.target.checked;
+               rsp.parent.uiState.showPaths = rsp.parent.rsp.filter(rsp => rsp.uiState.showPath === true).length === rsp.parent.rsp.length;
+               CatalogItemsActions.catalogItemMetaDataChanged(rsp.getRoot().model);
+       }
+
+       function onClickExitPathEdithMode(component, event) {
+               event.preventDefault();
+               component.setState({editPathsMode: false});
+       }
+
+       function onClickAddConnectionPointRef(component, rsp, connector, event) {
+               event.preventDefault();
+               if (rsp.isFactory) {
+                       const newRsp = rsp.createVnfdConnectionPointRef(connector);
+                       component.setState({editPathsMode: newRsp.uid});
+               } else {
+                       rsp.createVnfdConnectionPointRef(connector);
+               }
+               CatalogItemsActions.catalogItemDescriptorChanged(rsp.getRoot());
+       }
+
+       const isEditPathsMode = context.component.state.editPathsMode === rsp.uid;
+
+       const toggleSelectionOrCreateNewPath = (
+               <div>
+                       {!rsp.isFactory ? <input type="checkbox" id={'show-path-' + rsp.uid} checked={rsp.uiState.showPath} onChange={() => {}} onClick={onClickToggleRSPShowPath.bind(null, rsp)} /> : ' '}
+               </div>
+       );
+
+       const editRspName = (
+               <EditableProperty title="name">
+                       <ContentEditableDiv name="name" value={rsp.name} autoPadRight="true" onChange={onFormInputChangedModifyContainerAndNotify.bind(null, rsp)} />
+               </EditableProperty>
+       );
+
+       const hasServiceFunctionVNFDs = context.containers.filter(d => DescriptorModelFactory.isConstituentVnfdWithServiceChain(d, 'SF')).length > 0;
+
+       if (!hasServiceFunctionVNFDs && rsp.isFactory) {
+               return null;
+       }
+
+       let cpRefMapped = rsp.connectionPoints.map((cpRef, i) => {
+               return {
+                       index: i,
+                       value: cpRef
+               }
+       });
+
+       cpRefMapped.sort((a, b) => {
+               return a.value.order - b.value.order;
+       });
+
+       let connectionPointsSorted = cpRefMapped.map((cpRef) => {
+               return rsp.connectionPoints[cpRef.index];
+       });
+
+
+       return (
+               <div key={i} data-offset-width="table.fg-classifier" data-uid={rsp.uid}
+                        onClick={onClickSelectAndShowInDetailsPanel.bind(null, rsp)}
+                        onMouseOver={highlightPath.bind(null, rsp)}
+                        onMouseOut={removeHighlighting.bind(null, rsp)}
+                        onMouseLeave={removeHighlighting.bind(null, rsp)}
+                        onCut={onCutDelegateToRemove.bind(null, rsp)}>
+                       <div className={ClassNames(rsp.className, {'-is-factory': rsp.isFactory, '-is-edit-paths-mode': isEditPathsMode})}>
+                               <LayoutRow primaryActionColumn={toggleSelectionOrCreateNewPath} secondaryActionColumn={null}>
+                                       {editRspName}
+                                       <div className="connection-points">
+                                               {connectionPointsSorted.map(mapConnectionPoint.bind(null, context.stylePrimary, true))}
+                                               {hasServiceFunctionVNFDs ? <div className="rsp-create-new-connection-point-line rsp-line" style={context.styleSecondary}></div> : null}
+                                               {hasServiceFunctionVNFDs ? <div className="enter-path-edit-mode connection-point" style={context.styleSecondary}
+                                                        onClick={onClickEnterPathEdithMode.bind(null, context.component, rsp.uid)}>
+                                                       <small>+CP</small>
+                                               </div> : null}
+                                               {hasServiceFunctionVNFDs ? <ConnectionPointSelector containers={context.containers}
+                                                                                                style={context.styleSecondary}
+                                                                                                serviceChain="SF"
+                                                                                                onExitEditPathMode={onClickExitPathEdithMode.bind(null, context.component)}
+                                                                                                onAddConnectionPointRef={onClickAddConnectionPointRef.bind(null, context.component, rsp)}
+                                               /> : null}
+                                               {!hasServiceFunctionVNFDs && !rsp.isFactory ? <small className="hint">A VNFD with the chain SF is required to build Rendered Service Paths.</small> : null}
+                                               {rsp.isFactory && !isEditPathsMode? <small className="enter-path-edit-mode-hint hint">Tap to start creating a new path.</small> : null}
+                                       </div>
+                               </LayoutRow>
+                       </div>
+               </div>
+       );
+
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onClickSelectAndShowInDetailsPanel.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onClickSelectAndShowInDetailsPanel.js
new file mode 100644 (file)
index 0000000..d062088
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * Created by onvelocity on 3/2/16.
+ */
+'use strict';
+import ComposerAppActions from '../../actions/ComposerAppActions'
+export default function onClickSelectAndShowInDetailsPanel(container, event) {
+       if (event.defaultPrevented) return;
+       event.preventDefault();
+       if (container.isFactory) {
+               return
+       }
+       ComposerAppActions.selectModel(container);
+       ComposerAppActions.outlineModel.defer(container);
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onCutDelegateToRemove.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onCutDelegateToRemove.js
new file mode 100644 (file)
index 0000000..63410bf
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * Created by onvelocity on 3/2/16.
+ */
+'use strict';
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+export default function onCutDelegateToRemove(container, event) {
+       if (event.defaultPrevented) return;
+       if (container.remove()) {
+               CatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());
+       } else {
+               event.preventDefault();
+       }
+       event.stopPropagation();
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onFormInputChangedModifyContainerAndNotify.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onFormInputChangedModifyContainerAndNotify.js
new file mode 100644 (file)
index 0000000..a50a105
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * Created by onvelocity on 3/2/16.
+ */
+'use strict';
+import utils from '../../libraries/utils'
+import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+export default function onFormInputChangedModifyContainerAndNotify(container, event) {
+       if (DescriptorModelFactory.isContainer(container)) {
+               event.preventDefault();
+               const name = event.target.name;
+               const value = event.target.value;
+               utils.assignPathValue(container.model, name, value);
+               CatalogItemsActions.catalogItemDescriptorChanged(container.getRoot());
+       } else {
+               throw new TypeError('onFormInputChangedModifyContainerAndNotify called without a DescriptorModel. Did you forget to bind a DescriptorModel to the event handler?');
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onHoverHighlightConnectionPoint.js b/skyquake/plugins/composer/src/src/components/EditorForwardingGraph/onHoverHighlightConnectionPoint.js
new file mode 100644 (file)
index 0000000..4f78f72
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * Created by onvelocity on 3/4/16.
+ */
+'use strict';
+import d3 from 'd3'
+import TooltipManager from '../../libraries/TooltipManager'
+export default function onHoverHighlightConnectionPoint(cpNumber, event) {
+       const found = Array.from(document.querySelectorAll('[data-cp-number="' + cpNumber + '"]'));
+       if (event.type === 'mouseenter') {
+               found.forEach(d => {
+                       d3.select(d).classed('-is-highlight', true);
+                       if (d3.select(d).attr('data-tip')) {
+                               TooltipManager.showTooltip(d, 0);
+                       }
+               });
+       } else {
+               TooltipManager.hideTooltip();
+               found.forEach(d => d3.select(d).classed('-is-highlight', false));
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/components/ExportSelectorDialog.js b/skyquake/plugins/composer/src/src/components/ExportSelectorDialog.js
new file mode 100644 (file)
index 0000000..67c32a0
--- /dev/null
@@ -0,0 +1,127 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * Export Selector Dialog component.
+ * @module ExportSelectorDialog
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+import React from 'react'
+
+const defaults = {
+       catalogItemExportFormats: ['mano', 'rift'],
+       catalogItemExportGrammars: ['osm', 'tosca']
+};
+
+export default class ExportSelectorDialog extends React.Component {
+       constructor(props) {
+               super(props);
+               this.state = {};
+               this.state.onCancel = props.onCancel;
+               this.state.onDownload = props.onDownload;
+               this.state.onSelectGrammar = props.onSelectGrammar;
+               this.state.onSelectFormat = props.onSelectFormat;
+               this.state.currentlySelectedFormat = props.currentlySelectedFormat;
+               this.state.currentlySelectedGrammar = props.currentlySelectedGrammar;
+       }
+
+       selectFormat = (format, event) => {
+               this.setState({
+                       currentlySelectedFormat: format
+               });
+               
+               this.state.onSelectFormat.call(this, format);
+       }
+
+       selectGrammar = (grammar, event) => {
+               this.setState({
+                       currentlySelectedGrammar: grammar
+               });
+
+               this.state.onSelectGrammar.call(this, grammar);
+       }
+
+       render () {
+               let dialogListElements = [];
+
+               let schemaList = defaults.catalogItemExportFormats.map((format) => {
+                       let classNames = 'action Button';
+                       if (format == this.state.currentlySelectedFormat) {
+                               classNames += ' primary-action';
+                       } else {
+                               classNames += ' secondary-action';
+                       }
+
+                       return (
+                               <li>
+                                       <a className={classNames} onClick={this.selectFormat.bind(this, format)} style={{textTransform: 'uppercase'}}>{format}</a>
+                               </li>
+                       );
+               });
+
+               let grammarList = defaults.catalogItemExportGrammars.map((grammar) => {
+                       let classNames = 'action Button';
+                       if (grammar == this.state.currentlySelectedGrammar) {
+                               classNames += ' primary-action';
+                       } else {
+                               classNames += ' secondary-action';
+                       }
+
+                       return (
+                               <li>
+                                       <a className={classNames} onClick={this.selectGrammar.bind(this, grammar)} style={{textTransform: 'uppercase'}}>{grammar}</a>
+                               </li>
+                       );
+               });
+
+               dialogListElements.push(
+                       <li>
+                               <ul>
+                                       <li>Select a descriptor schema:</li>
+                                       {schemaList}
+                               </ul>
+                               <ul>
+                                       <li>Select a descriptor grammar:</li>
+                                       {grammarList}
+                               </ul>
+                       </li>
+               );
+
+               dialogListElements.push(
+                       <li>
+                               <a className="action Button" onClick={this.state.onCancel} style={{textTransform: 'capitalize', marginTop: '4rem', float: 'right'}}>Cancel</a>
+                               <a className="action Button" onClick={this.state.onDownload} style={{textTransform: 'capitalize', marginTop: '4rem', float: 'right'}}>Download</a>
+                       </li>
+               );
+
+               return (
+                       <div className="actions panel">
+                               <div className="panel-header" style={{minWidth: '30rem'}}>
+                                       <h1>Export Catalog Item</h1>
+                               </div>
+                               <div className="panel-body">
+                                       <ul className="schema-selector">
+                                               {dialogListElements}
+                                       </ul>
+                               </div>
+                       </div>
+               );
+       }
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/components/LayoutRow.js b/skyquake/plugins/composer/src/src/components/LayoutRow.js
new file mode 100644 (file)
index 0000000..04d4255
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * Created by onvelocity on 2/12/16.
+ */
+
+'use strict';
+
+import React from 'react'
+import ClassNames from 'classnames'
+
+import '../styles/LayoutRow.scss'
+
+export default function LayoutRow(props) {
+
+       const primaryActionColumn = props.primaryActionColumn ? props.primaryActionColumn : <div className="layout-row-empty-cell"> </div>;
+       const secondaryActionColumn = props.secondaryActionColumn ? props.secondaryActionColumn : <div className="layout-row-empty-cell"> </div>;
+
+       return (
+               <table {...props} className={ClassNames('layout-row', props.className)}>
+                       <tbody>
+                               <tr>
+                                       <th className="primary-action-column">
+                                               <div className="primary-action-column">{primaryActionColumn}</div>
+                                       </th>
+                                       <th className="secondary-action-column">
+                                               <div className="primary-action-column">{secondaryActionColumn}</div>
+                                       </th>
+                                       <td className="columns">
+                                               {props.children}
+                                       </td>
+                               </tr>
+                       </tbody>
+               </table>
+       );
+
+}
diff --git a/skyquake/plugins/composer/src/src/components/LoadingIndicator.js b/skyquake/plugins/composer/src/src/components/LoadingIndicator.js
new file mode 100644 (file)
index 0000000..1efe58b
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import ReactDOM from 'react-dom';
+import '../../../node_modules/loaders.css/src/animations/line-scale-pulse-out-rapid.scss';
+import '../styles/LoadingIndicator.scss';
+
+export default class Loader extends React.Component {
+       constructor(props) {
+               super(props);
+       }
+       render() {
+               let loader = '';
+               var style = {
+                       height: this.props.size + 'rem',
+                       width: this.props.size * 0.15 + 'rem',
+                       backgroundColor: this.props.color || 'white'
+               }
+               if (this.props.show) {
+                       loader = (
+                               <div className = {"line-scale-pulse-out-rapid"}>
+                                       <div style={style} ></div>
+                                       <div style={style} ></div>
+                                       <div style={style} ></div>
+                                       <div style={style} ></div>
+                                       <div style={style} ></div>
+                               </div>
+                       );
+               }
+               return loader;
+       }
+}
+Loader.defaultProps = {
+       show: true,
+       size: '5'
+}
diff --git a/skyquake/plugins/composer/src/src/components/ModalOverlay.js b/skyquake/plugins/composer/src/src/components/ModalOverlay.js
new file mode 100644 (file)
index 0000000..1840320
--- /dev/null
@@ -0,0 +1,81 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/14/15.
+ */
+'use strict';
+
+import React from 'react'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import ClassNames from 'classnames'
+
+import ModalOverlayStore from '../stores/ModalOverlayStore'
+
+import '../styles/ModalOverlay.scss'
+
+const ModalOverlay = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return ModalOverlayStore.getState();
+       },
+       getDefaultProps() {
+       },
+       componentWillMount() {
+               ModalOverlayStore.listen(this.onChange);
+       },
+       componentDidMount() {
+               window.addEventListener('resize', this.onResizeCapture, true);
+               window.addEventListener('mousemove', this.onMouseMoveCapture, true);
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+               ModalOverlayStore.unlisten(this.onChange);
+               window.removeEventListener('resize', this.onResize, true);
+               window.removeEventListener('mousemove', this.onMouseMoveCapture, true);
+       },
+       onChange(state) {
+               this.setState(state);
+       },
+       onResizeCapture(event) {
+               if (event.detail && event.detail.side) {
+                       if (this.state.visible) {
+                               event.preventDefault();
+                               event.stopPropagation();
+                       }
+               }
+       },
+       onMouseMoveCapture(event) {
+               if (this.state.visible) {
+                       event.preventDefault();
+                       event.stopPropagation();
+               }
+       },
+       render() {
+               const className = ClassNames('ModalOverlay', {'-is-visible': this.state.visible});
+               return (
+                       <div className={className}>
+                               <div className="background" onMouseMoveCapture={this.onMouseMoveCapture}></div>
+                               {this.state.ui ? <div className="foreground" onMouseMoveCapture={this.onMouseMoveCapture}><div className="ui">{this.state.ui}</div></div> : null}
+                       </div>
+               );
+       }
+});
+
+export default ModalOverlay;
diff --git a/skyquake/plugins/composer/src/src/components/PopupWindow.js b/skyquake/plugins/composer/src/src/components/PopupWindow.js
new file mode 100644 (file)
index 0000000..36b08e1
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Created by onvelocity on 2/2/16.
+ */
+
+import React from 'react'
+import OpenWindow from 'react-popout'
+import JSONViewer from 'widgets/JSONViewer/JSONViewer';
+import ComposerAppActions from '../actions/ComposerAppActions'
+
+import 'widgets/JSONViewer/JSONViewer.scss'
+
+window._open = window.open.bind(window);
+window.open = function monkeyPatchOpen(url, name, options) {
+       const popupWindow = this._open(url, name, options);
+       popupWindow.document.getElementsByTagName('body')[0].focus();
+       return popupWindow;
+};
+const h1style = {
+       'paddingTop' : '1rem',
+       'marginLeft': '1rem',
+       'left': 0,
+       'textTransform': 'uppercase',
+       'fontSize': '1.625rem',
+       'fontWeight': 'normal',
+       'fontFamily': 'sans-serif'
+}
+export default function (props) {
+       if (!props.show) {
+               return <div></div>;
+       }
+       function onClose() {
+               ComposerAppActions.closeJsonViewer();
+       }
+       return (
+               <OpenWindow title={"RIFT.ware Popup"} onClosing={onClose}>
+                       <div style={{backgroundColor: '#f1f1f1', 'paddingBottom': '1rem'}}>
+                               <h1 style={h1style}>{props.title}</h1>
+                               {props.children}
+                       </div>
+               </OpenWindow>
+       );
+}
diff --git a/skyquake/plugins/composer/src/src/components/Range.js b/skyquake/plugins/composer/src/src/components/Range.js
new file mode 100644 (file)
index 0000000..b3dc186
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * Created by onvelocity on 2/3/16.
+ */
+'use strict';
+
+var React = require('react');
+var ReactDOM = require('react-dom');
+var _extends = Object.assign;
+
+/**
+ * WORKAROUND FOR: https://github.com/facebook/react/issues/554
+ * COPIED FROM: https://github.com/mapbox/react-range
+ */
+
+var Range = React.createClass({
+       displayName: 'Range',
+       propTypes: {
+               onChange: React.PropTypes.func,
+               onClick: React.PropTypes.func,
+               onKeyDown: React.PropTypes.func,
+               onMouseMove: React.PropTypes.func
+       },
+       getDefaultProps: function() {
+               return {
+                       type: 'range',
+                       onChange: function(){},
+                       onClick: function(){},
+                       onKeyDown: function(){},
+                       onMouseMove: function(){}
+               };
+       },
+       onRangeChange: function(e) {
+               this.props.onMouseMove(e);
+               if (e.buttons !== 1 && e.which !== 1) return;
+               this.props.onChange(e);
+       },
+       onRangeClick: function(e) {
+               this.props.onClick(e);
+               this.props.onChange(e);
+       },
+       onRangeKeyDown: function(e) {
+               this.props.onKeyDown(e);
+               this.props.onChange(e);
+       },
+       componentWillReceiveProps: function(props) {
+               ReactDOM.findDOMNode(this).value = props.value;
+       },
+       render: function() {
+               var props = _extends({}, this.props, {
+                       defaultValue: this.props.value,
+                       onClick: this.onRangeClick,
+                       onKeyDown: this.onRangeKeyDown,
+                       onMouseMove: this.onRangeChange,
+                       onChange: function() {}
+               });
+               delete props.value;
+               return React.createElement(
+                       'input',
+                       props
+               );
+       }
+});
+
+module.exports = Range;
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/components/RiftHeader.js b/skyquake/plugins/composer/src/src/components/RiftHeader.js
new file mode 100644 (file)
index 0000000..16dc5fd
--- /dev/null
@@ -0,0 +1,98 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by kkashalk on 11/10/15.
+ */
+
+ // NOTE: THIS FILE HAS BEEN DEPRECATED AND WILL BE REMOVED
+
+'use strict';
+
+import utils from '../libraries/utils'
+import React from 'react'
+import ClassNames from 'classnames'
+import PureRenderMixin from 'react-addons-pure-render-mixin'
+import RiftHeaderActions from '../actions/RiftHeaderActions'
+import RiftHeaderStore from '../stores/RiftHeaderStore'
+
+import '../styles/RiftHeader.scss'
+
+const uiTransientState = {
+       timeoutId: 0
+};
+
+const RiftHeader = React.createClass({
+       mixins: [PureRenderMixin],
+       getInitialState() {
+               return RiftHeaderStore.getState();
+       },
+       getDefaultProps() {
+       },
+       componentWillMount() {
+       },
+       componentDidMount() {
+               RiftHeaderStore.listen(this.onChange);
+               const loadCatalogs = function () {
+                       RiftHeaderStore.loadCatalogs();
+                       uiTransientState.timeoutId = setTimeout(loadCatalogs, 2000);
+               };
+               RiftHeaderStore.requestLaunchpadConfig();
+               loadCatalogs();
+       },
+       componentDidUpdate() {
+       },
+       componentWillUnmount() {
+               if (uiTransientState.timeoutId) {
+                       clearTimeout(uiTransientState.timeoutId);
+               }
+               RiftHeaderStore.unlisten(this.onChange);
+       },
+
+       onChange(state) {
+               this.setState(state);
+       },
+       onClickOpenDashboard() {
+               if (uiTransientState.timeoutId) {
+                       clearTimeout(uiTransientState.timeoutId);
+               }
+               RiftHeaderStore.unlisten(this.onChange);
+               window.location.href = '//' + window.location.hostname + ':8000/index.html?api_server=' + utils.getSearchParams(window.location).api_server + '#/launchpad/' + utils.getSearchParams(window.location).mgmt_domain_name;
+       },
+       onClickOpenAccounts() {
+               if (uiTransientState.timeoutId) {
+                       clearTimeout(uiTransientState.timeoutId);
+               }
+               RiftHeaderStore.unlisten(this.onChange);
+               window.location.href = '//' + window.location.hostname + ':8000/index.html?api_server=' + utils.getSearchParams(window.location).api_server + '#/launchpad/' + utils.getSearchParams(window.location).mgmt_domain_name + '/cloud-account/dashboard';
+       },
+       render() {
+               let Header = (
+                               <header className="header-app">
+                                                       <h1>{this.state.headerTitle}</h1>
+                                                       <nav className="header-nav"> </nav>
+                                               </header>
+                                       );
+               Header = null;
+               return (
+                       null
+               );
+       }
+});
+
+export default RiftHeader;
diff --git a/skyquake/plugins/composer/src/src/components/messages.js b/skyquake/plugins/composer/src/src/components/messages.js
new file mode 100644 (file)
index 0000000..0128aa4
--- /dev/null
@@ -0,0 +1,54 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/20/15.
+ */
+'use strict';
+
+import React from 'react'
+
+import imgOnboard from '../../../node_modules/open-iconic/svg/cloud-upload.svg'
+
+const message = {
+       detailsWelcome() {
+               return <p className="welcome-message">Select an object to view details.</p>;
+       },
+       canvasWelcome() {
+               return (
+                       <span>
+                               <p className="welcome-message">Double-click a Descriptor to open.</p>
+                               <p className="welcome-message">Or drag a Descriptor to add to Canvas.</p>
+                       </span>
+               );
+       },
+       get showMoreTitle() {
+               return 'Show More';
+       },
+       get showLessTitle() {
+               return 'Show Less';
+       },
+       get catalogWelcome() {
+               return <p className="welcome-message">To onboard a descriptor, drag the package to the catalog or click the Onboard button (<img style={{width: '20px'}} src={imgOnboard} />) to select the package.</p>;
+       },
+       getSaveActionLabel(isNew) {
+               return isNew ? 'Onboard' : 'Update';
+       }
+};
+
+export default message;
diff --git a/skyquake/plugins/composer/src/src/favicon.ico b/skyquake/plugins/composer/src/src/favicon.ico
new file mode 100644 (file)
index 0000000..6527905
Binary files /dev/null and b/skyquake/plugins/composer/src/src/favicon.ico differ
diff --git a/skyquake/plugins/composer/src/src/images/default-catalog-icon.svg b/skyquake/plugins/composer/src/src/images/default-catalog-icon.svg
new file mode 100644 (file)
index 0000000..80fb5ef
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+       Copyright 2016 RIFT.IO Inc
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90.8 78.5"><path class="st0" d="M70.8 58.2c-0.7 0-1.4 0.1-2 0.3L51.5 42.7c0.7-1.1 1.2-2.4 1.2-3.8 0-1.4-0.4-2.7-1.2-3.8l15.1-13.9c1.1 0.9 2.6 1.5 4.2 1.5 3.7 0 6.7-3 6.7-6.6 0-3.7-3-6.6-6.7-6.6 -3.7 0-6.7 3-6.7 6.6 0 1.4 0.4 2.7 1.2 3.8L50.2 33.8c-1.1-0.9-2.6-1.5-4.2-1.5 -1.6 0-3.1 0.6-4.2 1.5L26.7 19.9c0.7-1.1 1.2-2.4 1.2-3.8 0-3.7-3-6.6-6.7-6.6 -3.7 0-6.7 3-6.7 6.6 0 3.3 2.5 6.1 5.7 6.6v35.6c-3.2 0.5-5.7 3.2-5.7 6.6 0 3.7 3 6.6 6.7 6.6 3.1 0 5.8-2.2 6.5-5.1h36.7c0.7 2.9 3.3 5.1 6.5 5.1 3.7 0 6.7-3 6.7-6.6C77.5 61.2 74.5 58.2 70.8 58.2zM64.2 64.5H27.8c-0.1-2.1-1.2-4-2.8-5.1l16.7-15.4c1.1 0.9 2.6 1.5 4.2 1.5 1.6 0 3.1-0.6 4.2-1.5L67 59.4C65.3 60.6 64.3 62.4 64.2 64.5zM25.4 21.3l15.1 13.9c-0.7 1.1-1.2 2.4-1.2 3.8 0 1.4 0.4 2.7 1.2 3.8L23.2 58.5c-0.3-0.1-0.7-0.2-1.1-0.2V22.7C23.4 22.5 24.5 22 25.4 21.3z"/></svg>
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/images/default-icon-white.svg b/skyquake/plugins/composer/src/src/images/default-icon-white.svg
new file mode 100644 (file)
index 0000000..c8b5bca
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+       Copyright 2016 RIFT.IO Inc
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="378" height="412" viewBox="0 0 378 412"><title>  default</title><desc>  default</desc><g id="Page-1" style="fill:none;stroke-width:1;stroke:none"><path stroke="white" d="M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z" id="default" fill="white"/></g></svg>
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/images/default-icon.svg b/skyquake/plugins/composer/src/src/images/default-icon.svg
new file mode 100644 (file)
index 0000000..1b28cd6
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+       Copyright 2016 RIFT.IO Inc
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="378" height="412" viewBox="0 0 378 412"><title>  default</title><desc>  default</desc><g id="Page-1" style="fill:none;stroke-width:1;stroke:none"><path d="M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z" id="default" fill="#000"/></g></svg>
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/images/header-logo.png b/skyquake/plugins/composer/src/src/images/header-logo.png
new file mode 100644 (file)
index 0000000..09b47c7
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/header-logo.png differ
diff --git a/skyquake/plugins/composer/src/src/images/logos/riftio.png b/skyquake/plugins/composer/src/src/images/logos/riftio.png
new file mode 100644 (file)
index 0000000..2361de6
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/logos/riftio.png differ
diff --git a/skyquake/plugins/composer/src/src/images/osm_header_253x50.png b/skyquake/plugins/composer/src/src/images/osm_header_253x50.png
new file mode 100644 (file)
index 0000000..1005431
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/osm_header_253x50.png differ
diff --git a/skyquake/plugins/composer/src/src/images/osm_header_506x100.png b/skyquake/plugins/composer/src/src/images/osm_header_506x100.png
new file mode 100644 (file)
index 0000000..7ece845
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/osm_header_506x100.png differ
diff --git a/skyquake/plugins/composer/src/src/images/riftio_website_logo_002_03.png b/skyquake/plugins/composer/src/src/images/riftio_website_logo_002_03.png
new file mode 100644 (file)
index 0000000..f187fb6
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/riftio_website_logo_002_03.png differ
diff --git a/skyquake/plugins/composer/src/src/images/sample-catalog.png b/skyquake/plugins/composer/src/src/images/sample-catalog.png
new file mode 100644 (file)
index 0000000..caf4251
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/sample-catalog.png differ
diff --git a/skyquake/plugins/composer/src/src/images/vendor-riftio.png b/skyquake/plugins/composer/src/src/images/vendor-riftio.png
new file mode 100644 (file)
index 0000000..70d23dd
Binary files /dev/null and b/skyquake/plugins/composer/src/src/images/vendor-riftio.png differ
diff --git a/skyquake/plugins/composer/src/src/index.html b/skyquake/plugins/composer/src/src/index.html
new file mode 100644 (file)
index 0000000..f75dbc4
--- /dev/null
@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+<head>
+       <meta charset="utf-8">
+       <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+       <title>RIFT.ware</title>
+       <meta name="description" content="">
+       <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+  <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+  <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+  <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+  <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+  <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+  <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+  <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+  <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
+  <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
+  <link rel="icon" type="image/png" href="/favicon-194x194.png" sizes="194x194">
+  <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
+  <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
+  <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
+  <link rel="manifest" href="/manifest.json">
+  <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+  <meta name="msapplication-TileColor" content="#da532c">
+  <meta name="msapplication-TileImage" content="/mstile-144x144.png">
+  <meta name="theme-color" content="#ffffff">
+</head>
+<body style="background-color:#505050">
+<!--[if lt IE 8]>
+<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade
+       your browser</a> to improve your experience.</p>
+<![endif]-->
+<div id="content">
+       <h1 id="msg-no-js" style="display:none;">If you can see this, something is broken (or JS is not enabled)!!.</h1>
+</div>
+
+<script>
+       __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__
+</script>
+<script type="text/javascript" src="assets/main.js"></script>
+</body>
+</html>
diff --git a/skyquake/plugins/composer/src/src/libraries/CatalogPackageManagerUploadDropZone.js b/skyquake/plugins/composer/src/src/libraries/CatalogPackageManagerUploadDropZone.js
new file mode 100644 (file)
index 0000000..5f1ee24
--- /dev/null
@@ -0,0 +1,122 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/27/15.
+ */
+
+import guid from '../libraries/guid'
+import DropZone from 'dropzone'
+import Utils from '../libraries/utils'
+import CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'
+
+/**
+ * This class is responsible for wiring the DropZone.js to our React actions.
+ */
+
+const ACTIONS = {
+       onboard: 'onboard',
+       update: 'update'
+};
+
+function getCatalogPackageManagerServerOrigin() {
+       return Utils.getSearchParams(window.location).upload_server + ':4567';
+}
+
+function initializeDropZone(element = '#dropzone', button = false, action = ACTIONS.onboard) {
+       DropZone.autoDiscover = false;
+       return new DropZone(element, {
+               paramName: 'descriptor',
+               url() {
+                       if (action === ACTIONS.update) {
+                               return getCatalogPackageManagerServerOrigin() + '/api/update';
+                       }
+                       return getCatalogPackageManagerServerOrigin() + '/api/upload';
+               },
+               maxFilesize: 10000000000,
+               clickable: button,
+               acceptedFiles: 'application/octet-stream,.gz,.tar.gz,.tar,.qcow,.qcow2,.iso,application/yaml,.yaml,application/json,.json,application/zip,.zip,application/x-rar-compressed,.rar,application/x-7z-compressed,.7z,application/x-bzip,.bz,application/x-bzip2,.bz2,application/x-gtar,.gtar',
+               autoProcessQueue: true,
+               previewTemplate: '',
+               sending(file, xhr, formData) {
+                       // NOTE ie11 does not get this form data
+                       formData.append('id', file.id);
+               },
+               error(file, errorMessage) {
+                       const response = {
+                               state: file,
+                               data: {
+                                       status: 'upload-error',
+                                       message: errorMessage
+                               }
+                       };
+                       CatalogPackageManagerActions.uploadCatalogPackageError(response);
+               },
+               success(file) {
+                       const data = JSON.parse(file.xhr.responseText);
+                       data.status = 'upload-success';
+                       const response = {
+                               state: file,
+                               data: data
+                       };
+                       CatalogPackageManagerActions.uploadCatalogPackageStatusUpdated(response);
+               },
+               addedfile(file) {
+                       file.id = file.id || guid();
+                       file.riftAction = action;
+                       CatalogPackageManagerActions.uploadCatalogPackage(file);
+               },
+               thumbnail(file, dataUrl) {
+                       const response = {
+                               state: file,
+                               data: {
+                                       status: 'upload-thumbnail',
+                                       dataUrl: dataUrl
+                               }
+                       };
+                       CatalogPackageManagerActions.uploadCatalogPackageStatusUpdated(response);
+               },
+               uploadprogress(file, progress, bytesSent) {
+                       const response = {
+                               state: file,
+                               data: {
+                                       status: 'upload-progress',
+                                       progress: progress,
+                                       bytesSent: bytesSent
+                               }
+                       };
+                       CatalogPackageManagerActions.uploadCatalogPackageStatusUpdated(response);
+               }
+       });
+}
+
+export default class CatalogPackageManagerUploadDropZone {
+
+       constructor(element, button, action) {
+               this.dropZone = initializeDropZone(element, button, action);
+       }
+
+       static get ACTIONS() {
+               return ACTIONS;
+       }
+
+       on(eventName, eventCallback) {
+               this.dropZone.on(eventName, eventCallback);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/ColorGroups.js b/skyquake/plugins/composer/src/src/libraries/ColorGroups.js
new file mode 100644 (file)
index 0000000..13984e7
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * Created by onvelocity on 2/3/16.
+ */
+'use strict';
+const pairedColors = ['#fb9a99','#e31a1c','#a6cee3','#1f78b4','#b2df8a','#33a02c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99','#b15928'];
+
+import colorTheme from '../assets/rift.ware-color-theme.json'
+
+/**
+ *
+ * Colors are also defined in _ColorGroups.scss. HINT: Uncomment the console statement at the bottom of this file to
+ * generate the variables and then copy and paste them into the .scss file.
+ *
+ * Externalized colors into a .json file to make it easier to modify them.
+ */
+const ColorGroups = {
+       // http://colorbrewer2.org/?type=qualitative&scheme=Paired&n=12
+       getColorPair(index) {
+               // make sure index is not larger than our list of colors
+               index = (index * 2) % 12;
+               return {
+                       primary: pairedColors[index + 1],
+                       secondary: pairedColors[index]
+               };
+       },
+       getColorCSS() {
+               return Object.keys(colorTheme).map((key) => {
+                       if (typeof colorTheme[key] === 'object') {
+                               const color = colorTheme[key];
+                               return Object.keys(color).map(name => {
+                                       return `\$${key}-${name}-color: ${color[name]};`
+                               }).join('\n');
+                       }
+                       if (typeof colorTheme[key] === 'string') {
+                               const color = colorTheme[key];
+                               return `$descriptor-${key}: ${color};\n\n`
+                       }
+               }).join('\n\n');
+       },
+       getColorPairForType(type) {
+               const colors = colorTheme[type];
+               if (colors) {
+                       return colors;
+               }
+               return colorTheme.common;
+       }
+};
+
+//console.log(ColorGroups.getColorCSS());
+
+Object.assign(ColorGroups, colorTheme);
+
+export default ColorGroups;
diff --git a/skyquake/plugins/composer/src/src/libraries/DeletionManager.js b/skyquake/plugins/composer/src/src/libraries/DeletionManager.js
new file mode 100644 (file)
index 0000000..026555c
--- /dev/null
@@ -0,0 +1,144 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/2/15.
+ */
+
+import _ from 'lodash'
+import d3 from 'd3'
+import UID from './UniqueId'
+import SelectionManager from './SelectionManager'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import DescriptorModelFactory from './model/DescriptorModelFactory'
+
+import '../styles/Animations.scss'
+
+const DELETE = 26;
+const BACKSPACE = 8;
+
+function onlyUnique(value, index, self) {
+       return self.indexOf(value) === index;
+}
+
+function createDeleteEvent(e, uid, eventName = 'cut') {
+       const data = {
+               bubbles: true,
+               cancelable: true,
+               detail: {
+                       uid: uid,
+                       originalEvent: e
+               }
+       };
+       if (window.CustomEvent.prototype.initCustomEvent) {
+               // support IE
+               var evt = document.createEvent('CustomEvent');
+               evt.initCustomEvent(eventName, data.bubbles, data.cancelable, data.detail);
+               return evt;
+       }
+       return new CustomEvent(eventName, data);
+}
+
+export default class DeletionManager {
+
+       static onDeleteKey(event) {
+               const target = event.target;
+               if (event.defaultPrevented) {
+                       return
+               }
+               if ((event.which === DELETE || event.which === BACKSPACE) && /^BODY|SVG|DIV$/i.test(target.tagName)) {
+                       event.preventDefault();
+                       DeletionManager.deleteSelected(event);
+                       return false;
+               }
+       }
+
+       static deleteSelected(event) {
+
+               // TODO refactor this to be a flux action e.g. move this code into ComposerAppActions.deleteSelected()
+
+               const selected = SelectionManager.getSelections();
+
+               const canvasPanelDiv = document.getElementById('canvasPanelDiv');
+
+               if (!canvasPanelDiv) {
+                       return
+               }
+
+               // get a valid list of items to potentially remove via the cut event handler
+               const removeElementList = selected.filter(d => d).filter(onlyUnique).reduce((r, uid) => {
+                       const elements = Array.from(canvasPanelDiv.querySelectorAll('[data-uid="' + uid + '"]'));
+                       return r.concat(elements);
+               }, []).filter(d => d);
+
+               if (removeElementList.length === 0 && selected.length > 0) {
+                       // something was selected but we did not find any dom elements with data-uid!
+                       console.error(`No valid DescriptorModel instance found on element. Did you forget to put data-uid={m.uid}`,
+                               selected.map(uid => Array.from(canvasPanelDiv.querySelectorAll(`[data-uid="${uid}"]`))));
+               }
+
+               SelectionManager.removeOutline();
+
+               // now actually update the model
+               const invokedEventAlreadyMap = {};
+               const failedToRemoveList = removeElementList.map(element => {
+
+                       const uid = UID.from(element);
+
+                       if (invokedEventAlreadyMap[uid]) {
+                               return
+                       }
+
+                       try {
+                               // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
+                               // false means event.preventDefault() was called by one of the handlers
+                               const deleteEvent = createDeleteEvent(event, uid);
+                               const preventDefault = (false === element.dispatchEvent(deleteEvent));
+                               if (preventDefault) {
+                                       console.log('cut event was cancelled', element);
+                                       //d3.select(element).classed('-with-animations deleteItemAnimation', false).style({opacity: null});
+                                       return element;
+                               }
+
+                       } catch (error) {
+                               console.warn(`Exception caught dispatching 'cut' event: ${error}`,
+                                       selected.map(uid => Array.from(canvasPanelDiv.querySelectorAll(`[data-uid="${uid}"]`)))
+                               );
+                               return element;
+                       } finally {
+                               invokedEventAlreadyMap[uid] = true;
+                       }
+
+               }).filter(d => d).filter(onlyUnique);
+
+               SelectionManager.clearSelectionAndRemoveOutline();
+               failedToRemoveList.forEach(d => SelectionManager.addSelection(d));
+               SelectionManager.refreshOutline();
+
+       }
+
+       static addEventListeners() {
+               DeletionManager.removeEventListeners();
+               document.body.addEventListener('keydown', DeletionManager.onDeleteKey);
+       }
+
+       static removeEventListeners() {
+               document.body.removeEventListener('keydown', DeletionManager.onDeleteKey);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/InstanceCounter.js b/skyquake/plugins/composer/src/src/libraries/InstanceCounter.js
new file mode 100644 (file)
index 0000000..78f8de7
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * Created by onvelocity on 1/28/16.
+ */
+
+function getInstanceCount(type, bump = true) {
+       // keep a global counter
+       let count = 0;
+       const data = sessionStorage.getItem('instance-counts');
+       const counts = JSON.parse(data || '{}');
+       if (counts.hasOwnProperty(type)) {
+               count = counts[type];
+               if (bump) {
+                       counts[type] = ++count;
+               } else {
+                       return count;
+               }
+       } else {
+               count = counts[type] = 1;
+       }
+       sessionStorage.setItem('instance-counts', JSON.stringify(counts));
+       return count;
+}
+
+export default {
+
+       /**
+        * Get instance count for given type without bumping the number.
+        *
+        * @param type
+        * @returns {number}
+        */
+       current(type) {
+               return getInstanceCount(type, false);
+       },
+
+       /**
+        * Get the instance count for the given type - will bump the counter and return the new value.
+        *
+        * @param type
+        * @returns {number}
+        */
+       count(type) {
+               return getInstanceCount(type);
+       }
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/libraries/ResizableManager.js b/skyquake/plugins/composer/src/src/libraries/ResizableManager.js
new file mode 100644 (file)
index 0000000..cd52b82
--- /dev/null
@@ -0,0 +1,428 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/9/15.
+ */
+'use strict';
+
+import getZoomFactor from './zoomFactor'
+import '../styles/ResizableManager.scss'
+
+const sideComplement = {
+       left: 'right',
+       right: 'left',
+       top: 'bottom',
+       bottom: 'top'
+};
+
+function zoneName(sides) {
+       return sides.sort((a, b) => {
+               if (!a) {
+                       return 1;
+               }
+               if (!b) {
+                       return 1;
+               }
+               if (a.side === 'top' || a.side === 'bottom') {
+                       return -1;
+               }
+               return 1;
+       }).join('-');
+}
+
+const resizeDragZones = {
+       top (position, x, y, resizeDragZoneWidth) {
+               const adj = y > 0 && y < document.body.clientHeight;
+               const pos = position.top - (adj ? resizeDragZoneWidth / 2 : 0);
+               if (Math.abs(y - pos) < resizeDragZoneWidth) {
+                       return 'top';
+               }
+       },
+       bottom (position, x, y, resizeDragZoneWidth) {
+               const adj = y > 0 && y < document.body.clientHeight;
+               const pos = position.bottom - (adj ? resizeDragZoneWidth / 2 : 0);
+               if (Math.abs(y - pos) < resizeDragZoneWidth) {
+                       return 'bottom';
+               }
+       },
+       right (position, x, y, resizeDragZoneWidth) {
+               const adj = x > 0 && x < document.body.clientWidth;
+               const pos = position.right - (adj ? resizeDragZoneWidth / 2 : 0);
+               if (Math.abs(x - pos) < resizeDragZoneWidth) {
+                       return 'right';
+               }
+       },
+       left (position, x, y, resizeDragZoneWidth) {
+               const adj = x > 0 && x < document.body.clientWidth;
+               const pos = position.left - (adj ? resizeDragZoneWidth / 2 : 0);
+               if (Math.abs(x - pos) < resizeDragZoneWidth) {
+                       return 'left';
+               }
+       },
+       outside (position, x, y, resizeDragZoneWidth) {
+               if (x < (position.left - resizeDragZoneWidth) || x > (position.right + resizeDragZoneWidth) || y < (position.top - resizeDragZoneWidth) || y > (position.bottom + resizeDragZoneWidth)) {
+                       return 'outside';
+               }
+       }
+};
+
+const resizeDragLimitForSide = {
+       top (position, x, y, resizeDragZoneWidth, resizing) {
+               // y must be inside the position coordinates
+               const adj = y > 0 && y < document.body.clientHeight;
+               const top = position.top - (adj ? resizeDragZoneWidth / 2 : 0);
+               const bottom = position.bottom + (adj ? resizeDragZoneWidth / 2 : 0);
+               return y > top && y < bottom;
+       },
+       bottom (position, x, y, resizeDragZoneWidth) {
+               return this.top(position, x, y, resizeDragZoneWidth);
+       },
+       right (position, x, y, resizeDragZoneWidth) {
+               const adj = x > 0 && x < document.body.clientWidth;
+               const left = position.left - (adj ? resizeDragZoneWidth / 2 : 0);
+               const right = position.right + (adj ? resizeDragZoneWidth / 2 : 0);
+               return x > left && x < right;
+       },
+       left (position, x, y, resizeDragZoneWidth) {
+               return this.right(position, x, y, resizeDragZoneWidth);
+       },
+       limit_top (position, x, y, resizeDragZoneWidth, resizing) {
+               // must be outside the position coordinates
+               const limit = {
+                       top: 0,
+                       right: position.right,
+                       bottom: position.bottom,
+                       left: position.left
+               };
+               return this.top(limit, x, y, resizeDragZoneWidth, resizing);
+       },
+       limit_bottom (position, x, y, resizeDragZoneWidth, resizing) {
+               const limit = {
+                       top: position.top,
+                       right: position.right,
+                       bottom:0,
+                       left: position.left
+               };
+               return this.bottom(limit, x, y, resizeDragZoneWidth, resizing);
+       },
+       limit_right (position, x, y, resizeDragZoneWidth, resizing) {
+               const limit = {
+                       top: position.top,
+                       right: 0,
+                       bottom: position.bottom,
+                       left: position.left
+               };
+               return this.right(position, x, y, resizeDragZoneWidth, resizing);
+       },
+       limit_left (position, x, y, resizeDragZoneWidth, resizing) {
+               const limit = {
+                       top: position.top,
+                       right: position.right,
+                       bottom: position.bottom,
+                       left: 0
+               };
+               return this.left(position, x, y, resizeDragZoneWidth, resizing);
+       }
+};
+
+function createEvent(e, eventName = 'resize') {
+       const lastX = this.resizing.lastX || 0;
+       const lastY = this.resizing.lastY || 0;
+       const zoomFactor = getZoomFactor();
+       this.resizing.lastX = (e.clientX / zoomFactor);
+       this.resizing.lastY = (e.clientY / zoomFactor);
+       const data = {
+               bubbles: true,
+               cancelable: true,
+               detail: {
+                       x: e.clientX / zoomFactor,
+                       y: e.clientY / zoomFactor,
+                       side: this.resizing.side,
+                       start: {x: this.resizing.startX, y: this.resizing.startY},
+                       moved: {
+                               x: lastX - (e.clientX / zoomFactor),
+                               y: lastY - (e.clientY / zoomFactor)
+                       },
+                       target: this.resizing.target,
+                       originalEvent: e
+               }
+       };
+       if (window.CustomEvent.prototype.initCustomEvent) {
+               // support IE
+               var evt = document.createEvent('CustomEvent');
+               evt.initCustomEvent(eventName, data.bubbles, data.cancelable, data.detail);
+               return evt;
+       }
+       return new CustomEvent(eventName, data);
+}
+
+const defaultHandleOffset = [0, 0, 0, 0]; // top, right, bottom, left
+
+class ResizableManager {
+
+       constructor(target = document, dragZones = resizeDragZones) {
+               this.target = target;
+               this.resizing = null;
+               this.lastResizable = null;
+               this.activeResizable = null;
+               this.resizeDragZones = dragZones;
+               this.defaultDragZoneWidth = 5;
+               this.isPaused = false;
+               this.addAllEventListeners();
+       }
+
+       pause() {
+               this.isPaused = true;
+               this.removeAllEventListeners();
+       }
+
+       resume() {
+               if (this.isPaused) {
+                       this.addAllEventListeners();
+                       this.isPaused = false;
+               }
+       }
+
+       static isResizing() {
+               return document.body.classList.contains('resizing');
+       }
+
+       addAllEventListeners() {
+               this.removeAllEventListeners();
+               this.mouseout = this.mouseout.bind(this);
+               this.mousedown = this.mousedown.bind(this);
+               this.dispatchResizeStop = this.dispatchResizeStop.bind(this);
+               this.dispatchResize = this.dispatchResize.bind(this);
+               this.updateResizeCursor = this.updateResizeCursor.bind(this);
+               this.target.addEventListener('mousemove', this.updateResizeCursor, true);
+               this.target.addEventListener('mousedown', this.mousedown, true);
+               this.target.addEventListener('mousemove', this.dispatchResize, true);
+               this.target.addEventListener('mouseup', this.dispatchResizeStop, true);
+               this.target.addEventListener('mouseout', this.mouseout, true);
+       }
+
+       removeAllEventListeners() {
+               this.target.removeEventListener('mousemove', this.updateResizeCursor, true);
+               this.target.removeEventListener('mousedown', this.mousedown, true);
+               this.target.removeEventListener('mousemove', this.dispatchResize, true);
+               this.target.removeEventListener('mouseup', this.dispatchResizeStop, true);
+               this.target.removeEventListener('mouseout', this.mouseout, true);
+       }
+
+       makeResizableActive(d) {
+               this.activeResizable = d;
+       }
+
+       clearActiveResizable() {
+               this.activeResizable = null;
+       }
+
+       mouseout(e) {
+               if (this.resizing && (e.clientX > window.innerWidth || e.clientX < 0 || e.clientY < 0 || e.clientY > window.innerHeight)) {
+                       this.dispatchResizeStop(e);
+               }
+       }
+
+       mousedown(e) {
+               if (!this.resizing && this.activeResizable) {
+                       this.resizing = this.activeResizable;
+                       const zoomFactor = getZoomFactor();
+                       this.resizing.startX = e.clientX / zoomFactor;
+                       this.resizing.startY = e.clientY / zoomFactor;
+                       e.preventDefault();
+                       this.dispatchResizeStart(e);
+               }
+       }
+
+       dispatchResize(e) {
+               if (this.resizing && !this.resizeLimitReached) {
+                       e.preventDefault();
+                       const resizeEvent = createEvent.call(this, e, 'resize');
+                       this.resizing.target.dispatchEvent(resizeEvent)
+               }
+       }
+
+       dispatchResizeStart(e) {
+               if (this.resizing) {
+                       document.body.classList.add('resizing');
+                       e.preventDefault();
+                       const resizeEvent = createEvent.call(this, e, 'resize-start');
+                       this.resizing.target.dispatchEvent(resizeEvent)
+               }
+       }
+
+       dispatchResizeStop(e) {
+               if (this.resizing) {
+                       document.body.classList.remove('resizing');
+                       e.preventDefault();
+                       const resizeEvent = createEvent.call(this, e, 'resize-stop');
+                       this.resizing.target.dispatchEvent(resizeEvent);
+                       this.lastResizable = this.resizing;
+               } else {
+                       this.lastResizable = this.activeResizable;
+               }
+               this.clearActiveResizable();
+               this.resizing = null;
+       }
+
+       isResizing() {
+               return this.activeResizable && this.resizing;
+       }
+
+       updateResizeCursor(e) {
+               if (e.defaultPrevented) {
+                       if (this.activeResizable) {
+                               document.body.style.cursor = '';
+                               this.clearActiveResizable();
+                               this.dispatchResizeStop(e);
+                       }
+                       return;
+               }
+               const zoomFactor = getZoomFactor();
+               const x = e.clientX / zoomFactor;
+               const y = e.clientY / zoomFactor;
+               const resizables = Array.from(document.querySelectorAll('[resizable], [data-resizable]'));
+               if (this.isResizing()) {
+                       const others = resizables.filter(d => d !== this.activeResizable.target);
+                       this.resizeLimitReached = this.checkResizeLimitReached(x, y, others);
+                       return;
+               }
+               if (this.lastResizable) {
+                       resizables.unshift(this.lastResizable.target)
+               }
+               let resizable = null;
+               for (resizable of resizables) {
+                       const result = this.isCoordinatesOnDragZone(x, y, resizable);
+                       if (result.side === 'inside' || result.side === 'outside') {
+                               this.clearActiveResizable();
+                               // todo IE cursor flickers - now sure why might need to reduce the amount of classList updates
+                               document.body.classList.remove('-is-show-resize-cursor-col-resize');
+                               document.body.classList.remove('-is-show-resize-cursor-row-resize');
+                               document.body.classList.remove('-is-show-resize-cursor-nesw-resize');
+                               document.body.classList.remove('-is-show-resize-cursor-nwse-resize');
+                               document.body.style.cursor = '';
+                               continue
+                       }
+                       if (result.side === 'right' || result.side === 'left') {
+                               if (!document.body.classList.contains('-is-show-resize-cursor-col-resize')) {
+                                       document.body.classList.add('-is-show-resize-cursor-col-resize');
+                                       document.body.style.cursor = 'col-resize';
+                               }
+                       } else if (result.side === 'top' || result.side === 'bottom') {
+                               if (!document.body.classList.contains('-is-show-resize-cursor-row-resize')) {
+                                       document.body.classList.add('-is-show-resize-cursor-row-resize');
+                                       document.body.style.cursor = 'row-resize';
+                               }
+                       } else if (result.side === 'top-right' || result.side === 'bottom-left') {
+                               if (!document.body.classList.contains('-is-show-resize-cursor-nesw-resize')) {
+                                       document.body.classList.add('-is-show-resize-cursor-nesw-resize');
+                                       document.body.style.cursor = 'nesw-resize';
+                               }
+                       } else if (result.side === 'top-left' || result.side === 'bottom-right') {
+                               if (!document.body.classList.contains('-is-show-resize-cursor-nwse-resize')) {
+                                       document.body.classList.add('-is-show-resize-cursor-nwse-resize');
+                                       document.body.style.cursor = 'nwse-resize';
+                               }
+                       }
+                       this.makeResizableActive(result);
+                       break
+               }
+       }
+
+       checkResizeLimitReached(x, y, resizables) {
+               let hasReachedLimit = false;
+               if (this.isResizing()) {
+                       const sides = this.activeResizable.side.split('-');
+                       resizables.filter(resizable => {
+                               const resizableSide = resizable.dataset.resizable;
+                               return sides.filter(side => resizableSide.indexOf(sideComplement[side]) > -1).length;
+                       }).forEach(resizable => {
+                               const position = resizable.getBoundingClientRect();
+                               const zoneWidth = resizable.dataset.resizableDragZoneWidth || this.defaultDragZoneWidth;
+                               const resizableSide = resizable.dataset.resizable;
+                               const isLimit = /^limit/.test(resizableSide);
+                               sides.forEach(side => {
+                                       const key = (isLimit ? 'limit_' : '') + side;
+                                       if (resizeDragLimitForSide[key]) {
+                                               if (resizeDragLimitForSide[key](position, x, y, zoneWidth, this.resizing)) {
+                                                       hasReachedLimit = true;
+                                               }
+                                       }
+                               });
+                       });
+               }
+               return hasReachedLimit;
+       }
+
+       isCoordinatesOnDragZone(x, y, element) {
+               const result = {
+                       side: 'inside',
+                       target: element
+               };
+               const check = this.resizeDragZones;
+               const sides = element.dataset.resizable || 'top,right,bottom,left';
+               const zoneWidth = element.dataset.resizableDragZoneWidth || this.defaultDragZoneWidth;
+               const zoneOffsets = this.parseHandleOffsets(element.dataset.resizableHandleOffset);
+               const rect = element.getBoundingClientRect();
+               const position = {
+                       top: rect.top + zoneOffsets[0],
+                       right: rect.right + zoneOffsets[1],
+                       bottom: rect.bottom + zoneOffsets[2],
+                       left: rect.left + zoneOffsets[3]
+               };
+               const temp = [];
+               if (check.outside && check.outside(position, x, y, zoneWidth)) {
+                       result.side = 'outside';
+                       return result;
+               }
+               sides.split(/\W+|\s*,\s*/).forEach(side => {
+                       if (check[side]) {
+                               const r = check[side](position, x, y, zoneWidth);
+                               if (r) {
+                                       temp.push(r);
+                               }
+                       }
+               });
+               if (temp.length) {
+                       result.side = zoneName(temp);
+                       return result;
+               }
+               return result;
+       }
+
+       parseHandleOffsets(str) {
+               const val = String(str).trim().split(' ');
+               if (val.length === 0) {
+                       return defaultHandleOffset.splice();
+               }
+               return defaultHandleOffset.map((defaultOffset, i) => {
+                       let offset = parseFloat(val[i]);
+                       if (isNaN(offset)) {
+                               offset = parseFloat(val[i - 2]);
+                               if (isNaN(offset)) {
+                                       return defaultHandleOffset[i];
+                               }
+                       }
+                       return offset;
+               });
+       }
+
+}
+
+export default ResizableManager;
diff --git a/skyquake/plugins/composer/src/src/libraries/SelectionManager.js b/skyquake/plugins/composer/src/src/libraries/SelectionManager.js
new file mode 100644 (file)
index 0000000..94ab813
--- /dev/null
@@ -0,0 +1,380 @@
+/*global SVGSVGElement, SVGPathElement, SVGGElement*/
+/**
+ * Created by onvelocity on 2/6/16.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+import UID from './UniqueId'
+import React from 'react'
+import PathBuilder from './graph/PathBuilder'
+
+const SELECTIONS = '::private::selections';
+
+/**
+ * SelectionManager provides two features:
+ *     1) given DescriptorModel instances mark them as 'selected'
+ *     2) given DOM elements draw an outline around them
+ *
+ * Note that the consumer must call addSelection(descriptor) and outlineElement(dom) separately. This allows for complex
+ * selections to be separate from the outline indicator. It also allows for selection sets that do not have a visual
+ * outline associated with them.
+ */
+class SelectionManager {
+
+       static disableOutlineChanges() {
+               SelectionManager._disableOutlineChanges = true;
+       }
+
+       static enableOutlineChanges() {
+               SelectionManager._disableOutlineChanges = false;
+       }
+
+       static select(obj) {
+               const isSelected = SelectionManager.isSelected(obj);
+               if (!isSelected) {
+                       SelectionManager.clearSelectionAndRemoveOutline();
+                       SelectionManager.addSelection(obj);
+                       return true;
+               }
+       }
+
+       static isSelected(obj) {
+               const uid = UID.from(obj);
+               if (uid) {
+                       return SelectionManager[SELECTIONS].has(uid);
+               }
+       }
+
+       static getSelections() {
+               return Array.from(SelectionManager[SELECTIONS]).filter(d => d);
+       }
+
+       static addSelection(obj) {
+               const uid = UID.from(obj);
+               if (uid) {
+                       SelectionManager[SELECTIONS].add(uid);
+               }
+       }
+
+       static updateSelection(container, addOrRemove = true) {
+               if (addOrRemove) {
+                       SelectionManager.addSelection(container);
+               } else {
+                       SelectionManager.removeSelection(container);
+               }
+       }
+
+       static removeSelection(obj) {
+               const uid = UID.from(obj);
+               if (uid) {
+                       SelectionManager[SELECTIONS].delete(uid);
+               }
+       }
+
+       static get onClearSelection() {
+               return this._onClearSelection;
+       }
+
+       static set onClearSelection(callback) {
+               if (!this._onClearSelection) {
+                       this._onClearSelection = new Set();
+               }
+               if (typeof callback !== 'function') {
+                       throw new TypeError('onClearSelection only takes functions');
+               }
+               this._onClearSelection.add(callback);
+       }
+
+       static clearSelectionAndRemoveOutline() {
+               SelectionManager.removeOutline();
+               const unselected = SelectionManager.getSelections();
+               if (unselected.length) {
+                       SelectionManager[SELECTIONS].clear();
+                       if (SelectionManager.onClearSelection) {
+                               SelectionManager.onClearSelection.forEach(callback => callback(unselected));
+                       }
+               }
+               return unselected;
+       }
+
+       static removeOutline() {
+               Array.from(document.querySelectorAll('[data-outline-indicator-outline]')).forEach(n => d3.select(n).remove());
+       }
+
+       static refreshOutline() {
+               clearTimeout(SelectionManager.timeoutId);
+               SelectionManager.moveOutline();
+               SelectionManager.timeoutId = setTimeout(() => {
+                       // note the timeout is to wait for the react digest to complete
+                       // in the case this method is called from an Alt action....
+                       SelectionManager.moveOutline();
+               }, 100);
+       }
+
+       static moveOutline() {
+               SelectionManager.getSelections().forEach(uid => {
+                       Array.from(document.body.querySelectorAll(`[data-uid="${uid}"]`)).forEach(SelectionManager.outline.bind(this));
+               });
+       }
+
+       static outline(dom) {
+
+               const elements = Array.isArray(dom) ? dom : [dom];
+
+               elements.map(SelectionManager.getClosestElementWithUID).filter(d => d).forEach(element => {
+
+                       if (element instanceof SVGElement) {
+                               SelectionManager.outlineSvg(element);
+                       } else {
+                               SelectionManager.outlineDom(element);
+                       }
+
+               });
+
+       }
+
+       static outlineSvg(element) {
+
+               if (SelectionManager._disableOutlineChanges) {
+                       return
+               }
+
+               const svg = element.viewportElement;
+
+               if (!svg) {
+                       return
+               }
+
+               const path = new PathBuilder();
+
+               const dim = element.getBBox();
+               const adjustPos = SelectionManager.sumTranslates(element);
+
+               let w = dim.width + 11;
+               let h = dim.height + 11;
+               let top = adjustPos[1] - 8 + dim.y;
+               let left = adjustPos[0] - 8 + dim.x;
+
+               let square = path.M(5, 5).L(w, 5).L(w, h).L(5, h).L(5, 5).Z.toString();
+
+               let border = element;
+
+               // strategy copy the element to use as a foreground mask
+               // - this allows the item to appear above other items and
+               // - it makes the outline apear outside the element
+
+               const mask = d3.select(element.cloneNode(true));
+
+               if (border instanceof SVGPathElement) {
+                       const t = d3.transform(d3.select(element).attr('transform')).translate;
+                       square = d3.select(element).attr('d');
+                       top = t[1];
+                       left = t[0];
+               } else if (border instanceof SVGGElement) {
+                       const t = d3.transform(d3.select(element).attr('transform')).translate;
+                       border = d3.select(element).select('path.border');
+                       square = border.attr('d');
+                       top = t[1];
+                       left = t[0];
+               }
+
+
+               const data = {
+                       top: top,
+                       left: left,
+                       path: square
+               };
+
+               const indicator = svg.querySelector(['[data-outline-indicator]']) || svg;
+
+               const outline = d3.select(indicator).selectAll('[data-outline-indicator-outline]').data([data]);
+
+               outline.exit().remove();
+
+               // move to top of z-order
+               element.parentNode.appendChild(element);
+
+               outline.enter().append('g').attr({
+                       'data-outline-indicator-outline': true,
+                       'class': '-with-transitions'
+               }).style({
+                       'pointer-events': 'none'
+               }).append('g');
+
+               outline.attr({
+                       transform: d => `translate(${d.left}, ${d.top})`
+               });
+
+               outline.select('g').append('path').attr({
+                       'data-outline-indicator-svg-outline-path': true,
+                       'stroke': 'red',
+                       'fill': 'transparent',
+                       'fill-rule': 'evenodd',
+                       'stroke-width': 5,
+                       'stroke-linejoin': 'round',
+                       'stroke-dasharray': '4',
+                       'opacity': 1,
+                       d: d => d.path
+               }).transition().style({'stroke-width': 15});
+
+               const g = outline.select('g').node();
+               const children = Array.from(mask.node().childNodes);
+               if (children.length) {
+
+                       children.forEach(child => {
+                               g.appendChild(child);
+                       });
+
+                       // ensure the outline moves with the item during drag operations
+                       const observer = new MutationObserver(function(mutations) {
+                               mutations.forEach(function(mutation) {
+                                       const transform = d3.select(mutation.target).style('opacity', 0).attr('transform');
+                                       outline.attr({
+                                               transform: transform
+                                       });
+                               });
+                       });
+
+                       const config = {attributes: true, attributeOldValue: true, attributeFilter: ['transform']};
+
+                       observer.observe(element, config);
+
+               } else {
+
+                       if (mask.classed('connection')) {
+                               element.parentNode.appendChild(outline.node());
+                               element.parentNode.appendChild(element);
+                       } else {
+                               //mask.attr('transform', null);
+                               element.parentNode.appendChild(outline.node());
+                               element.parentNode.appendChild(element);
+                       }
+
+               }
+
+       }
+
+       static outlineDom(element) {
+
+               if (SelectionManager._disableOutlineChanges) {
+                       return
+               }
+
+               element = SelectionManager.getClosestElementWithUID(element);
+
+               const offsetParent = SelectionManager.offsetParent(element);
+
+               const dim = SelectionManager.offsetDimensions(element);
+               const w = dim.width + 11;
+               const h = dim.height + 11;
+
+
+               const path = new PathBuilder();
+               const square = path.M(5, 5).L(w, 5).L(w, h).L(5, h).L(5, 5).Z.toString();
+
+               const parentDim = SelectionManager.offsetDimensions(offsetParent);
+
+               const top = dim.top - parentDim.top;
+               const left = dim.left - parentDim.left;
+               const svg = d3.select(offsetParent).selectAll('[data-outline-indicator-outline]').data([{}]);
+               svg.enter().append('svg').attr({
+                       'data-outline-indicator-outline': true,
+                       width: parentDim.width + 20,
+                       height: parentDim.height + 23,
+                       style: `pointer-events: none; position: absolute; z-index: 999; top: ${top - 8}px; left: ${left - 8}px; background: transparent;`
+               }).append('g').append('path').attr({
+                       'data-outline-indicator-dom-outline-path': true,
+                       'stroke': 'red',
+                       'fill': 'transparent',
+                       'stroke-width': '1.5px',
+                       'stroke-linejoin': 'round',
+                       'stroke-dasharray': '4',
+                       d: square
+               });
+
+               svg.select('svg').attr({
+                       width: parentDim.width + 20,
+                       height: parentDim.height + 23,
+               }).select('path').attr({
+                       d: square
+               });
+
+               svg.exit().remove();
+
+       }
+
+       static getClosestElementWithUID(element) {
+               let target = element;
+               while (target) {
+                       if (UID.from(target)) {
+                               return target;
+                       }
+                       if (target === target.parentNode) {
+                               return;
+                       }
+                       target = target.parentNode;
+               }
+       }
+
+       static offsetParent(target) {
+               while (target) {
+                       if ((d3.select(target).attr('data-offset-parent')) || target.nodeName === 'BODY') {
+                               return target;
+                       }
+                       target = target.parentNode;
+               }
+               return document.body;
+       }
+
+       /**
+        * Util for determining the widest child of an offsetParent that is scrolled.
+        *
+        * @param offsetParent
+        * @returns {{top: Number, right: Number, bottom: Number, left: Number, height: Number, width: Number}}
+        */
+       static offsetDimensions (offsetParent) {
+
+               const elementDim = offsetParent.getBoundingClientRect();
+               const dim = {
+                       top: elementDim.top,
+                       right: elementDim.right,
+                       bottom: elementDim.bottom,
+                       left: elementDim.left,
+                       height: elementDim.height,
+                       width: elementDim.width
+               };
+
+               const overrideWidth = Array.from(offsetParent.querySelectorAll('[data-offset-width]'));
+               dim.width = overrideWidth.reduce((width, child) => {
+                       const dim = child.getBoundingClientRect();
+                       return Math.max(width, dim.width);
+               }, elementDim.width);
+
+               return dim;
+
+       }
+
+       static sumTranslates(element) {
+               let parent = element;
+               const result = [0, 0];
+               while (parent) {
+                       const t = d3.transform(d3.select(parent).attr('transform')).translate;
+                       result[0] += t[0];
+                       result[1] += t[1];
+                       if (!parent.parentNode || /svg/i.test(parent.nodeName) || parent === parent.parentNode) {
+                               return result;
+                       }
+                       parent = parent.parentNode;
+               }
+               return result;
+       }
+
+}
+
+// warn static variable to store all selections across instances
+SelectionManager[SELECTIONS] = SelectionManager[SELECTIONS] || new Set();
+
+export default SelectionManager;
diff --git a/skyquake/plugins/composer/src/src/libraries/ToggleElementHandler.js b/skyquake/plugins/composer/src/src/libraries/ToggleElementHandler.js
new file mode 100644 (file)
index 0000000..5623ff7
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * Created by onvelocity on 1/28/16.
+ *
+ * This function expects a React SyntheticEvent e.g. onClick and toggles the data-toggle element and adds the class '-is-toggled'.
+ *
+ * <h1 data-toggle="false" onClick={toggle}>Basic</h1>
+ + <div className="toggleable">more info here</div>
+ */
+
+'use strict';
+
+import getEventPath from './getEventPath'
+
+import '../styles/ToggleElement.scss'
+
+
+export default function toggle(event) {
+       if (event.defaultPrevented) return;
+       const target = getEventPath(event).reduce((r, node) => {
+               if (r) {
+                       return r;
+               }
+               if (node && node.dataset && node.dataset.hasOwnProperty('toggle')) {
+                       return node;
+               }
+       }, false);
+       if (target) {
+               const value = String(target.dataset.toggle) !== 'true';
+               target.dataset.toggle = value;
+               target.classList.toggle('-is-toggled', value);
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/TooltipManager.js b/skyquake/plugins/composer/src/src/libraries/TooltipManager.js
new file mode 100644 (file)
index 0000000..3c792e7
--- /dev/null
@@ -0,0 +1,66 @@
+/*global Element*/
+/**
+ * Created by onvelocity on 2/22/16.
+ */
+
+'use strict';
+
+import d3 from 'd3'
+
+import '../styles/TooltipManager.scss'
+
+class TooltipManager {
+
+       static addEventListeners(element = document.body) {
+               TooltipManager.element = element;
+               TooltipManager.removeEventListeners();
+               TooltipManager.element.addEventListener('mousedown', TooltipManager.onScrollRemoveTooltip, true);
+               TooltipManager.element.addEventListener('scroll', TooltipManager.onScrollRemoveTooltip, true);
+       }
+
+       static removeEventListeners() {
+               if (TooltipManager.element) {
+                       TooltipManager.element.removeEventListener('mousedown', TooltipManager.onScrollRemoveTooltip, true);
+                       TooltipManager.element.removeEventListener('scroll', TooltipManager.onScrollRemoveTooltip, true);
+               }
+       }
+
+       static onScrollRemoveTooltip() {
+               TooltipManager.hideTooltip();
+       }
+
+       static showTooltip(dom, timeout = 2500) {
+               TooltipManager.hideTooltip();
+               const data = d3.select(dom).attr('data-tip');
+               const tip = d3.select(TooltipManager.element).selectAll('.tooltip-indicator').data([data]);
+               const rect = dom.getBoundingClientRect();
+               // position is handled fairly well by CSS for the bottom (default) position
+               // new code will be needed to support other positions, e.g. top, left, etc.
+               const position = {
+                       opacity: 0,
+                       position: 'absolute',
+                       'pointer-events': 'none',
+                       top: rect.bottom + 'px' ,
+                       left: (rect.left + (rect.width / 2)) + 'px'
+               };
+               const enter = tip.enter('div').append('div').classed('tooltip-indicator', true);
+               enter.append('i').classed('tooltip-indicator-arrow arrow-up', true);
+               enter.append('span').classed('tooltip-indicator-content', true);
+               tip.style(position).transition().style('opacity', 1);
+               tip.select('span').html(d => d);
+               if (timeout > 0) {
+                       TooltipManager.timeoutId = setTimeout(() => tip.transition().style('opacity', 0), timeout);
+               }
+               tip.exit().remove();
+       }
+
+       static hideTooltip() {
+               clearTimeout(TooltipManager.timeoutId);
+               d3.selectAll('.tooltip-indicator').remove();
+       }
+
+}
+
+TooltipManager.addEventListeners();
+
+export default TooltipManager;
diff --git a/skyquake/plugins/composer/src/src/libraries/UniqueId.js b/skyquake/plugins/composer/src/src/libraries/UniqueId.js
new file mode 100644 (file)
index 0000000..8f7344e
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Created by onvelocity on 2/12/16.
+ */
+'use strict';
+import d3 from 'd3'
+import guid from './guid'
+import DescriptorModel from './model/DescriptorModel'
+export default class UID {
+
+       static get propertyName() {
+               return ':uid';
+       }
+
+       static create() {
+               return guid();
+       }
+
+       static from(obj) {
+               if (!obj || /undefined|null/.test(obj)) {
+                       return;
+               }
+               if (obj instanceof DescriptorModel) {
+                       // a descriptor instance
+                       return obj.uid;
+               }
+               if (obj.dataset && obj.dataset.uid) {
+                       // DOM Element
+                       obj = obj.dataset.uid;
+               } else if (obj.__data__ && obj.__data__.uid) {
+                       // d3 managed element
+                       obj = obj.__data__.uid;
+               } else if (obj instanceof Element) {
+                       obj = d3.select(obj).attr('data-uid');
+               }
+               if (!obj || /undefined|null/.test(obj)) {
+                       return;
+               }
+               const uid = typeof obj === 'object' ? obj[UID.propertyName] || (obj.uiState && obj.uiState[UID.propertyName]) : obj;
+               if (typeof uid === 'string') {
+                       return uid;
+               }
+       }
+
+       static hasUniqueId(obj) {
+               return !!UID.from(obj);
+       }
+
+       static assignUniqueId(obj) {
+               return obj[UID.propertyName] = UID.create();
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/getEventPath.js b/skyquake/plugins/composer/src/src/libraries/getEventPath.js
new file mode 100644 (file)
index 0000000..ca5d6b9
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * Created by onvelocity on 2/3/16.
+ */
+'use strict';
+export default function getEventPath(event) {
+       if (event.path) {
+               return event.path;
+       }
+       if (event.nativeEvent && event.nativeEvent.path) {
+               return event.nativeEvent.path;
+       }
+       // for browsers, like IE, that don't have event.path
+       let node = event.target;
+       const path = [];
+       // Array.unshift means put the value on the top of the array
+       const addToPath = (value) => path.unshift(value);
+       // warn: some browsers set the root's parent to itself
+       while (node && node !== node.parentNode) {
+               addToPath(node);
+               node = node.parentNode;
+       }
+       return path;
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraph.js b/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraph.js
new file mode 100644 (file)
index 0000000..b70c921
--- /dev/null
@@ -0,0 +1,167 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/24/15.
+ */
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+import math from './math'
+import ClassNames from 'classnames'
+import ColorGroups from '../ColorGroups'
+import DescriptorModel from './../model/DescriptorModel'
+import DescriptorModelFactory from './../model/DescriptorModelFactory'
+import DescriptorGraphSelection from './DescriptorGraphSelection'
+import DescriptorGraphEdgeBuilder from './DescriptorGraphPathBuilder'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import DescriptorGraphGrid from './DescriptorGraphGrid'
+import SelectionManager from './../SelectionManager'
+import GraphConnectionPointNumber from './GraphConnectionPointNumber'
+import RelationsAndNetworksLayout from './layouts/RelationsAndNetworksLayout'
+
+const defaults = {
+       width: 1000,
+       height: 500,
+       padding: 10,
+       snapTo: 15,
+       zoom: 100,
+       connectionPointSize: 135
+};
+
+export default class DescriptorGraph {
+
+       constructor(element, props) {
+
+               this.element = element;
+               this.props = Object.assign({}, props, defaults);
+               this.layouts = [RelationsAndNetworksLayout];
+               this.containers = [];
+               this.showMoreInfo = false;
+               this.scale = 1;
+
+               if (!element) {
+                       throw new ReferenceError('An HTML DOM element is required to render DescriptorGraph.');
+               }
+
+               this.svg = d3.select(element).append('svg')
+                       .attr('class', 'DescriptorGraph')
+                       .attr('width', this.props.width)
+                       .attr('height', this.props.height)
+                       .attr('data-offset-parent', true);
+
+               this.g = this.svg.append('g')
+                       .attr('class', 'viewport');
+
+               // set the scale of everything
+               this.zoom(this.props.zoom || defaults.zoom);
+
+               this.defs = this.svg.append('defs');
+               this.grid = this.g.append('g').classed('grid', true);
+               this.paths = this.g.append('g').classed('paths', true);
+               this.connectorsGroup = this.g.append('g').classed('connectors', true);
+               this.containersGroup = this.g.append('g').classed('containers', true);
+               this.cpNumbers = this.g.append('g').classed('connection-point-numbers', true);
+               this.forwardingGraphPaths = this.g.append('g').classed('forwarding-graph-paths', true);
+               this.selectionOutlineGroup = this.g.append('g').attr('data-outline-indicator', true);
+
+               this.defs.append('marker')
+                       .attr({
+                               id: 'relation-marker-end',
+                               'markerWidth': 30,
+                               'markerHeight': 30,
+                               'orient': '0',
+                               //markerUnits: 'userSpaceOnUse'
+                               viewBox: '-15 -15 30 30'
+                       })
+                       .append('path')
+                       .attr({
+                               d: d3.svg.symbol().type('circle'),
+                               'class': 'relation-marker-end'
+                       });
+
+               this.update();
+
+       }
+
+       zoom(zoom) {
+               const scale = zoom / 100;
+               if (this.scale !== scale) {
+                       this.scale = scale;
+                       const transform = 'scale(' + this.scale + ')';
+                       requestAnimationFrame(() => {
+                               this.g.attr('transform', transform);
+                       });
+               }
+       }
+
+       get containerPositionMap() {
+               if (this.containers[0].uiState.containerPositionMap) {
+                       return this.containers[0].uiState.containerPositionMap;
+               } else {
+                       return this.containers[0].uiState.containerPositionMap = {};
+               }
+       }
+
+       lookupSavedContainerPosition(container) {
+               return this.containerPositionMap[container.key];
+       }
+
+       saveContainerPosition(container) {
+               this.containerPositionMap[container.key] = container.position.value();
+       }
+
+       update() {
+
+               const graph = this;
+
+               const filterContainers = d => (graph.showMoreInfo ? true : d.type !== 'vdu');
+               const containers = this.containers.filter(filterContainers);
+               const layouts = graph.layouts.map(layoutFactory => layoutFactory.bind(this)());
+
+               function runLayout(i) {
+                       const layout = layouts[i];
+                       if (layout) {
+                               layout.addContainers(containers);
+                               layout.render(graph, runLayout.bind(null, i + 1));
+                       }
+               }
+               runLayout(0);
+
+               const selection = new DescriptorGraphSelection(graph);
+               selection.addContainers(containers);
+               selection.render();
+
+               const edgeBuilder = new DescriptorGraphEdgeBuilder(graph);
+               edgeBuilder.addContainers(containers);
+               edgeBuilder.render();
+
+               const grid = new DescriptorGraphGrid(graph, {size: defaults.snapTo, padding: defaults.padding});
+               grid.render();
+
+       }
+
+       destroy() {
+               if (this.svg) {
+                       this.svg.remove();
+                       delete this.svg;
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphGrid.js b/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphGrid.js
new file mode 100644 (file)
index 0000000..4389321
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 12/3/15.
+ */
+
+import d3 from 'd3'
+
+const defaults = {
+       size: 15,
+       padding: 5
+};
+
+export default class DescriptorGraphGrid {
+
+       constructor(graph, props) {
+               this.graph = graph;
+               Object.assign(props, defaults);
+               this.size = props.size;
+               this.padding = props.padding;
+       }
+
+       render() {
+
+               const grid = this.graph.grid;
+               const width = 2 * this.graph.svg.attr('width');
+               const height = 2 * this.graph.svg.attr('height');
+               const yAxis = d3.range(0, height, this.size);
+               const xAxis = d3.range(0, width, this.size);
+
+               grid.selectAll('line.vertical')
+                       .data(xAxis)
+                       .enter().append('svg:line')
+                       .classed('vertical', true)
+                       .attr('x1', (d) => d)
+                       .attr('y1', 0)
+                       .attr('x2', (d) => d)
+                       .attr('y2', height);
+
+               grid.selectAll('line.horizontal')
+                       .data(yAxis)
+                       .enter().append('svg:line')
+                       .classed('horizontal', true)
+                       .attr('x1', 0)
+                       .attr('y1', (d) => d)
+                       .attr('x2', width)
+                       .attr('y2', (d) => d);
+
+       }
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphPathBuilder.js b/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphPathBuilder.js
new file mode 100644 (file)
index 0000000..2998dd0
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Draw edges by dragging a VirtualNetworkFunctionConnectionPoint to VNFD, VLD or another VirtualNetworkFunctionConnectionPoint.
+ *
+ * If VLD does not exist between two VNFDs then add one.
+ *
+ * CSS for this class is defined in DescriptorGraph.scss.
+ *
+ */
+
+import d3 from 'd3'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import SelectionManager from '../SelectionManager'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+
+const line = d3.svg.line()
+       .x(d => {
+               return d.x;
+       })
+       .y(d => {
+               return d.y;
+       });
+
+function mouseWithinPosition(position, mouseCoordinates, scale = 1) {
+       const x = mouseCoordinates[0] / scale;
+       const y = mouseCoordinates[1] / scale;
+       const withinXBoundary = position.left < x && position.right > x;
+       const withinYBoundary = position.top < y && position.bottom > y;
+       return withinXBoundary && withinYBoundary;
+}
+
+function getContainerUnderMouse(comp, element, scale) {
+       const mouseCoordinates = d3.mouse(element);
+       return comp.descriptorsAndConnectionPoints().filter(d => {
+               return DescriptorModelFactory.isConnectionPoint(d) ||
+                       DescriptorModelFactory.isInternalConnectionPoint(d) ||
+                       DescriptorModelFactory.isVirtualLink(d) ||
+                       DescriptorModelFactory.isInternalVirtualLink(d);
+       }).filter(d => mouseWithinPosition(d.position, mouseCoordinates, scale));
+}
+
+export default class DescriptorGraphPathBuilder {
+
+       constructor(graph) {
+               this.graph = graph;
+               this.containers = [];
+       }
+
+       descriptorsAndConnectionPoints() {
+               return this.graph.g.selectAll('.descriptor, .connector');
+       }
+
+       descriptors() {
+               return this.graph.containersGroup.selectAll('.descriptor');
+       }
+
+       connectionPoints() {
+               return this.graph.connectorsGroup.selectAll('.connector');
+       }
+
+       paths() {
+               return this.graph.g.selectAll('.connection');
+       }
+
+       addContainers(containers) {
+               this.containers = this.containers.concat(containers);
+       }
+
+       static addConnection(srcConnector, dstConnector) {
+
+               // return true on success; falsy otherwise to allow the caller to clean up accordingly
+
+               if (!(srcConnector || dstConnector)) {
+                       return false;
+               }
+
+               if (srcConnector.canConnectTo && srcConnector.canConnectTo(dstConnector)) {
+
+                       const root = srcConnector.getRoot();
+
+                       if (DescriptorModelFactory.isVirtualLink(dstConnector) || DescriptorModelFactory.isInternalVirtualLink(dstConnector)) {
+                               dstConnector.addConnectionPoint(srcConnector);
+                       } else {
+                               if (root) {
+                                       const vld = root.createVld();
+                                       root.removeAnyConnectionsForConnector(srcConnector);
+                                       root.removeAnyConnectionsForConnector(dstConnector);
+                                       vld.addConnectionPoint(srcConnector);
+                                       vld.addConnectionPoint(dstConnector);
+                               }
+                       }
+
+                       // notify catalog items have changed to force a redraw and update state accordingly
+                       CatalogItemsActions.catalogItemDescriptorChanged(root);
+
+                       return true;
+
+               }
+
+       }
+
+       static addConnectionToVLD(srcSelection, dstSelection) {
+
+               if (srcSelection[0].length === 0 || dstSelection[0].length === 0) {
+                       return false;
+               }
+
+               const dstVirtualLink = dstSelection.datum();
+               const srcConnectionPoint = srcSelection.datum();
+
+               dstVirtualLink.addConnectionPoint(srcConnectionPoint);
+
+               // notify catalog items have changed to force a redraw and update state accordingly
+               CatalogItemsActions.catalogItemDescriptorChanged(dstVirtualLink.getRoot());
+
+               return true;
+
+       }
+
+       render() {
+
+               /*
+                       Strategy: compare mouse position with the position of all the selectable elements.
+                       On mouse down:
+                           determine if there is a connection point under the mouse (the source)
+                           determine if there is already a path connected on this source
+                       On mouse move:
+                           draw a tracer line from the source to the mouse
+                       On mouse up:
+                           determine if there is a connection point or VLD under the mouse (the destination)
+                           take the respective action and notify
+                */
+
+               const comp = this;
+               const drawLine = line.interpolate('basis');
+
+               comp.boundMouseDownHandler = function (d) {
+
+                       let hasInitializedMouseMoveHandler = false;
+
+                       const srcConnectionPoint = comp.connectionPoints().filter(d => {
+                               return DescriptorModelFactory.isConnectionPoint(d) || DescriptorModelFactory.isInternalConnectionPoint(d);
+                       }).filter(d => mouseWithinPosition(d.position, d3.mouse(this), comp.graph.scale));
+
+                       if (srcConnectionPoint[0].length) {
+
+                               const src = srcConnectionPoint.datum() || {};
+
+                               // determine if there is already a path on this connection point
+                               // if there is then hide it; the mouseup handler will clean up
+                               const existingPath = comp.paths().filter(d => {
+                                       return d && d.parent && d.parent.type === 'vld' && d.key === src.key;
+                               });
+
+                               // create a new path to follow the mouse
+                               const path = comp.graph.paths.selectAll('.new-connection').data([srcConnectionPoint.datum()], DescriptorModelFactory.containerIdentity);
+                               path.enter().append('path').classed('new-connection', true);
+
+                               comp.boundMouseMoveHandler = function () {
+
+                                       const mouseCoordinates = d3.mouse(this);
+
+                                       path.attr({
+                                               fill: 'red',
+                                               stroke: 'red',
+                                               'stroke-width': '4px',
+                                               d: d => {
+                                                       const srcPosition = d.position.centerPoint();
+                                                       const dstPosition = {
+                                                               x: mouseCoordinates[0] / comp.graph.scale,
+                                                               y: mouseCoordinates[1] / comp.graph.scale
+                                                       };
+                                                       return drawLine([srcPosition, dstPosition]);
+                                               }
+                                       });
+
+                                       if (!hasInitializedMouseMoveHandler) {
+
+                                               hasInitializedMouseMoveHandler = true;
+
+                                               SelectionManager.removeOutline();
+
+                                               existingPath.style({
+                                                       opacity: 0
+                                               });
+
+                                               // allow for visual treatment of this drag operation
+                                               srcConnectionPoint.classed('-selected', true);
+
+                                               // allow for visual treatment of this drag operation
+                                               comp.graph.svg.classed('-is-dragging-connection-point', true);
+
+                                               // identify which descriptors are a valid drop target
+                                               comp.descriptors().filter(d => {
+                                                       const validTarget = src.canConnectTo && src.canConnectTo(d);
+                                                       return validTarget;
+                                               }).classed('-is-valid-drop-target', true);
+
+                                               // identify which connection points are a valid drop target
+                                               comp.connectionPoints().filter(d => {
+                                                       const validTarget = src.canConnectTo && src.canConnectTo(d);
+                                                       return validTarget;
+                                               }).classed('-is-valid-drop-target', true);
+
+                                       }
+
+                                       const validDropTarget = getContainerUnderMouse(comp, this, comp.graph.scale);
+                                       comp.graph.g.selectAll('.-is-drag-over').classed('-is-drag-over', false);
+                                       SelectionManager.removeOutline();
+                                       if (validDropTarget) {
+                                               validDropTarget
+                                                       .filter(d => src.canConnectTo && src.canConnectTo(d))
+                                                       .classed('-is-drag-over', true)
+                                                       .each(function () {
+                                                               // warn must be a function so 'this' will = the path element
+                                                               SelectionManager.outlineSvg(this);
+                                                       });
+                                       }
+
+                               };
+
+                               // determine what the interaction is and do it
+                               comp.boundMouseUpHandler = function () {
+
+                                       // remove these handlers so they start fresh on the next drag operation
+                                       comp.graph.svg
+                                               .on('mouseup.edgeBuilder', null)
+                                               .on('mousemove.edgeBuilder', null);
+
+                                       // remove visual treatments
+                                       comp.graph.svg.classed('-is-dragging-connection-point', false);
+                                       comp.descriptors().classed('-is-valid-drop-target', false);
+                                       comp.connectionPoints().classed('-is-valid-drop-target', false);
+                                       comp.graph.g.selectAll('.-is-drag-over').classed('-is-drag-over', false);
+
+                                       const dstSelection = getContainerUnderMouse(comp, this, comp.graph.scale);
+
+                                       // determine if there is a connection point
+                                       if (dstSelection[0].length) {
+                                               if (DescriptorGraphPathBuilder.addConnection(src, dstSelection.datum())) {
+                                                       existingPath.remove();
+                                               }
+                                       }
+
+                                       // if we hid an existing path restore it
+                                       existingPath.style({
+                                               opacity: null
+                                       });
+
+                                       // remove the tracer path
+                                       path.remove();
+
+                                       SelectionManager.refreshOutline();
+
+                               };
+
+                               // init drag handlers
+                               comp.graph.svg
+                                       .on('mouseup.edgeBuilder', comp.boundMouseUpHandler)
+                                       .on('mousemove.edgeBuilder', comp.boundMouseMoveHandler);
+                       }
+
+               };
+
+               // enable dragging features
+               comp.graph.svg
+                       .on('mousedown.edgeBuilder', comp.boundMouseDownHandler);
+
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphSelection.js b/skyquake/plugins/composer/src/src/libraries/graph/DescriptorGraphSelection.js
new file mode 100644 (file)
index 0000000..f74a872
--- /dev/null
@@ -0,0 +1,83 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Provide the visual treatment for selecting elements in the Canvas.
+ *
+ * Clicking on a Descriptor toggles selection.
+ * Clicking on a Path toggles selection.
+ * Clicking on the SVG container removes selection.
+ * Only one thing can be selected at a time.
+ *
+ */
+import d3 from 'd3'
+import DescriptorModelFactory from './../model/DescriptorModelFactory'
+import ComposerAppActions from '../../actions/ComposerAppActions'
+import SelectionManager from '../SelectionManager'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+
+export default class DescriptorGraphSelection {
+
+       constructor(graph) {
+               this.graph = graph;
+               this.containers = [];
+       }
+
+       addContainers(containers) {
+               this.containers = containers;
+       }
+
+       render() {
+
+               const comp = this;
+
+               // prevent multiple bindings of the same listener
+               this.unbindListeners();
+
+               // clicking on the background deselects all descriptors
+               comp.boundClickSVGHandler = function () {
+                       // do not deselect if user is dragging: https://github.com/mbostock/d3/issues/1445
+                       if (d3.event.defaultPrevented) return;
+                       const target = SelectionManager.getClosestElementWithUID(d3.event.target);
+                       if (target) {
+                               const data = d3.select(target).datum() || {};
+                               if (target && DescriptorModelFactory.isContainer(data)) {
+                                       ComposerAppActions.selectModel(data);
+                                       ComposerAppActions.outlineModel(data);
+                               } else {
+                                       ComposerAppActions.clearSelection();
+                               }
+                       } else {
+                               ComposerAppActions.clearSelection();
+                       }
+               };
+               comp.graph.svg.on('click.selection', comp.boundClickSVGHandler);
+
+       }
+
+       unbindListeners() {
+               this.graph.svg.on('.selection', null);
+       }
+
+       destroy() {
+               this.unbindListeners();
+               this.containers.length = 0;
+               this.graph = null;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphConnectionPointNumber.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphConnectionPointNumber.js
new file mode 100644 (file)
index 0000000..07af002
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * Created by onvelocity on 2/8/16.
+ */
+'use strict';
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+const defaults = {
+       adjustTop: -9,
+       adjustBottom: 21
+};
+export default class GraphConnectionPointNumber {
+
+       constructor(graph, props) {
+               this.cpNumbersGroup = graph.cpNumbers;
+               Object.assign(this, defaults, props);
+               this.containers = [];
+       }
+
+       addContainers(containers) {
+               this.containers = containers.filter(d => DescriptorModelFactory.isConnectionPoint(d) && DescriptorModelFactory.isNetworkService(d.getRoot()));
+       }
+
+       render() {
+               const cpNumber = this.cpNumbersGroup.selectAll('.connection-point-number').data(this.containers, d => d.uid);
+               cpNumber.enter().append('text').text(d => d.uiState.cpNumber);
+               cpNumber.attr({
+                       'data-key': d => d.key,
+                       'data-cp-number': d => d.uiState.cpNumber,
+                       'text-anchor': 'middle',
+                       'class': 'connection-point-number',
+                       transform: d => {
+                               const point = d.position.centerPoint();
+                               const yAdjust = (/top/.test(d.location) ? this.adjustTop : this.adjustBottom);
+                               return 'translate(' + (point.x) + ', ' + (point.y + yAdjust) + ')';
+                       }
+               });
+               cpNumber.exit().remove();
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphConstituentVnfd.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphConstituentVnfd.js
new file mode 100644 (file)
index 0000000..8fd80b6
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+
+import d3 from 'd3'
+import SelectionManager from '../SelectionManager.js'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import DescriptorGraphSelection from './DescriptorGraphSelection'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import GraphVirtualNetworkFunction from './GraphVirtualNetworkFunction'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+export default class GraphConstituentVnfd extends GraphDescriptorModel {
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.ConstituentVnfd, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphDescriptorModel.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphDescriptorModel.js
new file mode 100644 (file)
index 0000000..cc323af
--- /dev/null
@@ -0,0 +1,243 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+
+import d3 from 'd3'
+import ColorGroups from '../ColorGroups'
+import PathBuilder from '../graph/PathBuilder'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import DescriptorGraphSelection from './DescriptorGraphSelection'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import HighlightRecordServicePaths from './HighlightRecordServicePaths'
+import ComposerAppActions from '../../actions/ComposerAppActions'
+
+import '../../styles/GraphDescriptorModel.scss'
+
+const iconTitles = {
+       'vnffgd': 'fg',
+       'constituent-vnfd': 'vnf',
+       'nsd': 'ns',
+       'vnfd': 'vnf',
+       'vld': 'vl',
+       'internal-vld': 'vl'
+};
+
+export default class GraphDescriptorModel {
+
+       constructor(graph, classType, props = {}) {
+               this.props = {};
+               this.graph = graph;
+               this.classType = classType;
+               this.containers = [];
+               this._dragHandler = () => {};
+               if (!classType) {
+                       throw TypeError('Expect class type to be provided. Did you forget to pass in a class type, for example, DescriptorModelFactory.VirtualNetworkFunction?');
+               }
+               const defaults = {type: classType.type, className: classType.className, selector: [classType.className, classType.type, 'descriptor']};
+               this.props = Object.assign(this.props, defaults, {descriptorBorderRadius: 20, descriptorWidth: 250, descriptorHeight: 55}, props);
+               GraphDescriptorModel.buildRef(classType.type, this.graph.defs);
+       }
+
+       addContainers(containers) {
+               this.containers = containers.filter(d => d instanceof this.classType);
+       }
+
+       get dragHandler() {
+               return this._dragHandler;
+       }
+
+       set dragHandler(drag) {
+               this._dragHandler = drag;
+       }
+
+       render() {
+
+               const g = this.graph.containersGroup;
+
+               const descriptor = g.selectAll('.' + this.props.selector.join('.')).data(this.containers, DescriptorModelFactory.containerIdentity);
+
+               const path = new PathBuilder();
+
+               const descriptorPath = PathBuilder.descriptorPath(this.props.descriptorBorderRadius, this.props.descriptorHeight, this.props.descriptorWidth).toString();
+
+               // ENTER
+               const box = descriptor.enter().append('g')
+                       .attr({
+                               'data-uid': d => d.uid,
+                               'data-key': d => d.key,
+                               'class': d => {
+                                       return this.props.selector.join(' ');
+                               }
+                       }).on('cut', (container) => {
+
+                               let success = false;
+
+                               if (container && container.remove) {
+                                       success = container.remove();
+                               }
+
+                               if (success) {
+                                       CatalogItemsActions.catalogItemDescriptorChanged(container.getRoot());
+                               } else {
+                                       d3.event.preventDefault();
+                               }
+
+                               d3.event.stopPropagation();
+
+                       }).call(this.dragHandler);
+
+               box.append('path')
+                       .attr({
+                               class: d => d.type + '-descriptor-model-background-layer background-layer',
+                               d: descriptorPath,
+                               fill: ColorGroups.common.background,
+                               stroke: ColorGroups.common.background,
+                               'stroke-width': '2px'
+                       });
+
+               box.append('path')
+                       .attr({
+                               class: d => d.type + '-descriptor-model-background background',
+                               d: descriptorPath,
+                               fill: d => `url(#${d.type}-descriptor-model-badge-fill)`,
+                               stroke: 'transparent',
+                               'stroke-width': '2px'
+                       });
+
+               box.append('path')
+                       .attr({
+                               class: d => d.type + '-descriptor-model-border border',
+                               d: descriptorPath,
+                               fill: 'transparent',
+                               stroke: d => ColorGroups.getColorPairForType(d.type).secondary,
+                               'stroke-width': 1.25
+                       }).style({opacity: 0.75});
+
+               box.append('path').attr({
+                       class: d => d.type + '-icon icon',
+                       d: d => d.icon.d,
+                       transform: d => `translate(${d.icon.translate ? d.icon.translate : '-4, 2'}) rotate(0) scale(${24 / d.icon.width}, ${24 / d.icon.width})`,
+                       fill: 'white',
+                       stroke: 'white'
+               });
+
+               box.append('text')
+                       .attr({
+                               class:d => d.type + '-type type',
+                               'font-weight': 100,
+                               'font-size': '12px',
+                               'text-anchor': 'middle',
+                               'text-transform': 'uppercase',
+                               fill: 'white',
+                               stroke: 'white',
+                               x: 13,
+                               y: 49
+                       }).text(d => iconTitles[d.type] || d.type).style({opacity: 1});
+
+               box.append('text')
+                       .attr({
+                               class: d => d.type + '-title title',
+                               'font-weight': 100,
+                               'font-size': '12px',
+                               'text-anchor': 'middle',
+                               x: (d) => {
+                                       const left = 0;
+                                       const widthOffset = (d.position.width / 2) + 20;
+                                       return left + widthOffset;
+                               },
+                               y: (d) => {
+                                       const top = 0;
+                                       const height = d.position.height;
+                                       const heightOffset = height / 2;
+                                       const textHeightOffset = 12 / 2;
+                                       return top + heightOffset + textHeightOffset;
+                               }
+                       });
+
+               box.each(function (d) {
+                       if (DescriptorModelFactory.isForwardingGraph(d)) {
+                               const box = d3.select(this);
+
+                               d.rsp.forEach((rsp, i) => {
+                                       const colorLegend = box.append('g').attr({
+                                               class:d => d.type + '-rsp-color-legend color-legend',
+                                               transform: d => {
+                                                       const widthOffset = d.position.width - 20 - (i * 26);
+                                                       const heightOffset = d.position.height - 10;
+                                                       return `translate(${widthOffset}, ${heightOffset})`;
+                                               }
+                                       });
+                                       colorLegend.append('ellipse').classed('colors', true).attr({
+                                               rx: 12,
+                                               ry: 7.5,
+                                               fill: d => d.colors && d.colors.primary,
+                                               stroke: d => d.colors && d.colors.secondary
+                                       }).on('mouseenter', function (d) {
+                                               HighlightRecordServicePaths.highlightPaths(rsp);
+                                       }).on('mouseout', function () {
+                                               HighlightRecordServicePaths.removeHighlighting();
+                                       }).on('mouseleave', function () {
+                                               HighlightRecordServicePaths.removeHighlighting();
+                                       }).on('click', function () {
+                                               d3.event.preventDefault();
+                                               ComposerAppActions.selectModel(rsp);
+                                       });
+                               });
+
+                       }
+               });
+
+
+               // ENTER & UPDATE
+               descriptor.attr({
+                       transform: d => {
+                               const x = d.position.left;
+                               const y = d.position.top;
+                               return 'translate(' + x + ', ' + y + ')';
+                       }
+               });
+
+               descriptor.select('text.title')
+                       .text(d => {
+                               return d.title;
+                       });
+
+               // EXIT
+               descriptor.exit()
+                       .remove();
+
+       }
+
+       static buildRef(type, defs) {
+               if (defs.selectAll('#' + type + '-descriptor-model-badge-fill')[0].length === 0) {
+                       var vld = defs.append('pattern').attr({
+                               id: type + '-descriptor-model-badge-fill',
+                               //patternUnits: 'userSpaceOnUse',
+                               patternContentUnits: 'objectBoundingBox',
+                               width: 1,
+                               height: 1,
+                               viewBox: '0 0 1 1',
+                               preserveAspectRatio: 'none'
+                       });
+                       vld.append('rect').attr({
+                               width: 1,
+                               height: 1,
+                               fill: 'white'//ensure transparent layers keep their color
+                       });
+                       vld.append('rect').attr({
+                               width: 1,
+                               height: 1,
+                               fill: ColorGroups.getColorPairForType(type).secondary
+                       }).style({opacity: 1});
+                       vld.append('rect').attr({
+                               y: 0,
+                               x: 0.22,
+                               width: 1,
+                               height: 1,
+                               fill: ColorGroups.common.background
+                       });
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphForwardingGraph.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphForwardingGraph.js
new file mode 100644 (file)
index 0000000..7cdd549
--- /dev/null
@@ -0,0 +1,15 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+export default class GraphForwardingGraph extends GraphDescriptorModel {
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.ForwardingGraph, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphInternalVirtualLink.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphInternalVirtualLink.js
new file mode 100644 (file)
index 0000000..cb78911
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+
+import d3 from 'd3'
+import ClassNames from 'classnames'
+import ColorGroups from '../ColorGroups'
+import SelectionManager from '../SelectionManager.js'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import DescriptorGraphSelection from './DescriptorGraphSelection'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+import '../../styles/GraphVirtualLink.scss'
+
+export default class GraphInternalVirtualLink extends GraphDescriptorModel {
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.InternalVirtualLink, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphInternalVirtualLinkPaths.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphInternalVirtualLinkPaths.js
new file mode 100644 (file)
index 0000000..b043b4d
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * Created by onvelocity on 2/15/16.
+ */
+
+import math from './math'
+import PathBuilder from './PathBuilder'
+import ColorGroups from '../ColorGroups'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+
+/**
+ *
+ * This class draws the paths between the VLD and the Connection Point it references.
+ *
+ */
+
+const line = d3.svg.line()
+       .x(d => {
+               return d.x;
+       })
+       .y(d => {
+               return d.y;
+       });
+
+export default class GraphVirtualLinkPaths {
+
+       constructor(graph, props) {
+               this.graph = graph;
+               this.props = props;
+               this.maps = new WeakMap();
+               this.maps.set(this, {vld: {}, containers: new Set()});
+       }
+
+       findVldForInternalConnectionPoint(icp) {
+               const id = icp.vldRef;
+               return this.maps.get(this).vld[id];
+       }
+
+       mapVld(vl) {
+               this.maps.get(this).vld[vl.id] = vl;
+       }
+
+       get containersList() {
+               return Array.from(this.maps.get(this).containers);
+       }
+
+       addContainer(container) {
+               this.maps.get(this).containers.add(container);
+       }
+
+       addContainers(containers) {
+               containers.filter(container => {
+                       if (DescriptorModelFactory.isInternalConnectionPoint(container)) {
+                               this.addContainer(container);
+                       } else if (DescriptorModelFactory.isInternalVirtualLink(container)) {
+                               this.mapVld(container);
+                       }
+               });
+       }
+
+       renderPath(icp, ivld) {
+               const path = line.interpolate('basis');
+               const srcPoint = icp.position.centerPoint();
+               const dstPoint = ivld.position.centerPoint();
+               const srcIsTopMounted = /top/.test(icp.location);
+               const srcSpline1 = {
+                       x: srcPoint.x,
+                       y: (srcIsTopMounted ? icp.position.top - 15 : icp.position.bottom + 15)
+               };
+               const srcSpline2 = {
+                       x: srcPoint.x,
+                       y: (srcIsTopMounted ? icp.position.top - 15 : icp.position.bottom + 15)
+               };
+               return path([srcPoint, srcSpline1, srcSpline2, dstPoint]);
+       }
+
+       render() {
+
+               const paths = this.graph.paths.selectAll('.' + this.props.selector.join('.')).data(this.containersList, DescriptorModelFactory.containerIdentity);
+
+               paths.enter().append('path');
+
+               paths.attr({
+                       'data-uid': d => {
+                               return d.uid;
+                       },
+                       'class': d => {
+                               return 'connection between-' + d.parent.type + '-and-' + d.type;
+                       },
+                       'stroke-width': 5,
+                       stroke: ColorGroups.vld.primary,
+                       fill: 'transparent',
+                       d: d => {
+                               return this.renderPath(d, this.findVldForInternalConnectionPoint(d));
+                       }
+               });
+
+               paths.exit().remove();
+
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphNetworkService.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphNetworkService.js
new file mode 100644 (file)
index 0000000..3d4a69a
--- /dev/null
@@ -0,0 +1,15 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+export default class GraphNetworkService extends GraphDescriptorModel{
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.NetworkService, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphRecordServicePath.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphRecordServicePath.js
new file mode 100644 (file)
index 0000000..403c644
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * Created by onvelocity on 2/10/16.
+ */
+
+import math from './math'
+import PathBuilder from './PathBuilder'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+
+import '../../styles/GraphRecordServicePaths.scss'
+
+export default class GraphRecordServicePath {
+
+       constructor(graph, props) {
+               this.graph = graph;
+               this.props = props;
+               this.containers = [];
+               this.networkMap = new WeakMap();
+               this.networkMap.set(this, {networkMap: {}});
+
+       }
+
+       getNetwork(key) {
+               return this.networkMap.get(this).networkMap[key];
+       }
+
+       putNetwork(item) {
+               this.networkMap.get(this).networkMap[item.key + item.type] = item;
+       }
+
+       addContainers(containers) {
+
+               containers.filter(d => {
+                       if (DescriptorModelFactory.isRecordServicePath(d)) {
+                               return true;
+                       }
+                       if (DescriptorModelFactory.isRspConnectionPointRef(d)) {
+                               return false;
+                       }
+                       if (DescriptorModelFactory.isConnectionPoint(d)) {
+                               this.putNetwork(d);
+                       }
+                       if (DescriptorModelFactory.isVnfdConnectionPointRef(d)) {
+                               this.putNetwork(d)
+                       }
+               }).forEach(d => this.containers.push(d));
+
+       }
+
+       render() {
+
+               const pathsGroup = this.graph.forwardingGraphPaths;
+
+               const path = pathsGroup.selectAll('.rsp-path').data(this.containers, DescriptorModelFactory.containerIdentity);
+
+               path.enter().append('path');
+
+               path.attr({
+                       'class': 'rsp-path path',
+                       'stroke': rsp => rsp.parent.colors.primary,
+                       'data-id': d => d.id,
+                       'stroke-width': 1.5,
+                       fill: 'transparent',
+                       'shape-rendering': 'geometricPrecision',
+                       d: (rsp, rspIndex) => {
+
+                               if (!rsp.uiState.showPath) {
+                                       return '';
+                               }
+
+                               const cpList = rsp.connectionPoints.filter(d => d);
+                               const cpCount = rsp.connectionPoints.length - 1;
+
+                               const path = new PathBuilder();
+
+                               const pathOffset = 20 * rspIndex;
+
+                               return rsp.connectionPoints.reduce((r, cpRef, cpRefIndex) => {
+
+                                       const cp = this.getNetwork(cpRef.key + 'connection-point');
+                                       const point = cp.position.centerPoint();
+                                       const vnfdCpRef = this.getNetwork(cp.key + 'vnfd-connection-point-ref');
+
+                                       if (path.length === 0) {
+                                               path.M(point.x, point.y, {container: cp});
+                                       } else if (cpRefIndex === 1) {
+
+                                               const last = path.last();
+                                               //
+                                               //const previousContainer = path.findPrevious(d => d.info.container);
+                                               //
+                                               //let distance = 200;
+
+                                               //if (previousContainer) {
+                                               //      distance = math.distanceBetweenPositions(previousContainer.info.container.position, cp.position);
+                                               //}
+
+                                               if (last.cmd === 'M') {
+                                                       path.C(last.x + 100 + pathOffset, last.y - 100 - pathOffset, point.x - 100 - pathOffset, point.y - 100 - pathOffset, point.x, point.y);
+                                               } else {
+                                                       path.S(point.x - 100, point.y - 100, point.x, point.y);
+                                               }
+
+                                       } else {
+
+                                               //const last = path.last();
+                                               //
+                                               //const previousContainer = path.findPrevious(d => d.info.container);
+                                               //
+                                               //let distance = 200;
+
+                                               //if (previousContainer) {
+                                               //      distance = math.distanceBetweenPositions(previousContainer.info.container.position, cp.position);
+                                               //}
+
+                                               path.S(point.x - 100 - pathOffset, point.y - 100 - pathOffset, point.x, point.y);
+
+                                       }
+
+
+                                       if (cpRefIndex < cpCount && vnfdCpRef) {
+
+                                               const nextVnfdCpRef = this.getNetwork(cpList[cpRefIndex + 1].key + 'vnfd-connection-point-ref');
+
+                                               if (nextVnfdCpRef) {
+
+                                                       const cpsOnSameVnfd = nextVnfdCpRef && nextVnfdCpRef.key === vnfdCpRef.key;
+                                                       const cpsOnSameVld = nextVnfdCpRef.parent.key === vnfdCpRef.parent.key;
+
+                                                       if (cpsOnSameVld) {
+
+                                                               const vldCenter = vnfdCpRef.parent.position.centerPoint();
+
+                                                               const last = path.last();
+
+                                                               if (last.cmd === 'M') {
+                                                                       path.C(last.x, last.y + 40 + pathOffset, vldCenter.x, vldCenter.y - 40 - pathOffset, vldCenter.x, vldCenter.y);
+                                                               } else {
+                                                                       path.S(vldCenter.x, vldCenter.y - 40 - pathOffset, vldCenter.x, vldCenter.y);
+                                                               }
+
+                                                               //const distance = math.distanceBetweenPositions(cp.position, vnfdCpRef.parent.position);
+
+                                                       } else if (cpsOnSameVnfd) {
+
+                                                               const last = path.last();
+
+                                                               const vldCenter = vnfdCpRef.parent.position.centerPoint();
+
+                                                               if (last.cmd === 'M') {
+                                                                       path.C(last.x, last.y + 40, vldCenter.x, vldCenter.y - 40, vldCenter.x, vldCenter.y);
+                                                               } else {
+                                                                       path.S(vldCenter.x, vldCenter.y - 40, vldCenter.x, vldCenter.y);
+                                                               }
+
+                                                       }
+
+                                               }
+
+                                       }
+
+                                       return path.toString();
+
+                               }, '')
+                       }
+
+               });
+
+               path.exit().remove();
+
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualDeploymentUnit.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualDeploymentUnit.js
new file mode 100644 (file)
index 0000000..1b17f88
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+export default class GraphVirtualDeploymentUnit extends GraphDescriptorModel {
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.VirtualDeploymentUnit, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualLink.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualLink.js
new file mode 100644 (file)
index 0000000..fd8e080
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+
+import d3 from 'd3'
+import ClassNames from 'classnames'
+import ColorGroups from '../ColorGroups'
+import SelectionManager from '../SelectionManager.js'
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import DescriptorGraphSelection from './DescriptorGraphSelection'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+import '../../styles/GraphVirtualLink.scss'
+
+export default class GraphVirtualLink extends GraphDescriptorModel {
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.VirtualLink, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualLinkPaths.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualLinkPaths.js
new file mode 100644 (file)
index 0000000..3c93d5b
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Created by onvelocity on 2/15/16.
+ */
+import ColorGroups from '../ColorGroups'
+
+/**
+ * NOTE: WIP this will replace part of the RelationsAndNetworksLayout::drawConnectionPointsAndPaths method.
+ *
+ * This class draws the paths between the VLD and the Connection Point it references.
+ *
+ */
+export default class GraphVirtualLinkPaths {
+
+       constructor(graph, props) {
+               this.graph = graph;
+               this.props = props;
+               this.containers = [];
+       }
+
+       addContainers(containers) {
+
+       }
+
+       render() {
+
+               const paths = graph.paths.selectAll('.connection').data(connectionPointRefs, DescriptorModelFactory.containerIdentity);
+
+               paths.enter().append('path');
+
+               paths.attr({
+                       'data-uid': d => {
+                               return d.uid;
+                       },
+                       'class': d => {
+                               return 'connection between-' + d.parent.type + '-and-' + d.type;
+                       },
+                       'stroke-width': 5,
+                       stroke: ColorGroups.vld.primary,
+                       fill: 'transparent',
+                       d: edge => {
+                               const layout = containerLayouts[edge.parent.type];
+                               return layout.renderConnectionPath(edge, containerLayouts);
+                       }
+               });
+
+               paths.exit().remove();
+
+       }
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualNetworkFunction.js b/skyquake/plugins/composer/src/src/libraries/graph/GraphVirtualNetworkFunction.js
new file mode 100644 (file)
index 0000000..9e4c101
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * Created by onvelocity on 2/11/16.
+ */
+'use strict';
+import DescriptorModelFactory from '../model/DescriptorModelFactory'
+import GraphDescriptorModel from './GraphDescriptorModel'
+
+export default class GraphVirtualNetworkFunction extends GraphDescriptorModel {
+
+       constructor(graph, props) {
+               super(graph, DescriptorModelFactory.VirtualNetworkFunction, props);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/HighlightRecordServicePaths.js b/skyquake/plugins/composer/src/src/libraries/graph/HighlightRecordServicePaths.js
new file mode 100644 (file)
index 0000000..9274c23
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Created by onvelocity on 2/23/16.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+
+/**
+ * Add CSS classes to Rendered Service Paths (Record Service Path in code) so they hightlight.
+ */
+export default class HighlightRecordServicePaths {
+
+       static removeHighlighting() {
+               Array.from(document.querySelectorAll(`svg .forwarding-graph-paths`)).forEach(d => {
+                       d3.select(d).classed('-is-highlighting', false);
+               });
+               Array.from(document.querySelectorAll('.rsp-path')).forEach(d => {
+                       d3.select(d).classed('-is-highlighted', false);
+               });
+       }
+
+       static highlightPaths(rsp) {
+               HighlightRecordServicePaths.removeHighlighting();
+               Array.from(document.querySelectorAll(`svg .forwarding-graph-paths`)).forEach(d => {
+                       d3.select(d).classed('-is-highlighting', true);
+               });
+               const list = _.isArray(rsp) ? rsp : [rsp];
+               list.forEach(rsp => {
+                       Array.from(document.querySelectorAll(`[data-id="${rsp.id}"]`)).forEach(d => {
+                               d.parentNode.appendChild(d);
+                               d3.select(d).classed('-is-highlighted', true);
+                       });
+               });
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/PathBuilder.js b/skyquake/plugins/composer/src/src/libraries/graph/PathBuilder.js
new file mode 100644 (file)
index 0000000..70e9be7
--- /dev/null
@@ -0,0 +1,177 @@
+
+/**
+ * Created by onvelocity on 2/10/16.
+ */
+
+export default class PathBuilder {
+
+       constructor() {
+               this.path = [];
+       }
+
+       static archFlags(override) {
+               return Object.assign({xAxisRotation: 0, largeArcFlag: 0, sweepFlag: 0}, override);
+       }
+
+       M(x, y, info = {}) {
+               this.path.push({x: x, y: y, cmd: 'M', info: info});
+               return this;
+       }
+
+       m(dx, dy, info = {}) {
+               this.path.push({dx: dx, dy: dy, cmd: 'm', info: info});
+               return this;
+       }
+
+       L(x, y, info = {}) {
+               this.path.push({x: x, y: y, cmd: 'L', info: info});
+               return this;
+       }
+
+       l(dx, dy, info = {}) {
+               this.path.push({dx: dx, dy: dy, cmd: 'l', info: info});
+               return this;
+       }
+
+       H(x, info = {}) {
+               this.path.push({x: x, cmd: 'H', info: info});
+               return this;
+       }
+
+       h(dx, info = {}) {
+               this.path.push({dx: dx, cmd: 'h', info: info});
+               return this;
+       }
+
+       V(y, info = {}) {
+               this.path.push({y: y, cmd: 'V', info: info});
+               return this;
+       }
+
+       v(dy, info = {}) {
+               this.path.push({dy: dy, cmd: 'v', info: info});
+               return this;
+       }
+
+       C(x1, y1, x2, y2, x, y, info = {}) {
+               this.path.push({x1: x1, y1: y1, x2: x2, y2: y2, x: x, y: y, cmd: 'C', info: info});
+               return this;
+       }
+
+       c(dx1, dy1, dx2, dy2, dx, dy, info = {}) {
+               this.path.push({dx1: dx1, dy1: dy1, dx2: dx2, dy2: dy2, dx: dx, dy: dy, cmd: 'c', info: info});
+               return this;
+       }
+
+       Q(x1, y1, x, y, info = {}) {
+               this.path.push({x1: x1, y1: y1, x: x, y: y, cmd: 'Q', info: info});
+               return this;
+       }
+
+       q(x1, y1, x, y, info = {}) {
+               this.path.push({x1: x1, y1: y1, x: x, y: y, cmd: 'q', info: info});
+               return this;
+       }
+
+       T(x, y, info = {}) {
+               this.path.push({x: x, y: y, cmd: 'T', info: info});
+               return this;
+       }
+
+       A (rx, ry, x, y, info = {xAxisRotation: 0, largeArcFlag: 0, sweepFlag: 0}) {
+               info = PathBuilder.archFlags(info);
+               this.path.push({rx: rx, ry: ry, 'x-axis-rotation': info.xAxisRotation,  'large-arc-flag': info.largeArcFlag, 'sweep-flag': info.sweepFlag, x: x, y: y, cmd: 'A', info: info});
+               return this;
+       }
+
+       S(x2, y2, x, y, info = {}) {
+               this.path.push({x2: x2, y2: y2, x: x, y: y, cmd: 'S', info: info});
+               return this;
+       }
+
+       H(x, info = {}) {
+               this.path.push({x: x, info: info});
+               return this;
+       }
+
+       h(dx, info = {}) {
+               this.path.push({dx: dx, info: info});
+               return this;
+       }
+
+       V(y, info = {}) {
+               this.path.push({y: y, info: info});
+               return this;
+       }
+
+       v(dy, info = {}) {
+               this.path.push({dy: dy, info: info});
+               return this;
+       }
+
+       get Z() {
+               this.path.push({cmd: 'Z'});
+               return this;
+       }
+
+       last() {
+               return this.path[this.path.length - 1];
+       }
+
+       findPrevious(filter) {
+               return this.path.splice().reverse().reduce((r, d) => {
+                       if (r) {
+                               return r;
+                       }
+                       if (filter(d)) {
+                               return d
+                       }
+               }, null);
+       }
+
+       insertBeforeLast() {
+               if (this.path.length < 3) {
+                       return this;
+               }
+               const last = this.path.pop();
+               this.path.splice(this.length - 2, 0, last);
+               return this;
+       }
+
+       concat(pathBuilder) {
+               this.path = this.path.filter(d => d.cmd !== 'Z').concat(pathBuilder);
+               return this;
+       }
+
+       toString() {
+               return this.path.reduce((r, d) => {
+                       return r + ' ' + d.cmd + ' ' + Object.keys(d).filter(k => !(k == 'cmd' || k === 'info')).map(k => d[k]).reduce((r, val) => r + ' ' + val, '');
+               }, '').replace(/\s+/g, ' ').trim();
+       }
+
+       get length() {
+               return this.path.length;
+       }
+
+       static descriptorPath(borderRadius = 20, height = 55, width = 250) {
+               const path = new PathBuilder();
+               borderRadius = Math.max(0, borderRadius);
+               width = Math.max(borderRadius, width) - borderRadius;
+               height = Math.max(borderRadius, height) - (borderRadius);
+               const iconWidthHeight = 40;
+               return path.M(0, 0)
+                       // top
+                       .L(width, 0).C(width, 0, width + borderRadius, 0, width + borderRadius, borderRadius)
+                       // right
+                       .L(width + borderRadius, height).C(width + borderRadius, height, width + borderRadius, height + borderRadius, width, height + borderRadius)
+                       // bottom
+                       .L(0, height + borderRadius).C(0, height + borderRadius, 0 - borderRadius, height + borderRadius, 0 - borderRadius, height)
+                       // left
+                       .L(0 - borderRadius, 0 + borderRadius).C(0 - borderRadius, 0 + borderRadius, 0 - borderRadius, 0, 0, 0)
+                       // icon separator
+                       //.L(iconWidthHeight, 0).L(iconWidthHeight, iconWidthHeight + (borderRadius + height - iconWidthHeight))
+                       // label separator
+                       //.L(iconWidthHeight, iconWidthHeight).L(0 - borderRadius, iconWidthHeight);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/Position.js b/skyquake/plugins/composer/src/src/libraries/graph/Position.js
new file mode 100644 (file)
index 0000000..df5465e
--- /dev/null
@@ -0,0 +1,177 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/25/15.
+ */
+
+export default class Position {
+
+       constructor(pos = {}) {
+               this._position = Object.assign({}, Position.defaults(), pos);
+               // if consumer specified width or height in the
+               // constructor then set right and bottom....
+               if (!isNaN(parseFloat(pos.width))) {
+                       // ensure right is set
+                       this.width = pos.width;
+               }
+               if (!isNaN(parseFloat(pos.height))) {
+                       // ensure bottom is set
+                       this.height = pos.height;
+               }
+       }
+
+       static defaults() {
+               return {
+                       top: 0,
+                       left: 0,
+                       bottom: 0,
+                       right: 0,
+                       width: 0,
+                       height: 0
+               };
+       }
+
+       get position() {
+               return Object.assign({}, this._position);
+       }
+
+       get top() {
+               return this._position.top;
+       }
+
+       set top(value) {
+               this._position.top = parseFloat(value) || 0;
+               return this;
+       }
+
+       get left() {
+               return this._position.left;
+       }
+
+       set left(value) {
+               this._position.left = parseFloat(value) || 0;
+               return this;
+       }
+
+       get bottom() {
+               return this._position.bottom;
+       }
+
+       set bottom(value) {
+               this._position.bottom = parseFloat(value) || 0;
+               return this;
+       }
+
+       get right() {
+               return this._position.right;
+       }
+
+       set right(value) {
+               this._position.right = parseFloat(value) || 0;
+               return this;
+       }
+
+       get width() {
+               return Math.abs(this.right - this.left);
+       }
+
+       set width(width) {
+               const value = parseFloat(width);
+               if (!isNaN(value)) {
+                       this.right = value + this.left;
+                       this._position.width = this.width;
+               }
+       }
+
+       get height() {
+               return Math.abs(this.bottom - this.top);
+       }
+
+       set height(height) {
+               const value = parseFloat(height);
+               if (!isNaN(value)) {
+                       this.bottom = value + this.top;
+                       this._position.height = this.height;
+               }
+       }
+
+       toString() {
+               return JSON.stringify(this._position);
+       }
+
+       value() {
+               return {
+                       top: this.top,
+                       left: this.left,
+                       right: this.right,
+                       bottom: this.bottom,
+                       width: this.width,
+                       height: this.height
+               };
+       }
+
+       centerPoint() {
+               return {
+                       x: this.left + (this.width / 2),
+                       y: this.top + (this.height / 2)
+               };
+       }
+
+       move(left, top) {
+               this.moveTop(top);
+               this.moveLeft(left);
+       }
+
+       moveLeft(left) {
+               const width = this.width;
+               const value = parseFloat(left);
+               if (!isNaN(value)) {
+                       this._position.left = value;
+                       this._position.right = value + width;
+               }
+       }
+
+       moveRight(right) {
+               const width = this.width;
+               const value = parseFloat(right);
+               if (!isNaN(value)) {
+                       this._position.left = value - width;
+                       this._position.right = value;
+               }
+       }
+
+       moveTop(top) {
+               const height = this.height;
+               const value = parseFloat(top);
+               if (!isNaN(value)) {
+                       this._position.top = value;
+                       this._position.bottom = value + height;
+               }
+       }
+
+       moveBottom(bottom) {
+               const height = this.height;
+               const value = parseFloat(bottom);
+               if (!isNaN(value)) {
+                       this._position.top = value - height;
+                       this._position.bottom = value;
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/layouts/RelationsAndNetworksLayout.js b/skyquake/plugins/composer/src/src/libraries/graph/layouts/RelationsAndNetworksLayout.js
new file mode 100644 (file)
index 0000000..f53b4dc
--- /dev/null
@@ -0,0 +1,571 @@
+/**
+ * Created by onvelocity on 2/10/16.
+ */
+import alt from '../../../alt'
+import _ from 'lodash'
+import d3 from 'd3'
+import math from '../math'
+import ClassNames from 'classnames'
+import ColorGroups from '../../ColorGroups'
+import GraphVirtualLink from '../GraphVirtualLink'
+import GraphNetworkService from '../GraphNetworkService'
+import GraphForwardingGraph from '../GraphForwardingGraph'
+import GraphConstituentVnfd from '../GraphConstituentVnfd'
+import GraphVirtualNetworkFunction from '../GraphVirtualNetworkFunction'
+import SelectionManager from '../../SelectionManager'
+import GraphConnectionPointNumber from '../GraphConnectionPointNumber'
+import CatalogItemsActions from '../../../actions/CatalogItemsActions'
+import DescriptorModelFactory from '../../model/DescriptorModelFactory'
+import DescriptorGraphSelection from '../DescriptorGraphSelection'
+import GraphVirtualDeploymentUnit from '../GraphVirtualDeploymentUnit'
+import GraphRecordServicePath from '../GraphRecordServicePath'
+import GraphInternalVirtualLink from '../GraphInternalVirtualLink'
+import TooltipManager from '../../TooltipManager'
+
+function onCutDelegateToRemove(container) {
+       function onCut(event) {
+               event.target.removeEventListener('cut', onCut);
+               if (container.remove()) {
+                       CatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());
+               } else {
+                       event.preventDefault();
+               }
+       }
+       this.addEventListener('cut', onCut);
+}
+
+export default function RelationsAndNetworksLayout() {
+
+       const graph = this;
+       const props = this.props;
+       const containerWidth = 250;
+       const containerHeight = 55;
+       const marginTop = 20;
+       const marginLeft = 10;
+       const containerList = [];
+       const leftOffset = containerWidth;
+
+       const snapTo = (value) => {
+               return Math.max(props.snapTo * Math.round(value / props.snapTo), props.padding);
+       };
+
+       const line = d3.svg.line()
+               .x(d => {
+                       return d.x;
+               })
+               .y(d => {
+                       return d.y;
+               });
+
+       function countAncestors(container = {}) {
+               let count = 0;
+               while (container.parent) {
+                       count++;
+                       container = container.parent;
+               }
+               return count;
+       }
+
+       function renderRelationPath(src, dst) {
+               const path = line.interpolate('basis');
+               const srcPoint = src.position.centerPoint();
+               const dstPoint = dst.position.centerPoint();
+               const angle = math.angleBetweenPositions(src.position, dst.position);
+               if (angle < 180) {
+                       srcPoint.y = src.position.top;
+                       dstPoint.y = dst.position.bottom;
+               } else {
+                       srcPoint.y = src.position.bottom;
+                       dstPoint.y = dst.position.top;
+               }
+               return path([srcPoint, dstPoint]);
+       }
+
+       function renderConnectionPath(cpRef) {
+               const path = line.interpolate('basis');
+               const srcPoint = cpRef.position.centerPoint();
+               const dstPoint = cpRef.parent.position.centerPoint();
+               const srcIsTopMounted = /top/.test(cpRef.location);
+               //const srcIsLeftMounted = /left/.test(cpRef.parent.location);
+               const offset = 15;
+               const srcSpline1 = {
+                       x: srcPoint.x,
+                       y: (srcIsTopMounted ? cpRef.position.top - offset : cpRef.position.bottom + offset)
+               };
+               const srcSpline2 = {
+                       x: srcPoint.x,
+                       y: (srcIsTopMounted ? cpRef.position.top - offset : cpRef.position.bottom + offset)
+               };
+               return path([srcPoint, srcSpline1, srcSpline2, dstPoint]);
+       }
+
+       const containerLayoutInfo = {
+               nsd: {
+                       list: [],
+                       width: containerWidth,
+                       height: containerHeight,
+                       top() {
+                               return 10;
+                       },
+                       left(container, layouts) {
+                               const positionIndex = layouts.vnffgd.list.length + this.list.length;
+                               return (positionIndex * (this.width * 1.5)) + leftOffset / 2;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               vnffgd: {
+                       list: [],
+                       width: containerWidth,
+                       height: containerHeight,
+                       top(container, layouts) {
+                               const positionIndex = layouts.nsd.list.length + this.list.length;
+                               return (positionIndex * (this.height * 1.5)) + 120;
+                       },
+                       left(container, layouts) {
+                               return 10;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               vnfd: {
+                       list: [],
+                       width: containerWidth,
+                       height: containerHeight,
+                       top(container) {
+                               return (countAncestors(container) * 100) + 10;
+                       },
+                       left() {
+                               const positionIndex = this.list.length;
+                               return (positionIndex * (this.width * 1.5)) + leftOffset;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               'constituent-vnfd': {
+                       list: [],
+                       width: containerWidth,
+                       height: containerHeight,
+                       top(container) {
+                               return (countAncestors(container) * 100) + 10;
+                       },
+                       left() {
+                               const positionIndex = this.list.length;
+                               return (positionIndex * (this.width * 1.5)) + leftOffset;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               pnfd: {
+                       list: [],
+                       width: containerWidth,
+                       height: containerHeight,
+                       top(container) {
+                               return (countAncestors(container) * 100) + 10;
+                       },
+                       left() {
+                               const positionIndex = this.list.length;
+                               return (positionIndex * (this.width * 1.5)) + leftOffset;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               vld: {
+                       list: [],
+                       width: containerWidth,
+                       height: 38,
+                       top(container) {
+                               return (countAncestors(container) * 100) + 180;
+                       },
+                       left() {
+                               const positionIndex = this.list.length;
+                               const marginOffsetFactor = 1.5;
+                               const gutterOffsetFactor = 1.5;
+                               return (positionIndex * (this.width * gutterOffsetFactor)) + ((this.width * marginOffsetFactor) / 2) + leftOffset;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               'internal-vld': {
+                       list: [],
+                       width: containerWidth,
+                       height: 38,
+                       top(container, containerLayouts) {
+                               return (countAncestors(container) * 100) + 100;
+                       },
+                       left() {
+                               const positionIndex = this.list.length;
+                               const marginOffsetFactor = 1.5;
+                               const gutterOffsetFactor = 1.5;
+                               return (positionIndex * (this.width * gutterOffsetFactor)) + ((this.width * marginOffsetFactor) / 2) + leftOffset;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               },
+               vdu: {
+                       list: [],
+                       width: containerWidth,
+                       height: containerHeight,
+                       gutter: 30,
+                       top(container) {
+                               return (countAncestors(container) * 100) + 10;
+                       },
+                       left(container) {
+                               const positionIndex = this.list.length;
+                               return (positionIndex * (this.width * 1.5)) + leftOffset;
+                       },
+                       renderRelationPath: renderRelationPath,
+                       renderConnectionPath: renderConnectionPath
+               }
+       };
+
+       function getConnectionPointEdges() {
+
+               // 1. create a lookup map to find a connection-point by it's key
+               const connectionPointMap = {};
+               containerList.filter(d => d.connectionPoint).reduce((result, container) => {
+                       return container.connectionPoint.reduce((result, connectionPoint) => {
+                               result[connectionPoint.key] = connectionPoint;
+                               connectionPoint.uiState.hasConnection = false;
+                               return result;
+                       }, result);
+               }, connectionPointMap);
+
+               // 2. determine position of the connection-point and connection-point-ref (they are the same)
+               const connectionPointRefList = [];
+               containerList.filter(container => container.connection).forEach(container => {
+                       container.uiState.hasConnection = false;
+                       container.connection.filter(d => d.key).forEach(cpRef => {
+                               try {
+                                       const source = connectionPointMap[cpRef.key];
+                                       const destination = container;
+                                       source.uiState.hasConnection = true;
+                                       destination.uiState.hasConnection = true;
+                                       const edgeStateMachine = math.upperLowerEdgeLocation;
+                                       // angle is used to determine location top, bottom, right, left
+                                       const angle = math.angleBetweenPositions(source.parent.position, destination.position);
+                                       // distance is used to determine order of the connection points
+                                       const distance = math.distanceBetweenPositions(source.parent.position, destination.position);
+                                       cpRef.location = source.location = edgeStateMachine(angle);
+                                       source.edgeAngle = angle;
+                                       if (destination.type === 'vdu') {
+                                               source.edgeLength = Math.max(source.edgeLength || 0, distance);
+                                       }
+                                       // warn assigning same instance (e.g. pass by reference) so that changes will reflect thru
+                                       cpRef.position = source.position;
+                                       connectionPointRefList.push(cpRef);
+                               } catch(e) {
+                                       return;
+                               }
+                       });
+               });
+
+               // 3. update the connection-point/-ref location based on the angle of the path
+               containerList.filter(d => d.connectionPoint).forEach(container => {
+                       // group the connectors by their location and then update their position coordinates accordingly
+                       const connectionPoints = container.connectionPoint.sort((a, b) => b.edgeLength - a.edgeLength);
+                       const locationIndexCounters = {};
+                       connectionPoints.forEach(connectionPoint => {
+                               // location index is used to calculate the actual position where the path will terminate on the container
+                               const location = connectionPoint.location;
+                               const locationIndex = locationIndexCounters[location] || (locationIndexCounters[location] = 0);
+                               connectionPoint.positionIndex = locationIndex;
+                               if (/left/.test(location)) {
+                                       connectionPoint.position.moveLeft(connectionPoint.parent.position.left + 5 + ((connectionPoint.width + 1) * locationIndex));
+                               } else {
+                                       connectionPoint.position.moveRight(connectionPoint.parent.position.right - 15 - ((connectionPoint.width + 1) * locationIndex));
+                               }
+                               if (/top/.test(location)) {
+                                       connectionPoint.position.moveTop(connectionPoint.parent.position.top - connectionPoint.height);
+                               } else {
+                                       connectionPoint.position.moveTop(connectionPoint.parent.position.bottom);
+                               }
+                               locationIndexCounters[location] = locationIndex + 1;
+                       });
+               });
+
+               return connectionPointRefList;
+
+       }
+
+       function drawConnectionPointsAndPaths(graph, connectionPointRefs) {
+
+               const paths = graph.paths.selectAll('.connection').data(connectionPointRefs, DescriptorModelFactory.containerIdentity);
+
+               paths.enter().append('path');
+
+               paths.attr({
+                       'data-uid': d => {
+                               return d.uid;
+                       },
+                       'class': d => {
+                               return 'connection between-' + d.parent.type + '-and-' + d.type;
+                       },
+                       'stroke-width': 5,
+                       stroke: ColorGroups.vld.primary,
+                       fill: 'transparent',
+                       d: edge => {
+                               const layout = containerLayoutInfo[edge.parent.type];
+                               return layout.renderConnectionPath(edge, containerLayoutInfo);
+                       }
+               }).on('cut', (container) => {
+
+                       let success = false;
+
+                       if (container && container.remove) {
+                               success = container.remove();
+                       }
+
+                       if (success) {
+                               CatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());
+                       } else {
+                               d3.event.preventDefault();
+                       }
+
+                       d3.event.stopPropagation();
+
+               });
+
+               paths.exit().remove();
+
+               const symbolSize = props.connectionPointSize;
+               const connectionPointSymbol = d3.svg.symbol().type('square').size(symbolSize);
+               const internalConnectionPointSymbolBottom = d3.svg.symbol().type('triangle-down').size(symbolSize);
+               const internalConnectionPointSymbolTop = d3.svg.symbol().type('triangle-up').size(symbolSize);
+
+               const connectors = containerList.filter(d => d.connectors).reduce((result, container) => {
+                       return container.connectors.reduce((result, connector) => {
+                               result.add(connector);
+                               return result;
+                       }, result);
+               }, new Set());
+
+               const points = graph.connectorsGroup.selectAll('.connector').data(Array.from(connectors), DescriptorModelFactory.containerIdentity);
+
+               points.enter().append('path');
+
+               points.attr({
+                       'data-uid': d => d.uid,
+                       'data-key': d => d.key,
+                       'data-cp-number': d => d.uiState.cpNumber,
+                       'class': d => {
+                               return ClassNames('connector', d.type, d.parent.type, {
+                                       '-is-connected': d.uiState.hasConnection,
+                                       '-is-not-connected': !d.uiState.hasConnection
+                               });
+                       },
+                       'data-tip': d => {
+                               const info = d.displayData;
+                               return Object.keys(info).reduce((r, key) => {
+                                       if (info[key]) {
+                                               return r + `<div class="${key}"><i>${key}</i><val>${info[key]}</val></div>`;
+                                       }
+                                       return r;
+                               }, '');
+                       },
+                       'data-tip-offset': d => {
+                               if (d.type === 'internal-connection-point') {
+                                       return '{"top": -7, "left": -9}';
+                               }
+                               return '{"top": -5, "left": -5}';
+                       },
+                       transform: d => {
+                               const point = d.position.centerPoint();
+                               return 'translate(' + (point.x) + ', ' + (point.y) + ')';
+                       },
+                       d: d => {
+                               if (d.type === 'connection-point') {
+                                       return connectionPointSymbol();
+                               }
+                               if (/top/.test(d.location)) {
+                                       return internalConnectionPointSymbolTop();
+                               }
+                               return internalConnectionPointSymbolBottom();
+                       }
+               }).on('cut', (container) => {
+
+                       let success = false;
+
+                       if (container && container.remove) {
+                               success = container.remove();
+                       }
+
+                       if (success) {
+                               CatalogItemsActions.catalogItemDescriptorChanged.defer(container.getRoot());
+                       } else {
+                               d3.event.preventDefault();
+                       }
+
+                       d3.event.stopPropagation();
+
+               }).on('mouseenter', () => {
+                       TooltipManager.showTooltip(d3.event.target);
+               });
+
+               points.exit().remove();
+
+               const test = new GraphConnectionPointNumber(graph);
+               test.addContainers(Array.from(connectors));
+               test.render();
+       }
+
+       function drawRelationPointsAndPaths (graph, relationEdges) {
+
+               const paths = graph.paths.selectAll('.relation').data(relationEdges, DescriptorModelFactory.containerIdentity);
+
+               paths.enter().append('path')
+                       .attr({
+                               'class': d => {
+                                       return ClassNames('relation', d.type, {'-is-selected': d.uiState && SelectionManager.isSelected(d) /*d.uiState && d.uiState.selected*/});
+                               },
+                               stroke: 'red',
+                               fill: 'transparent',
+                               'marker-start': 'url(#relation-marker-end)',
+                               'marker-end': 'url(#relation-marker-end)'
+                       });
+
+               paths.attr({
+                       d: d => {
+                               const src = d;
+                               const dst = d.parent;
+                               const layout = containerLayoutInfo[src.type];
+                               return layout.renderRelationPath(src, dst, containerLayoutInfo);
+                       }
+               });
+
+               paths.exit().remove();
+
+       }
+
+       function updateContainerPosition(graph, container, layout) {
+               // use the provided layout to generate the position coordinates
+               const position = container.position;
+               position.top = layout.top(container, containerLayoutInfo) + marginTop;
+               position.left = layout.left(container, containerLayoutInfo) + marginLeft;
+               position.width = layout.width;
+               position.height = layout.height;
+               // cache the default layout position which may be needed by the layout
+               // of children elements that have not been positioned by the user
+               container.uiState.defaultLayoutPosition = position.value();
+               const savedContainerPosition = graph.lookupSavedContainerPosition(container);
+               if (savedContainerPosition) {
+                       // set the container position with the saved position coordinates
+                       container.setPosition(savedContainerPosition);
+               }
+               if (container.uiState.dropCoordinates) {
+                       const rect = graph.svg.node().getBoundingClientRect();
+                       const top = container.uiState.dropCoordinates.clientY - (position.height / 2) - rect.top;
+                       const left = container.uiState.dropCoordinates.clientX - (position.width / 2) - rect.left;
+                       container.position.move(Math.max(props.padding, left), Math.max(props.padding, top));
+                       graph.saveContainerPosition(container);
+                       delete container.uiState.dropCoordinates;
+               } else {
+                       graph.saveContainerPosition(container);
+               }
+       }
+
+       return {
+
+               addContainers(containers) {
+
+                       const layout = this;
+
+                       //containers = containers.filter(d => containerLayouts[d.type]);
+
+                       const graphSize = {
+                               width: 0,
+                               height: 0
+                       };
+
+                       containers.forEach(container => {
+                               containerList.push(container);
+                       });
+
+                       containers.forEach(container => {
+                               const layout = containerLayoutInfo[container.type];
+                               if (!layout) {
+                                       return
+                                       //throw new ReferenceError('unknown container type: ' + container.type);
+                               }
+                               updateContainerPosition(graph, container, layout);
+                               layout.list.push(container);
+                               graphSize.width = Math.max(graphSize.width, container.position.right, props.width);
+                               graphSize.height = Math.max(graphSize.height, container.position.bottom, props.height);
+                       });
+
+                       graph.svg.attr({
+                               width: graphSize.width + props.width,
+                               height: graphSize.height + props.height
+                       });
+
+                       const uiTransientState = {
+                               isDragging: false,
+                               dragStartInfo: [0, 0]
+                       };
+
+                       // todo extract drag behavior into class DescriptorGraphDrag
+
+                       const drag = this.drag = d3.behavior.drag()
+                               .origin(function(d) { return d; })
+                               .on('drag.graph', function (d) {
+                                       uiTransientState.isDragging = true;
+                                       const mouse = d3.mouse(graph.g.node());
+                                       const offset = uiTransientState.dragStartInfo;
+                                       const newTopEdge = snapTo(mouse[1] - offset[1]);
+                                       const newLeftEdge = snapTo(mouse[0] - offset[0]);
+                                       if (d.position.left === newLeftEdge && d.position.top === newTopEdge) {
+                                               // do not redraw since we are not moving the container
+                                               return;
+                                       }
+                                       d.position.move(newLeftEdge, newTopEdge);
+                                       graph.saveContainerPosition(d);
+                                       const connectionPointRefs = getConnectionPointEdges();
+                                       d3.select(this).attr({
+                                               transform: () => {
+                                                       const x = d.position.left;
+                                                       const y = d.position.top;
+                                                       return 'translate(' + x + ', ' + y + ')';
+                                               }
+                                       });
+                                       requestAnimationFrame(() => {
+                                               drawConnectionPointsAndPaths(graph, connectionPointRefs);
+                                               layout.renderers.forEach(d => d.render());
+                                       });
+                               }).on('dragend.graph', () => {
+                                       // d3 fires a drag-end event on mouse up, even if just clicking
+                                       if (uiTransientState.isDragging) {
+                                               uiTransientState.isDragging = false;
+                                               CatalogItemsActions.catalogItemMetaDataChanged(graph.containers[0].model);
+                                               d3.select(this).on('.graph', null);
+                                       }
+                               }).on('dragstart.graph', function (d) {
+                                       // the x, y offset of the mouse from the container's left, top
+                                       uiTransientState.dragStartInfo = d3.mouse(this);
+                               });
+
+                       this.renderers = [GraphVirtualLink, GraphNetworkService, GraphForwardingGraph, GraphVirtualNetworkFunction, GraphConstituentVnfd, GraphVirtualDeploymentUnit, GraphRecordServicePath, GraphInternalVirtualLink].map(layout => {
+                               const container = new layout(graph, props);
+                               const layoutInfo = containerLayoutInfo[container.classType && container.classType.type];
+                               if (layoutInfo) {
+                                       container.props.descriptorWidth = layoutInfo.width;
+                                       container.props.descriptorHeight = layoutInfo.height;
+                               }
+                               container.dragHandler = drag;
+                               container.addContainers(containerList);
+                               return container;
+                       });
+
+               },
+
+               render(graph, updateCallback = () => {}) {
+                       const connectionPointRefs = getConnectionPointEdges();
+                       requestAnimationFrame(() => {
+                               drawConnectionPointsAndPaths(graph, connectionPointRefs);
+                               this.renderers.forEach(d => d.render());
+                               updateCallback();
+                       });
+               }
+
+       };
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/libraries/graph/math.js b/skyquake/plugins/composer/src/src/libraries/graph/math.js
new file mode 100644 (file)
index 0000000..2968cfa
--- /dev/null
@@ -0,0 +1,147 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 9/1/15.
+ */
+
+import Position from './Position'
+
+const angleOfLine = function (x1, y1, x2, y2) {
+
+       const y = y2 - y1;
+       const x = x2 - x1;
+
+       const rad = Math.atan2(y, x);
+       const deg = Math.abs(rad * 180 / Math.PI);
+
+       let addDeg = 0;
+
+       if (rad <= 0) {
+               addDeg = 360;
+       }
+
+       // - addDeg bc atan2 returns -π to π where -π is the upper side of rectangle
+       // - 360 bc our ui grid system has zero in upper left corner not lower left
+       return Math.abs(Math.abs(deg - addDeg) - 360);
+
+};
+
+const angleBetweenPositions = function (src, dst) {
+       if (!src instanceof Position) {
+               throw new ReferenceError('require a position instance');
+       }
+       if (!dst instanceof Position) {
+               throw new ReferenceError('require a position instance');
+       }
+       const srcCenter = src.centerPoint();
+       const dstCenter = dst.centerPoint();
+       return angleOfLine(srcCenter.x, srcCenter.y, dstCenter.x, dstCenter.y);
+};
+
+const distanceBetweenPositions = function (src, dst) {
+       if (!src instanceof Position) {
+               throw new ReferenceError('require a position instance');
+       }
+       if (!dst instanceof Position) {
+               throw new ReferenceError('require a position instance');
+       }
+       const srcCenter = src.centerPoint();
+       const dstCenter = dst.centerPoint();
+       const x = Math.pow(dstCenter.x - srcCenter.x, 2);
+       const y = Math.pow(dstCenter.y - srcCenter.y, 2);
+       const distance = Math.sqrt((x) + (y));
+       if (isNaN(distance)) {
+               console.log('nan distance', srcCenter, dstCenter);
+       }
+       return distance;
+};
+
+const rectangleAnglesFromCenter = function (position) {
+       /* given a rectangle defined by a Position, determine the angle of each corner from center.
+        // note: 0˚ is on x-axis; angles are given counterclockwise from x-axis
+        // for example:
+        // the line AB(0, 0, 5, 0) would have angle 0˚
+        // the line AC(0, 0, 0, 5) would have angle 90˚
+        // the line BC(5, 0, 0, 5) would have angle 135˚
+        // the line BA(5, 0, 0, 0) would have angle 180˚
+        */
+       if (!position instanceof Position) {
+               throw new ReferenceError('require a Position instance');
+       }
+       const center = position.centerPoint();
+       return [
+               angleOfLine(center.x, center.y, position.right, position.top),
+               angleOfLine(center.x, center.y, position.left, position.top),
+               angleOfLine(center.x, center.y, position.left, position.bottom),
+               angleOfLine(center.x, center.y, position.right, position.bottom)
+       ];
+};
+
+const edgeLocation = function (rectangleInclinations) {
+       /* given the angle of a line, determine which edge of the rectangle the line should attach. */
+       let inclinations = rectangleInclinations;
+       if (rectangleInclinations instanceof Position) {
+               inclinations = rectangleAnglesFromCenter(rectangleInclinations);
+       }
+       return angle => {
+               angle = parseFloat(angle);
+               if (angle >= inclinations[3]) {
+                       return 'right';
+               }
+               if (angle >= 270) {
+                       return 'bottom-right';
+               }
+               if (angle >= inclinations[2]) {
+                       return 'bottom-left';
+               }
+               if (angle >= inclinations[1]) {
+                       return 'left';
+               }
+               if (angle >= 90) {
+                       return 'top-left';
+               }
+               if (angle >= inclinations[0]) {
+                       return 'top-right';
+               }
+               return 'right';
+       };
+};
+
+const upperLowerEdgeLocation = function (angle) {
+       angle = parseFloat(angle);
+       if (angle > 270) {
+               return 'bottom-right';
+       }
+       if (angle > 180) {
+               return 'bottom-left';
+       }
+       if (angle > 90) {
+               return 'top-left';
+       }
+       return 'top-right';
+};
+
+export default {
+       angleOfLine: angleOfLine,
+       angleBetweenPositions: angleBetweenPositions,
+       distanceBetweenPositions: distanceBetweenPositions,
+       anglesFromCenter: rectangleAnglesFromCenter,
+       edgeLocation: edgeLocation,
+       upperLowerEdgeLocation: upperLowerEdgeLocation
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/guid.js b/skyquake/plugins/composer/src/src/libraries/guid.js
new file mode 100644 (file)
index 0000000..752c204
--- /dev/null
@@ -0,0 +1,27 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+const TEMPLATE = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
+export default function guid(len = TEMPLATE.length) {
+       // http://byronsalau.com/blog/how-to-create-a-guid-uuid-in-javascript/
+       return TEMPLATE.replace(/[xy]/g, function (c) {
+               var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
+               return v.toString(16);
+       }).substring(0, len);
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/isFullScreen.js b/skyquake/plugins/composer/src/src/libraries/isFullScreen.js
new file mode 100644 (file)
index 0000000..a7e28d4
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * Created by onvelocity on 2/22/16.
+ */
+
+const checkFullScreen = ['fullscreen', 'mozFullScreen', 'webkitIsFullScreen', 'msFullscreenElement'];
+
+export default function isFullScreen () {
+       return checkFullScreen.reduce((r, name) => {
+               if (name in document) {
+                       return document[name];
+               }
+               return r;
+       }, false);
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModel.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModel.js
new file mode 100644 (file)
index 0000000..02bbfcd
--- /dev/null
@@ -0,0 +1,309 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 8/23/15.
+ */
+
+import _ from 'lodash'
+import guid from '../guid'
+import Position from '../graph/Position'
+import IconFactory from './IconFactory'
+import SelectionManager from '../SelectionManager'
+import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
+
+/**
+ * Abstract base class for the CONFD MANO Descriptors as defined by the Rift.ware YANG configuration files.
+ *
+ * Sub-classes should specify the type and qualified-type properties.
+ */
+export default class DescriptorModel {
+
+       constructor(model = {uiState: {}}, parent = null) {
+               // when our instance has no more strong references
+               // then our properties will get garbage collected.
+               this._props_ = new WeakMap();
+               this._props_.set(this, {
+                       position: new Position(),
+                       children: new Set(),
+                       values: {},
+                       model: model
+               });
+               this.className = 'DescriptorModel';
+               this.uid = this.uid || guid();
+               if (parent instanceof DescriptorModel) {
+                       parent.addChild(this);
+               }
+       }
+
+       get fieldNames() {
+               return DescriptorModelMetaFactory.getModelFieldNamesForType(this.uiState['qualified-type'] || this.type);
+       }
+
+       get property() {
+               return DescriptorModelMetaFactory.getModelMetaForType(this.uiState['qualified-type'] || this.type);
+       }
+
+       get model() {
+               let model = this._props_.get(this).model;
+               if (!model) {
+                       model = this.model = {uiState: {}};
+               }
+               return model;
+       }
+
+       set model(model) {
+               this._props_.get(this).model = model;
+               return this;
+       }
+
+       get uiState() {
+               return this.model.uiState = this.model.uiState || {};
+       }
+
+       set uiState(uiState) {
+               this.model.uiState = uiState;
+               return this;
+       }
+
+       get uid() {
+               return this.uiState[':uid'];
+       }
+
+       set uid(uid) {
+               this.uiState[':uid'] = uid;
+               return this;
+       }
+
+       get key() {
+               return this.id;
+       }
+
+       // key is read only by design
+
+       get id() {
+               return this.model.id;
+       }
+
+       set id(id) {
+               this.model.id = id;
+               return this;
+       }
+
+       get title() {
+               return this.model['short-name'] || this.model.name || this.key;
+       }
+
+       // title is read only by design
+
+       get name() {
+               return this.model.name;
+       }
+
+       set name(name) {
+               this.model.name = name;
+       }
+
+       get 'short-name'() {
+               return this.model['short-name'];
+       }
+
+       set 'short-name'(name) {
+               this.model['short-name'] = name;
+       }
+
+       get type() {
+               return this.uiState.type;
+       }
+
+       set type(type) {
+               this.uiState.type = type;
+               return this;
+       }
+
+       get qualifiedType() {
+               return this.uiState['qualified-type'] || this.type;
+       }
+
+       set qualifiedType(type) {
+               this.uiState['qualified-type'] = type;
+       }
+
+       get position() {
+               return this._props_.get(this).position;
+       }
+
+       set position(position) {
+               if (!(position instanceof Position)) {
+
+               }
+               this._props_.get(this).position = position;
+               return this;
+       }
+
+       get location() {
+               return this.uiState.location;
+       }
+
+       set location(v) {
+               this.uiState.location = v;
+       }
+
+       get children() {
+               return Array.from(this._props_.get(this).children);
+       }
+
+       addProp(name, value) {
+               this._props_.get(this).values[name] = value;
+               return this;
+       }
+
+       getProp(name) {
+               return this._props_.get(this).values[name];
+       }
+
+       addChild(child) {
+               if (!child instanceof DescriptorModel) {
+                       throw new ReferenceError('child must be an instance of DescriptorModel class');
+               }
+               if (this.findChildByUid(child.uid)) {
+                       throw new ReferenceError('child already exists');
+               }
+               if (child.parent instanceof DescriptorModel) {
+                       throw new ReferenceError('child already has a parent');
+               }
+               child.parent = this;
+               this._props_.get(this).children.add(child);
+       }
+
+       findChildByUid(uid) {
+               // uid can be a DescriptorModel instance,  JSON model object, or a uid string
+               if (typeof uid === 'object') {
+                       uid = uid.uiState && uid.uiState[':uid'];
+               }
+               if (typeof uid === 'string') {
+                       return this.children.filter(d => d.uid === uid)[0];
+               }
+       }
+
+       removeChild(child) {
+               let uid;
+               // warn don't clear parent so that removed ones can get to root for updating the catalog json model
+               //child.parent = null;
+               // uid can be a DescriptorModel instance, JSON model object, or a uid string
+               if (typeof uid === 'object') {
+                       uid = uid.uiState && uid.uiState[':uid'];
+               }
+               if (typeof uid === 'string') {
+                       this.children.filter(d => d.uid === uid).forEach(d => this._props_.get(this).children.delete(d));
+               } else {
+                       this._props_.get(this).children.delete(child);
+               }
+       }
+
+       getRoot() {
+               let root = this;
+               while (root && root.parent) {
+                       root = root.parent;
+               }
+               return root;
+       }
+
+       getRootNSDContainer() {
+               let container = this.parent;
+               while(container) {
+                       if (container.type === 'nsd') {
+                               return container;
+                       }
+                       container = container.parent;
+               }
+       }
+
+       setPosition(position) {
+               this.position = new Position(position);
+       }
+
+       get selected() {
+               return SelectionManager.isSelected(this);
+       }
+
+       get colors() {
+               return this.uiState.colors || {primary: 'black', secondary: 'white'};
+       }
+
+       set colors(colors) {
+               this.uiState.colors = colors;
+       }
+
+       get icon() {
+               return IconFactory.getIconForType(this.type);
+       }
+
+       get width() {
+               return this.position.width;
+       }
+
+       get height() {
+               return this.position.height;
+       }
+
+       get displayData() {
+               return {
+                       title: this.title,
+                       type: this.model.type,
+                       cpNumber: this.cpNumber
+               };
+       }
+
+       valueOf() {
+               return this.model;
+       }
+
+       updateModelList(modelFieldName, modelFieldValue, descriptorClass = DescriptorModel, newItemAddedSuccessCallback = () => {}) {
+               // value can be Array of (DescriptorModel | json model), DescriptorModel, or json model
+               if (_.isArray(modelFieldValue)) {
+                       this.model[modelFieldName] = modelFieldValue.map(d => d instanceof descriptorClass ? d.model : d);
+                       return true;
+               }
+               const size = this.model[modelFieldName].length;
+               if (modelFieldValue instanceof descriptorClass) {
+                       this.model[modelFieldName].push(modelFieldValue.valueOf());
+                       newItemAddedSuccessCallback(modelFieldValue);
+               } else if (typeof modelFieldValue === 'object') {
+                       this.model[modelFieldName].push(modelFieldValue);
+                       newItemAddedSuccessCallback(new descriptorClass(modelFieldValue, this));
+               } else {
+                       throw new ReferenceError(`expect object to be either an Array, ${descriptorClass.name} or JSON object`);
+               }
+               return size !== this.model[modelFieldName].length;
+       }
+
+       removeModelListItem(propertyName, child) {
+               // ensure child is a DescriptorModel instance
+               child = this.findChildByUid(child) || child;
+               if (!child) {
+                       return false;
+               }
+               this.removeChild(child);
+               const uid = child.uid;
+               const length = this[propertyName].length;
+               this[propertyName] = this[propertyName].filter(d => d.uid !== uid);
+               return length !== this[propertyName].length;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFactory.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFactory.js
new file mode 100644 (file)
index 0000000..68b70d7
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+import UID from './../UniqueId'
+import guid from '../guid'
+import Position from './../graph/Position'
+import ColorGroups from '../ColorGroups'
+import DescriptorModel from './DescriptorModel'
+import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
+import DescriptorModelMetaProperty from './DescriptorModelMetaProperty'
+
+import Classifier from './descriptors/Classifier'
+import ClassifierMatchAttributes from './descriptors/ClassifierMatchAttributes'
+import ConnectionPoint from './descriptors/ConnectionPoint'
+import VnfdConnectionPointRef from './descriptors/VnfdConnectionPointRef'
+import ConstituentVnfd from './descriptors/ConstituentVnfd'
+import ConstituentVnfdConnectionPoint from './descriptors/ConstituentVnfdConnectionPoint'
+import ForwardingGraph from './descriptors/ForwardingGraph'
+import InternalConnectionPoint from './descriptors/InternalConnectionPoint'
+import InternalVirtualLink from './descriptors/InternalVirtualLink'
+import NetworkService from './descriptors/NetworkService'
+import PhysicalNetworkFunction from './descriptors/PhysicalNetworkFunction'
+import RecordServicePath from './descriptors/RecordServicePath'
+import RspConnectionPointRef from './descriptors/RspConnectionPointRef'
+import VirtualDeploymentUnit from './descriptors/VirtualDeploymentUnit'
+import VirtualLink from './descriptors/VirtualLink'
+import VirtualNetworkFunction from './descriptors/VirtualNetworkFunction'
+import VirtualNetworkFunctionReadOnlyWrapper from './descriptors/VirtualNetworkFunctionReadOnlyWrapper'
+import InternalConnectionPointRef from './descriptors/InternalConnectionPointRef'
+import VirtualNetworkFunctionConnectionPoint from './descriptors/VirtualNetworkFunctionConnectionPoint'
+import VirtualDeploymentUnitInternalConnectionPoint from './descriptors/VirtualDeploymentUnitInternalConnectionPoint'
+
+function findChildDescriptorModelAndUpdateModel(model, parent) {
+       if (parent instanceof DescriptorModel) {
+               const child = parent.findChildByUid(model);
+               if (child) {
+                       child.model = model;
+                       return child;
+               }
+       }
+}
+
+let identity = 0;
+
+class DescriptorModelFactory {
+
+
+       static containerIdentity(d) {
+               const parentId = UID.from(d && d.parent);
+               // note the incremental counter is to always force d3 models to update
+               return (parentId ? parentId + ':' : '') + UID.from(d) + ':' + identity++;
+       }
+
+       /**
+        * Create a reduce function that creates a DescriptorModel element tree
+        * representation of a Catalog Item and then returns a flat list of
+        * DescriptorModel elements. The first item in the array is root.
+
+        * @returns {Function}
+        */
+       static buildCatalogItemFactory(catalogs) {
+
+               function findCatalogItemByTypeAndId(type, id) {
+                       return catalogs.filter(catalog => catalog.type === type).reduce((a, b) => a.concat(b.descriptors), []).filter(d => d.id === id)[0];
+               }
+
+               function mapVLD(vld, containerList) {
+                       containerList.push(vld);
+                       vld.connection.forEach(d => containerList.push(d));
+               }
+
+               function mapIVLD(ivld, containerList) {
+                       containerList.push(ivld);
+                       ivld.connection.forEach(d => containerList.push(d));
+               }
+
+               function mapRspConnectionPoint(cp, containerList) {
+                       containerList.push(cp);
+               }
+
+               function mapClassifier(classifier, containerList) {
+                       containerList.push(classifier);
+                       // get the referenced vnfd required for rendering the connection point
+                       const vnfdRef = findCatalogItemByTypeAndId('vnfd', classifier.model['vnfd-id-ref']);
+                       if (vnfdRef) {
+                               classifier.uiState.vnfdRef = vnfdRef;
+                       }
+                       classifier.matchAttributes.forEach(attr => containerList.push(attr));
+               }
+
+               function mapRSP(rsp, containerList) {
+                       containerList.push(rsp);
+                       rsp.vnfdConnectionPointRef.forEach(cpRef => mapRspConnectionPoint(cpRef, containerList));
+               }
+
+               function mapFG(fg, containerList) {
+                       containerList.push(fg);
+                       fg.rsp.forEach(rsp => mapRSP(rsp, containerList));
+                       fg.classifier.forEach(classifier => mapClassifier(classifier, containerList));
+               }
+
+               function mapVDU(vdu, containerList) {
+                       containerList.push(vdu);
+                       vdu.connectionPoint.forEach(d => containerList.push(d));
+               }
+
+               function mapCVNFD(cvnfd, containerList) {
+                       // get the referenced vnfd required for rendering the connection points
+                       const vnfdRef = findCatalogItemByTypeAndId('vnfd', cvnfd.model['vnfd-id-ref']);
+                       if (!vnfdRef) {
+                               console.warn('No VNFD found in catalog with id: ' + cvnfd['vnfd-id-ref']);
+                       }
+                       cvnfd.vnfdRef = vnfdRef;
+                       containerList.push(cvnfd);
+                       cvnfd.vld.forEach(vld => mapIVLD(vld, containerList));
+                       cvnfd.connectionPoint.forEach(cp => containerList.push(cp));
+               }
+
+               function mapNSD(nsd, containerList) {
+                       containerList.push(nsd);
+                       nsd.constituentVnfd.forEach(cvnfd => mapCVNFD(cvnfd, containerList));
+                       nsd.vld.forEach(vld => mapVLD(vld, containerList));
+                       nsd.vnffgd.forEach(fg => mapFG(fg, containerList));
+               }
+
+               function mapVNFD(vnfd, containerList) {
+                       containerList.push(vnfd);
+                       vnfd.vdu.forEach(vdu => mapVDU(vdu, containerList));
+                       vnfd.vld.forEach(vld => mapIVLD(vld, containerList));
+                       vnfd.connectionPoint.forEach(cp => containerList.push(cp));
+               }
+
+               function mapPNFD(pnfd, containerList) {
+                       containerList.push(pnfd);
+               }
+
+               return (containerList, obj) => {
+                       if (_.isEmpty(obj)) {
+                               return containerList;
+                       }
+                       switch (obj.uiState.type) {
+                       case 'nsd':
+                               mapNSD(DescriptorModelFactory.newNetworkService(obj), containerList);
+                               break;
+                       case 'vnfd':
+                               mapVNFD(DescriptorModelFactory.newVirtualNetworkFunction(obj), containerList);
+                               break;
+                       case 'pnfd':
+                               mapPNFD(DescriptorModelFactory.newPhysicalNetworkFunction(obj), containerList);
+                               break;
+                       default:
+                               throw new ReferenceError('only catalog items can be rendered in the canvas. unexpected type: ' + obj.uiState.type);
+                       }
+                       return containerList;
+               };
+
+       }
+
+       static newNetworkService(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new NetworkService(model, parent);
+       }
+
+       static newConstituentVnfd(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfd(model, parent);
+       }
+
+       static newVirtualNetworkFunction(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunction(model, parent);
+       }
+
+       static newVirtualNetworkFunctionConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunctionConnectionPoint(model, parent);
+       }
+
+       static newInternalConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalConnectionPoint(model, parent);
+       }
+
+       static newVirtualDeploymentUnit(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnit(model, parent);
+       }
+
+       static newVirtualDeploymentUnitInternalConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnitInternalConnectionPoint(model, parent);
+       }
+
+       static newVirtualLink(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualLink(model, parent);
+       }
+
+       static newInternalVirtualLink(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalVirtualLink(model, parent);
+       }
+
+       static newPhysicalNetworkFunction(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new PhysicalNetworkFunction(model, parent);
+       }
+
+       static newConstituentVnfdConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfdConnectionPoint(model, parent);
+       }
+
+       static newVnfdConnectionPointRef(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VnfdConnectionPointRef(model, parent);
+       }
+
+       static newForwardingGraph(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ForwardingGraph(model, parent);
+       }
+
+       static newRecordServicePath(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new RecordServicePath(model, parent);
+       }
+
+       static newRspConnectionPointRef(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new RspConnectionPointRef(model, parent);
+       }
+
+       static newVirtualNetworkFunctionReadOnlyWrapper(vnfdToWrap, parent) {
+               let model;
+               if (vnfdToWrap instanceof DescriptorModel) {
+                       if (vnfdToWrap instanceof VirtualNetworkFunction) {
+                               model = vnfdToWrap.model;
+                       } else {
+                               throw new ReferenceError(`expected a VirtualNetworkFunction but got a ${vnfdToWrap.className}`);
+                       }
+               } else {
+                       model = vnfdToWrap;
+               }
+               return new VirtualNetworkFunctionReadOnlyWrapper(_.cloneDeep(model), parent);
+       }
+
+       static newClassifier(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new Classifier(model, parent);
+       }
+
+       static newClassifierMatchAttributes(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ClassifierMatchAttributes(model, parent);
+       }
+
+       static newInternalConnectionPointRef(model, parent) {
+               // note do not find children bc model is not an object it is a leaf-list primative and so the class manages it
+               return new InternalConnectionPointRef(model, parent);
+       }
+
+       /**
+        * Special instance of a RecordServicePath that will create its parent ForwardingGraph it does not exist.
+        *
+        * This is useful to present a stub RSP as an initiator to create Paths without explicitly creating an RSP - just
+        * start building a path and it auto-magically builds the RSP.
+        *
+        * @param parent
+        * @param model
+        */
+       static newRecordServicePathFactory(model, parent) {
+               return new AutoCreateRecordServicePath(model, parent);
+       }
+
+       static isContainer(obj) {
+               return obj instanceof DescriptorModel;
+       }
+
+       static isConnector(obj) {
+               return obj instanceof ConnectionPoint;
+       }
+
+       static isConnectionPoint(obj) {
+               return obj instanceof ConnectionPoint;
+       }
+
+       static isConstituentVnfd(obj) {
+               return obj instanceof ConstituentVnfd;
+       }
+
+       static isConstituentVnfdWithServiceChain(obj, chain) {
+               return obj instanceof ConstituentVnfd && obj.vnfdServiceFunctionChain === chain;
+       }
+
+       static isNetworkService(obj) {
+               return obj instanceof NetworkService;
+       }
+
+       static isVnfdConnectionPointRef(obj) {
+               return obj instanceof VnfdConnectionPointRef;
+       }
+
+       static isRecordServicePath(obj) {
+               return obj instanceof RecordServicePath;
+       }
+
+       static isRspConnectionPointRef(obj) {
+               return obj instanceof RspConnectionPointRef;
+       }
+
+       static isVirtualLink(obj) {
+               return obj instanceof VirtualLink;
+       }
+
+       static isVirtualNetworkFunction(obj) {
+               return obj instanceof VirtualNetworkFunction;
+       }
+
+       static isForwardingGraph(obj) {
+               return obj instanceof ForwardingGraph;
+       }
+
+       static isInternalConnectionPoint(obj) {
+               return obj instanceof InternalConnectionPoint;
+       }
+
+       static isInternalVirtualLink(obj) {
+               return obj instanceof InternalVirtualLink;
+       }
+
+       static get VirtualLink () {
+               return VirtualLink;
+       }
+
+       static get NetworkService () {
+               return NetworkService;
+       }
+
+       static get ForwardingGraph () {
+               return ForwardingGraph;
+       }
+
+       static get VirtualNetworkFunction () {
+               return VirtualNetworkFunction;
+       }
+
+       static get ConstituentVnfd () {
+               return ConstituentVnfd;
+       }
+
+       static get Classifier() {
+               return Classifier;
+       }
+
+       static get ClassifierMatchAttributes() {
+               return ClassifierMatchAttributes;
+       }
+
+       static get VnfdConnectionPointRef() {
+               return VnfdConnectionPointRef;
+       }
+
+       static get VirtualDeploymentUnit() {
+               return VirtualDeploymentUnit;
+       }
+
+       static get InternalConnectionPoint() {
+               return InternalConnectionPoint;
+       }
+
+       static get InternalVirtualLink() {
+               return InternalVirtualLink;
+       }
+
+       static get InternalConnectionPointRef() {
+               return InternalConnectionPointRef;
+       }
+
+       static get VirtualNetworkFunctionConnectionPoint() {
+               return VirtualNetworkFunctionConnectionPoint;
+       }
+
+       static get VirtualDeploymentUnitInternalConnectionPoint() {
+               return VirtualDeploymentUnitInternalConnectionPoint;
+       }
+
+}
+
+/**
+ * Auto create a RecordServicePath when a VnfdConnectionPointRef is added.
+ */
+class AutoCreateRecordServicePath extends RecordServicePath {
+
+       constructor(model, parent) {
+               super(model, null);
+               this.parent = parent;
+               this.isFactory = true;
+       }
+
+       create() {
+               return this.parent.createRsp();
+       }
+
+       createVnfdConnectionPointRef(obj) {
+               const rsp = this.create();
+               rsp.createVnfdConnectionPointRef(obj);
+               return rsp;
+       }
+
+}
+
+export default DescriptorModelFactory;
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFields.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFields.js
new file mode 100644 (file)
index 0000000..40228ee
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 1/19/16.
+ *
+ * The fields used to populate the 'Basic' details editor panel.
+ */
+const common = ['logo', 'name', 'short-name', 'description', 'vendor', 'version'];
+export default {
+       simpleList: ['constituent-vnfd', 'vnffgd', 'vld', 'vdu', 'internal-vld'],
+       common: common.concat(),
+       nsd: common.concat(['constituent-vnfd', 'vnffgd', 'vld']),
+       vld: common.concat([]),
+       vnfd: common.concat(['vdu', 'internal-vld']),
+       'vnfd.vdu': common.concat(['image', 'external-interface', 'vm-flavor', 'cloud-init']),
+       // white-list valid fields to send in the meta field
+       meta: ['containerPositionMap']
+};
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMeta.json b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMeta.json
new file mode 100644 (file)
index 0000000..e676019
--- /dev/null
@@ -0,0 +1,4336 @@
+{
+     "nsd": {
+          "name": "nsd",
+          "type": "list",
+          "cardinality": "0..N",
+          "properties": [
+               {
+                    "name": "id",
+                    "type": "leaf",
+                    "description": "Identifier for the NSD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "name",
+                    "type": "leaf",
+                    "description": "NSD name.",
+                    "cardinality": "1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "short-name",
+                    "type": "leaf",
+                    "description": "NSD short name.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "type": "leaf",
+                    "description": "Vendor of the NSD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "logo",
+                    "type": "leaf",
+                    "description": "File path for the vendor specific logo. For example icons/mylogo.png. The logo should be part of the network service",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "description",
+                    "type": "leaf",
+                    "description": "Description of the NSD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "version",
+                    "type": "leaf",
+                    "description": "Version of the NSD",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "meta",
+                    "type": "leaf",
+                    "description": "Any meta-data needed by the UI",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "connection-point",
+                    "type": "list",
+                    "description": "List for external connection points. Each NS has one or more external connection points. As the name implies that external connection points are used for connecting the NS to other NS or to external networks. Each NS exposes these connection points to the orchestrator. The orchestrator can construct network service chains by connecting the connection points between different NS.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the NS connection point.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "VPORT"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "vld",
+                    "type": "list",
+                    "description": "List of Virtual Link Descriptors.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the VLD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Virtual Link Descriptor (VLD) name.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name for VLD for UI",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "vendor",
+                              "type": "leaf",
+                              "description": "Provider of the VLD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "description": "Description of the VLD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "version",
+                              "type": "leaf",
+                              "description": "Version of the VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "ELAN"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "root-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the aggregate bandwidth.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "leaf-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the bandwidth of branches.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "vnfd-connection-point-ref",
+                              "type": "list",
+                              "description": "A list of references to connection points.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to member-vnf within constituent-vnfds",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a vnfd. This is a leafref to path: ../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         },
+                         {
+                              "name": "provider-network",
+                              "type": "container",
+                              "description": "Container for the provider network.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "physical-network",
+                                        "type": "leaf",
+                                        "description": "Name of the phsyical network on which the provider network is built.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "overlay-type",
+                                        "type": "leaf",
+                                        "description": "Type of the overlay network.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LOCAL": {
+                                                            "value": 0
+                                                       },
+                                                       "FLAT": {
+                                                            "value": 1
+                                                       },
+                                                       "VLAN": {
+                                                            "value": 2
+                                                       },
+                                                       "VXLAN": {
+                                                            "value": 3
+                                                       },
+                                                       "GRE": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "segmentation_id",
+                                        "type": "leaf",
+                                        "description": "Segmentation ID",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "constituent-vnfd",
+                    "type": "list",
+                    "description": "List of VNFDs that are part of this network service.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "member-vnf-index",
+                              "type": "leaf",
+                              "description": "Identifier/index for the VNFD. This separate id is required to ensure that multiple VNFs can be part of single NS",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "vnfd-id-ref",
+                              "type": "leaf",
+                              "description": "Identifier for the VNFD.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "start-by-default",
+                              "type": "leaf",
+                              "description": "VNFD is started as part of the NS instantiation",
+                              "cardinality": "0..1",
+                              "data-type": "boolean",
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "member-vnf-index"
+                    ]
+               },
+               {
+                    "name": "scaling-group-descriptor",
+                    "type": "list",
+                    "description": "scaling group descriptor within this network service. The scaling group defines a group of VNFs, and the ratio of VNFs in the network service that is used as target for scaling action",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of this scaling group.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "min-instance-count",
+                              "type": "leaf",
+                              "description": "Minimum instances of the scaling group which are allowed. These instances are created by default when the network service is instantiated.",
+                              "cardinality": "0..1",
+                              "data-type": "uint32",
+                              "properties": []
+                         },
+                         {
+                              "name": "max-instance-count",
+                              "type": "leaf",
+                              "description": "Maximum instances of this scaling group that are allowed in a single network service. The network service scaling will fail, when the number of service group instances exceed the max-instance-count specified.",
+                              "cardinality": "0..1",
+                              "data-type": "uint32",
+                              "properties": []
+                         },
+                         {
+                              "name": "vnfd-member",
+                              "type": "list",
+                              "description": "List of VNFs in this scaling group",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "member VNF index of this member VNF",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../constituent-vnfd/member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "count",
+                                        "type": "leaf",
+                                        "description": "count of this member VNF within this scaling group. The count allows to define the number of instances when a scaling action targets this scaling group",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         },
+                         {
+                              "name": "scaling-config-action",
+                              "type": "list",
+                              "description": "List of scaling config actions",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "trigger",
+                                        "type": "leaf",
+                                        "description": "scaling trigger",
+                                        "cardinality": "0..1",
+                                        "data-type": "scaling-trigger",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "ns-config-primitive-name-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to the NS config name primitive",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../config-primitive/name"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "trigger"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "placement-groups",
+                    "type": "list",
+                    "description": "List of placement groups at NS level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "member-vnfd",
+                              "type": "list",
+                              "description": "List of VNFDs that are part of this placement group",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "member VNF index of this member VNF",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../constituent-vnfd/member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "Identifier for the VNFD.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Place group construct to define the compute resource placement strategy in cloud environment",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "requirement",
+                              "type": "leaf",
+                              "description": "This is free text space used to describe the intent/rationale behind this placement group. This is for human consumption only",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "strategy",
+                              "type": "leaf",
+                              "description": "Strategy associated with this placement group Following values are possible - COLOCATION: Colocation strategy imply intent to share the physical infrastructure (hypervisor/network) among all members of this group. - ISOLATION: Isolation strategy imply intent to not share the physical infrastructure (hypervisor/network) among the members of this group. ",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "COLOCATION": {
+                                                  "value": 0
+                                             },
+                                             "ISOLATION": {
+                                                  "value": 1
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "vnf-dependency",
+                    "type": "list",
+                    "description": "List of VNF dependencies.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "vnf-source-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "vnf-depends-on-ref",
+                              "type": "leaf",
+                              "description": "Reference to VNF that sorce VNF depends.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "vnf-source-ref"
+                    ]
+               },
+               {
+                    "name": "vnffgd",
+                    "type": "list",
+                    "description": "List of VNF Forwarding Graph Descriptors (VNFFGD).",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the VNFFGD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "VNFFGD name.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name for VNFFGD for UI",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "vendor",
+                              "type": "leaf",
+                              "description": "Provider of the VNFFGD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "description": "Description of the VNFFGD.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "version",
+                              "type": "leaf",
+                              "description": "Version of the VNFFGD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "rsp",
+                              "type": "list",
+                              "description": "List of Rendered Service Paths (RSP).",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "id",
+                                        "type": "leaf",
+                                        "description": "Identifier for the RSP.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "RSP name.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "list",
+                                        "description": "A list of references to connection points.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "member-vnf-index-ref",
+                                                  "type": "leaf",
+                                                  "description": "Reference to member-vnf within constituent-vnfds",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "leafref": {
+                                                            "path": "../../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "order",
+                                                  "type": "leaf",
+                                                  "description": "A number that denotes the order of a VNF in a chain",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint8",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vnfd-id-ref",
+                                                  "type": "leaf",
+                                                  "description": "A reference to a vnfd. This is a leafref to path: ../../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vnfd-connection-point-ref",
+                                                  "type": "leaf",
+                                                  "description": "A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "member-vnf-index-ref"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "id"
+                              ]
+                         },
+                         {
+                              "name": "classifier",
+                              "type": "list",
+                              "description": "List of classifier rules.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "id",
+                                        "type": "leaf",
+                                        "description": "Identifier for the classifier rule.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the classifier.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "rsp-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to the RSP.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../nsd:rsp/nsd:id"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to member-vnf within constituent-vnfds",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../nsd:constituent-vnfd/nsd:member-vnf-index"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a vnfd. This is a leafref to path: ../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a connection point name in a vnfd. This is a leafref to path: /vnfd:vnfd-catalog/vnfd:vnfd + [vnfd:id = current()/../nsd:vnfd-id-ref] + /vnfd:connection-point/vnfd:name NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "match-attributes",
+                                        "type": "list",
+                                        "description": "List of match attributes.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "id",
+                                                  "type": "leaf",
+                                                  "description": "Identifier for the classifier match attribute rule.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "ip-proto",
+                                                  "type": "leaf",
+                                                  "description": "IP Protocol.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint8",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "source-ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "destination-ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "source-port",
+                                                  "type": "leaf",
+                                                  "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "uint16": {
+                                                            "range": "0..65535"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "destination-port",
+                                                  "type": "leaf",
+                                                  "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "uint16": {
+                                                            "range": "0..65535"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "id"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "id"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "parameter-pool",
+                    "type": "list",
+                    "description": "Pool of parameter values which must be pulled from during configuration",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the configuration value pool",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "range",
+                              "type": "container",
+                              "description": "Create a range of values to populate the pool with",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "start-value",
+                                        "type": "leaf",
+                                        "description": "Generated pool values start at this value",
+                                        "cardinality": "1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "end-value",
+                                        "type": "leaf",
+                                        "description": "Generated pool values stop at this value",
+                                        "cardinality": "1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "http-endpoint",
+                    "type": "list",
+                    "description": "List of http endpoints to be used by monitoring params",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "path",
+                              "type": "leaf",
+                              "description": "The HTTP path on the management server",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "https",
+                              "type": "leaf",
+                              "description": "Pick HTTPS instead of HTTP , Default is false",
+                              "cardinality": "0..1",
+                              "data-type": "boolean",
+                              "properties": []
+                         },
+                         {
+                              "name": "port",
+                              "type": "leaf",
+                              "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "uint16": {
+                                        "range": "0..65535"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "username",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth username",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "password",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth password",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "polling_interval_secs",
+                              "type": "leaf",
+                              "description": "The HTTP polling interval in seconds",
+                              "cardinality": "0..1",
+                              "data-type": "uint8",
+                              "properties": []
+                         },
+                         {
+                              "name": "method",
+                              "type": "leaf",
+                              "description": "Type of HTTP operation",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "POST": {
+                                                  "value": 0
+                                             },
+                                             "PUT": {
+                                                  "value": 1
+                                             },
+                                             "GET": {
+                                                  "value": 2
+                                             },
+                                             "DELETE": {
+                                                  "value": 3
+                                             },
+                                             "OPTIONS": {
+                                                  "value": 4
+                                             },
+                                             "PATCH": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "headers",
+                              "type": "list",
+                              "description": "Custom HTTP headers to put on HTTP request",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "key",
+                                        "type": "leaf",
+                                        "description": "HTTP header key",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "value",
+                                        "type": "leaf",
+                                        "description": "HTTP header value",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "key"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "path"
+                    ]
+               },
+               {
+                    "name": "monitoring-param",
+                    "type": "list",
+                    "description": "List of monitoring parameters at the NS level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "http-endpoint-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../http-endpoint/path"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-method",
+                              "type": "leaf",
+                              "description": "The method to extract a value from a JSON response NAMEKEY - Use the name as the key for a non-nested value. JSONPATH - Use jsonpath-rw implemenation to extract a value. OBJECTPATH - Use objectpath implemenation to extract a value.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "NAMEKEY": {
+                                                  "value": 0
+                                             },
+                                             "JSONPATH": {
+                                                  "value": 1
+                                             },
+                                             "OBJECTPATH": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "group-tag",
+                              "type": "leaf",
+                              "description": "A simple tag to group monitoring parameters",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-type",
+                              "type": "leaf",
+                              "description": "The type of the parameter value",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "INT": {
+                                                  "value": 0
+                                             },
+                                             "DECIMAL": {
+                                                  "value": 1
+                                             },
+                                             "STRING": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-integer",
+                              "type": "leaf",
+                              "description": "Current value for an integer parameter",
+                              "cardinality": "0..1",
+                              "data-type": "int64",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-decimal",
+                              "type": "leaf",
+                              "description": "Current value for a decimal parameter",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "decimal64": {
+                                        "fraction-digits": "4"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-string",
+                              "type": "leaf",
+                              "description": "Current value for a string parameter",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "widget-type",
+                              "type": "leaf",
+                              "description": "Type of the widget, typically used by the UI.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "HISTOGRAM": {
+                                                  "value": 0
+                                             },
+                                             "BAR": {
+                                                  "value": 1
+                                             },
+                                             "GAUGE": {
+                                                  "value": 2
+                                             },
+                                             "SLIDER": {
+                                                  "value": 3
+                                             },
+                                             "COUNTER": {
+                                                  "value": 4
+                                             },
+                                             "TEXTBOX": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "units",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-params",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "json-path",
+                                        "type": "leaf",
+                                        "description": "The jsonpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "object-path",
+                                        "type": "leaf",
+                                        "description": "The objectpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "numeric-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-value",
+                                        "type": "leaf",
+                                        "description": "Minimum value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-value",
+                                        "type": "leaf",
+                                        "description": "Maxium value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "text-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-length",
+                                        "type": "leaf",
+                                        "description": "Minimum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-length",
+                                        "type": "leaf",
+                                        "description": "Maximum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "input-parameter-xpath",
+                    "type": "list",
+                    "description": "List of xpaths to parameters inside the NSD the can be customized during the instantiation.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "xpath",
+                              "type": "leaf",
+                              "description": "An xpath that specifies the element in a descriptor.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "label",
+                              "type": "leaf",
+                              "description": "A descriptive string",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "default-value",
+                              "type": "leaf",
+                              "description": " A default value for this input parameter",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "xpath"
+                    ]
+               },
+               {
+                    "name": "config-primitive",
+                    "type": "list",
+                    "description": "Network service level configuration primitives.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the configuration primitive.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "user-defined-script",
+                              "type": "leaf",
+                              "description": "A user defined script.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "parameter",
+                              "type": "list",
+                              "description": "List of parameters to the configuration primitive.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the parameter.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "data-type",
+                                        "type": "leaf",
+                                        "description": "Data type associated with the name.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "STRING": {
+                                                            "value": 0
+                                                       },
+                                                       "INTEGER": {
+                                                            "value": 1
+                                                       },
+                                                       "BOOLEAN": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "mandatory",
+                                        "type": "leaf",
+                                        "description": "Is this field mandatory",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "default-value",
+                                        "type": "leaf",
+                                        "description": "The default value for this field",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "parameter-pool",
+                                        "type": "leaf",
+                                        "description": "NSD Parameter pool name to use for this paramter",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "read-only",
+                                        "type": "leaf",
+                                        "description": "The value should be greyed out by the UI. Only applies to parameters with default values.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "hidden",
+                                        "type": "leaf",
+                                        "description": "The value should be hidden by the UI. Only applies to parameters with default values.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "parameter-group",
+                              "type": "list",
+                              "description": "Grouping of parameters which are logically grouped in UI",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the parameter group",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "mandatory",
+                                        "type": "leaf",
+                                        "description": "Is this parameter group mandatory",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "parameter",
+                                        "type": "list",
+                                        "description": "List of parameters to the configuration primitive.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the parameter.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "data-type",
+                                                  "type": "leaf",
+                                                  "description": "Data type associated with the name.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "enumeration": {
+                                                            "enum": {
+                                                                 "STRING": {
+                                                                      "value": 0
+                                                                 },
+                                                                 "INTEGER": {
+                                                                      "value": 1
+                                                                 },
+                                                                 "BOOLEAN": {
+                                                                      "value": 2
+                                                                 }
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "mandatory",
+                                                  "type": "leaf",
+                                                  "description": "Is this field mandatory",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "boolean",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "default-value",
+                                                  "type": "leaf",
+                                                  "description": "The default value for this field",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "parameter-pool",
+                                                  "type": "leaf",
+                                                  "description": "NSD Parameter pool name to use for this paramter",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "read-only",
+                                                  "type": "leaf",
+                                                  "description": "The value should be greyed out by the UI. Only applies to parameters with default values.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "boolean",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "hidden",
+                                                  "type": "leaf",
+                                                  "description": "The value should be hidden by the UI. Only applies to parameters with default values.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "boolean",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "name"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "vnf-primitive-group",
+                              "type": "list",
+                              "description": "List of configuration primitives grouped by VNF.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vnf-index-ref",
+                                        "type": "leaf",
+                                        "description": "Reference to member-vnf within constituent-vnfds",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-id-ref",
+                                        "type": "leaf",
+                                        "description": "A reference to a vnfd. This is a leafref to path: ../../../../nsd:constituent-vnfd + [nsd:id = current()/../nsd:id-ref] + /nsd:vnfd-id-ref NOTE: An issue with confd is preventing the use of xpath. Seems to be an issue with leafref to leafref, whose target is in a different module. Once that is resovled this will switched to use leafref",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-name",
+                                        "type": "leaf",
+                                        "description": "Name of the VNFD",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "primitive",
+                                        "type": "list",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "index",
+                                                  "type": "leaf",
+                                                  "description": "Index of this primitive",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint32",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the primitive in the VNF primitive ",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "index"
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "member-vnf-index-ref"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               }
+          ],
+          "key": [
+               "id"
+          ]
+     },
+     "vnfd": {
+          "name": "vnfd",
+          "type": "list",
+          "cardinality": "0..N",
+          "properties": [
+               {
+                    "name": "id",
+                    "type": "leaf",
+                    "description": "Identifier for the VNFD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "name",
+                    "type": "leaf",
+                    "description": "VNFD name.",
+                    "cardinality": "1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "short-name",
+                    "type": "leaf",
+                    "description": "VNFD short name.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "vendor",
+                    "type": "leaf",
+                    "description": "Vendor of the VNFD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "logo",
+                    "type": "leaf",
+                    "description": "Vendor logo for the Virtual Network Function",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "description",
+                    "type": "leaf",
+                    "description": "Description of the VNFD.",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "version",
+                    "type": "leaf",
+                    "description": "Version of the VNFD",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "service-function-chain",
+                    "type": "leaf",
+                    "description": "Type of node in Service Function Chaining Architecture",
+                    "cardinality": "0..1",
+                    "data-type": {
+                         "enumeration": {
+                              "enum": {
+                                   "UNAWARE": null,
+                                   "CLASSIFIER": null,
+                                   "SF": null,
+                                   "SFF": null
+                              }
+                         }
+                    },
+                    "properties": []
+               },
+               {
+                    "name": "service-function-type",
+                    "type": "leaf",
+                    "description": "Type of Service Function. NOTE: This needs to map with Service Function Type in ODL to support VNFFG. Service Function Type is manadatory param in ODL SFC. This is temporarily set to string for ease of use",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "meta",
+                    "type": "leaf",
+                    "description": "Any meta-data needed by the UI",
+                    "cardinality": "0..1",
+                    "data-type": "string",
+                    "properties": []
+               },
+               {
+                    "name": "mgmt-interface",
+                    "type": "container",
+                    "description": "Interface over which the VNF is managed.",
+                    "cardinality": "0..1",
+                    "properties": [
+                         {
+                              "name": "endpoint-type",
+                              "type": "choice",
+                              "description": "Indicates the type of management endpoint.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "ip",
+                                        "type": "case",
+                                        "description": "Specifies the static IP address for managing the VNF.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "vdu-id",
+                                        "type": "case",
+                                        "description": "Use the default management interface on this VDU.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "vdu-id",
+                                                  "type": "leaf",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "leafref": {
+                                                            "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "cp",
+                                        "type": "case",
+                                        "description": "Use the ip address associated with this connection point.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "cp",
+                                                  "type": "leaf",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "leafref": {
+                                                            "path": "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name"
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             }
+                                        ]
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "port",
+                              "type": "leaf",
+                              "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "uint16": {
+                                        "range": "0..65535"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "dashboard-params",
+                              "type": "container",
+                              "description": "Parameters for the VNF dashboard",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "path",
+                                        "type": "leaf",
+                                        "description": "The HTTP path for the dashboard",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "https",
+                                        "type": "leaf",
+                                        "description": "Pick HTTPS instead of HTTP , Default is false",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "port",
+                                        "type": "leaf",
+                                        "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "uint16": {
+                                                  "range": "0..65535"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "vnf-configuration",
+                              "type": "container",
+                              "description": "Information regarding the VNF configuration is captured here. ",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "config-method",
+                                        "type": "choice",
+                                        "description": "Defines the configuration method for the VNF.",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "netconf",
+                                                  "type": "case",
+                                                  "description": "Use NETCONF for configuring the VNF.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "netconf",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "target",
+                                                                      "type": "leaf",
+                                                                      "description": "Netconf configuration target",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "running": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "candidate": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "protocol",
+                                                                      "type": "leaf",
+                                                                      "description": "Protocol to use for netconf (e.g. ssh)",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "None": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "ssh": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "port",
+                                                                      "type": "leaf",
+                                                                      "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "uint16": {
+                                                                                "range": "0..65535"
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "rest",
+                                                  "type": "case",
+                                                  "description": "Use REST for configuring the VNF.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "rest",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "port",
+                                                                      "type": "leaf",
+                                                                      "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "uint16": {
+                                                                                "range": "0..65535"
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "script",
+                                                  "type": "case",
+                                                  "description": "Use custom script for configuring the VNF. This script is executed in the context of Orchestrator.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "script",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "script-type",
+                                                                      "type": "leaf",
+                                                                      "description": "Script type - currently supported : bash, expect",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "bash": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "expect": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "juju",
+                                                  "type": "case",
+                                                  "description": "Configure the VNF through Juju.",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "juju",
+                                                            "type": "container",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "charm",
+                                                                      "type": "leaf",
+                                                                      "description": "Juju charm to use with the VNF.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": "string",
+                                                                      "properties": []
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-access",
+                                        "type": "container",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "mgmt-ip-address",
+                                                  "type": "leaf",
+                                                  "description": "The ip-address type represents an IP address and is IP version neutral. The format of the textual representation implies the IP version. This type supports scoped addresses by allowing zone identifiers in the address format.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "union": {
+                                                            "type": {
+                                                                 "inet:ipv4-address": null,
+                                                                 "inet:ipv6-address": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "username",
+                                                  "type": "leaf",
+                                                  "description": "username for configuration.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "password",
+                                                  "type": "leaf",
+                                                  "description": "Password for configuration access authentication.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-attributes",
+                                        "type": "container",
+                                        "description": "Miscelaneous input parameters to be considered while processing the NSD to apply configuration",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "config-priority",
+                                                  "type": "leaf",
+                                                  "description": "Configuration priority - order of confgiration to be applied to each VNF in this NS, low number gets precedence over high number",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "config-delay",
+                                                  "type": "leaf",
+                                                  "description": "Wait (seconds) before applying the configuration to VNF",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-primitive",
+                                        "type": "list",
+                                        "description": "List of configuration primitives supported by the configuration agent for this VNF.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the configuration primitive.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "parameter",
+                                                  "type": "list",
+                                                  "description": "List of parameters to the configuration primitive.",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "name",
+                                                            "type": "leaf",
+                                                            "description": "Name of the parameter.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "data-type",
+                                                            "type": "leaf",
+                                                            "description": "Data type associated with the name.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": {
+                                                                 "enumeration": {
+                                                                      "enum": {
+                                                                           "STRING": {
+                                                                                "value": 0
+                                                                           },
+                                                                           "INTEGER": {
+                                                                                "value": 1
+                                                                           },
+                                                                           "BOOLEAN": {
+                                                                                "value": 2
+                                                                           }
+                                                                      }
+                                                                 }
+                                                            },
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "mandatory",
+                                                            "type": "leaf",
+                                                            "description": "Is this field mandatory",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "boolean",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "default-value",
+                                                            "type": "leaf",
+                                                            "description": "The default value for this field",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "parameter-pool",
+                                                            "type": "leaf",
+                                                            "description": "NSD Parameter pool name to use for this paramter",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "read-only",
+                                                            "type": "leaf",
+                                                            "description": "The value should be greyed out by the UI. Only applies to parameters with default values.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "boolean",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "hidden",
+                                                            "type": "leaf",
+                                                            "description": "The value should be hidden by the UI. Only applies to parameters with default values.",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "boolean",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "name"
+                                                  ]
+                                             }
+                                        ],
+                                        "key": [
+                                             "name"
+                                        ]
+                                   },
+                                   {
+                                        "name": "initial-config-primitive",
+                                        "type": "list",
+                                        "description": "Initial set of configuration primitives.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "seq",
+                                                  "type": "leaf",
+                                                  "description": "Sequence number for the configuration primitive.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "name",
+                                                  "type": "leaf",
+                                                  "description": "Name of the configuration primitive.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "parameter",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "name",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       },
+                                                       {
+                                                            "name": "value",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "name"
+                                                  ]
+                                             }
+                                        ],
+                                        "key": [
+                                             "seq"
+                                        ]
+                                   },
+                                   {
+                                        "name": "config-template",
+                                        "type": "leaf",
+                                        "description": "Configuration template for each VNF",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ]
+               },
+               {
+                    "name": "internal-vld",
+                    "type": "list",
+                    "description": "List of Internal Virtual Link Descriptors (VLD). The internal VLD describes the basic topology of the connectivity (e.g. E-LAN, E-Line, E-Tree) between internal VNF components of the system.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the internal VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name of the internal VLD",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of virtual link ELAN: A multipoint service connecting a set of VNFs // ELINE: For a simple point to point connection // between a VNF and the existing network. // ETREE: A multipoint service connecting one or // more roots and a set of leaves, but // preventing inter-leaf communication.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "ELAN"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "root-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the aggregate bandwidth.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "leaf-bandwidth",
+                              "type": "leaf",
+                              "description": "For ELAN this is the bandwidth of branches.",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "internal-connection-point-ref",
+                              "type": "leaf-list",
+                              "cardinality": "0..N",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../vdu/internal-connection-point/id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "provider-network",
+                              "type": "container",
+                              "description": "Container for the provider network.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "physical-network",
+                                        "type": "leaf",
+                                        "description": "Name of the phsyical network on which the provider network is built.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "overlay-type",
+                                        "type": "leaf",
+                                        "description": "Type of the overlay network.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LOCAL": {
+                                                            "value": 0
+                                                       },
+                                                       "FLAT": {
+                                                            "value": 1
+                                                       },
+                                                       "VLAN": {
+                                                            "value": 2
+                                                       },
+                                                       "VXLAN": {
+                                                            "value": 3
+                                                       },
+                                                       "GRE": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "segmentation_id",
+                                        "type": "leaf",
+                                        "description": "Segmentation ID",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "connection-point",
+                    "type": "list",
+                    "description": "List for external connection points. Each VNF has one or more external connection points. As the name implies that external connection points are used for connecting the VNF to other VNFs or to external networks. Each VNF exposes these connection points to the orchestrator. The orchestrator can construct network services by connecting the connection points between different VNFs. The NFVO will use VLDs and VNFFGs at the network service level to construct network services.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Name of the connection point",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Identifier for the internal connection points",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "short-name",
+                              "type": "leaf",
+                              "description": "Short name of the connection point",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "type",
+                              "type": "leaf",
+                              "description": "Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": "VPORT"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "vdu",
+                    "type": "list",
+                    "description": "List of Virtual Deployment Units",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "description": "Unique id for the VDU",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Unique name for the VDU",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "description": "Description of the VDU.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "count",
+                              "type": "leaf",
+                              "description": "Number of instances of VDU",
+                              "cardinality": "0..1",
+                              "data-type": "uint64",
+                              "properties": []
+                         },
+                         {
+                              "name": "mgmt-vpci",
+                              "type": "leaf",
+                              "description": "Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "image",
+                              "type": "leaf",
+                              "description": "Image name for the software image. If the image name is found within the VNF packaage it will be uploaded to all cloud accounts during onboarding process. Otherwise, the image must be added to the cloud account with the same name as entered here. ",
+                              "cardinality": "1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "image-checksum",
+                              "type": "leaf",
+                              "description": "Image md5sum for the software image. The md5sum, if provided, along with the image name uniquely identifies an image uploaded to the CAL. ",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "cloud-init",
+                              "type": "leaf",
+                              "description": "Content of cloud-init script",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "alarm",
+                              "type": "list",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "alarm-id",
+                                        "type": "leaf",
+                                        "description": "This field is reserved for the identifier assigned by the cloud provider",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "A human readable string to identify the alarm",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "description",
+                                        "type": "leaf",
+                                        "description": "A string containing a description of this alarm",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vdur-id",
+                                        "type": "leaf",
+                                        "description": "The identifier of the VDUR that the alarm is associated with",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "repeat",
+                                        "type": "leaf",
+                                        "description": "This flag indicates whether the alarm should be repeatedly emitted while the associated threshold has been crossed.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "enabled",
+                                        "type": "leaf",
+                                        "description": "This flag indicates whether the alarm has been enabled or disabled.",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "severity",
+                                        "type": "leaf",
+                                        "description": "An indication of the importance or ugency of the alarm",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LOW": {
+                                                            "value": 0
+                                                       },
+                                                       "MODERATE": {
+                                                            "value": 1
+                                                       },
+                                                       "CRITICAL": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "metric",
+                                        "type": "leaf",
+                                        "description": "The type of metrics to register the alarm for",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "CPU_UTILIZATION": {
+                                                            "value": 0
+                                                       },
+                                                       "MEMORY_UTILIZATION": {
+                                                            "value": 1
+                                                       },
+                                                       "STORAGE_UTILIZATION": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "statistic",
+                                        "type": "leaf",
+                                        "description": "The type of statistic to used to measure a metric to determine threshold crossing for an alarm.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "AVERAGE": {
+                                                            "value": 0
+                                                       },
+                                                       "MINIMUM": {
+                                                            "value": 1
+                                                       },
+                                                       "MAXIMUM": {
+                                                            "value": 2
+                                                       },
+                                                       "COUNT": {
+                                                            "value": 3
+                                                       },
+                                                       "SUM": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "operation",
+                                        "type": "leaf",
+                                        "description": "The relational operator used to define whether an alarm should be triggered when, say, the metric statistic goes above or below a specified value.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "GE": {
+                                                            "value": 0
+                                                       },
+                                                       "LE": {
+                                                            "value": 1
+                                                       },
+                                                       "GT": {
+                                                            "value": 2
+                                                       },
+                                                       "LT": {
+                                                            "value": 3
+                                                       },
+                                                       "EQ": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "value",
+                                        "type": "leaf",
+                                        "description": "This value defines the threshold that, if crossed, will trigger the alarm.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "decimal64": {
+                                                  "fraction-digits": "4"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "period",
+                                        "type": "leaf",
+                                        "description": "The period defines the length of time (seconds) that the metric data are collected over in oreder to evaluate the chosen statistic.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "evaluations",
+                                        "type": "leaf",
+                                        "description": "This is the number of samples of the metric statistic used to evaluate threshold crossing. Each sample or evaluation is equal to the metric statistic obtained for a given period. This can be used to mitigate spikes in the metric that may skew the statistic of interest.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint32",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "actions",
+                                        "type": "container",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "ok",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "url",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "url"
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "insufficient-data",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "url",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "url"
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "alarm",
+                                                  "type": "list",
+                                                  "cardinality": "0..N",
+                                                  "properties": [
+                                                       {
+                                                            "name": "url",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "string",
+                                                            "properties": []
+                                                       }
+                                                  ],
+                                                  "key": [
+                                                       "url"
+                                                  ]
+                                             }
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "alarm-id"
+                              ]
+                         },
+                         {
+                              "name": "internal-connection-point",
+                              "type": "list",
+                              "description": "List for internal connection points. Each VNFC has zero or more internal connection points. Internal connection points are used for connecting the VNF components internal to the VNF. If a VNF has only one VNFC, it may not have any internal connection points.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "internal-vld-ref",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../internal-vld/id"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the connection point",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "id",
+                                        "type": "leaf",
+                                        "description": "Identifier for the internal connection points",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "short-name",
+                                        "type": "leaf",
+                                        "description": "Short name of the connection point",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "type",
+                                        "type": "leaf",
+                                        "description": "Type of connection point VPORT: Virtual Port // VNIC_ADDR: Virtual NIC Address // PNIC_ADDR: Physical NIC Address // PPORT: Phsical Port.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": "VPORT"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "id"
+                              ]
+                         },
+                         {
+                              "name": "internal-interface",
+                              "type": "list",
+                              "description": "List of internal interfaces for the VNF",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of internal interface. Note that this name has only local significance to the VDU.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vdu-internal-connection-point-ref",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../internal-connection-point/id"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "virtual-interface",
+                                        "type": "container",
+                                        "description": "Container for the virtual interface properties",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "type",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the type of virtual interface between VM and host. VIRTIO : Use the traditional VIRTIO interface. PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface. SR-IOV : Use SR-IOV interface. OM-MGMT : Used to specify openmano mgmt external-connection type",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "enumeration": {
+                                                            "enum": {
+                                                                 "OM-MGMT": null,
+                                                                 "PCI-PASSTHROUGH": null,
+                                                                 "SR-IOV": null,
+                                                                 "VIRTIO": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vpci",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "bandwidth",
+                                                  "type": "leaf",
+                                                  "description": "Aggregate bandwidth of the NIC.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "external-interface",
+                              "type": "list",
+                              "description": "List of external interfaces for the VNF. The external interfaces enable sending traffic to and from VNF.",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "name",
+                                        "type": "leaf",
+                                        "description": "Name of the external interface. Note that this name has only local significance.",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "vnfd-connection-point-ref",
+                                        "type": "leaf",
+                                        "description": "Name of the external connection point.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../connection-point/name"
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "virtual-interface",
+                                        "type": "container",
+                                        "description": "Container for the virtual interface properties",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "type",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the type of virtual interface between VM and host. VIRTIO : Use the traditional VIRTIO interface. PCI-PASSTHROUGH : Use PCI-PASSTHROUGH interface. SR-IOV : Use SR-IOV interface. OM-MGMT : Used to specify openmano mgmt external-connection type",
+                                                  "cardinality": "0..1",
+                                                  "data-type": {
+                                                       "enumeration": {
+                                                            "enum": {
+                                                                 "OM-MGMT": null,
+                                                                 "PCI-PASSTHROUGH": null,
+                                                                 "SR-IOV": null,
+                                                                 "VIRTIO": null
+                                                            }
+                                                       }
+                                                  },
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "vpci",
+                                                  "type": "leaf",
+                                                  "description": "Specifies the virtual PCI address. Expressed in the following format dddd:dd:dd.d. For example 0000:00:12.0. This information can be used to pass as metadata during the VM creation.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "bandwidth",
+                                                  "type": "leaf",
+                                                  "description": "Aggregate bandwidth of the NIC.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ]
+                                   }
+                              ],
+                              "key": [
+                                   "name"
+                              ]
+                         },
+                         {
+                              "name": "vm-flavor",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "vcpu-count",
+                                        "type": "leaf",
+                                        "description": "Number of vcpus for the VM.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint16",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "memory-mb",
+                                        "type": "leaf",
+                                        "description": "Amount of memory in MB.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "storage-gb",
+                                        "type": "leaf",
+                                        "description": "Amount of disk space in GB.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "guest-epa",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "trusted-execution",
+                                        "type": "leaf",
+                                        "description": "This VM should be allocated from trusted pool",
+                                        "cardinality": "0..1",
+                                        "data-type": "boolean",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "mempage-size",
+                                        "type": "leaf",
+                                        "description": "Memory page allocation size. If a VM requires hugepages, it should choose LARGE or SIZE_2MB or SIZE_1GB. If the VM prefers hugepages it should chose PREFER_LARGE. LARGE : Require hugepages (either 2MB or 1GB) SMALL : Doesn't require hugepages SIZE_2MB : Requires 2MB hugepages SIZE_1GB : Requires 1GB hugepages PREFER_LARGE : Application perfers hugepages",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "LARGE": {
+                                                            "value": 0
+                                                       },
+                                                       "SMALL": {
+                                                            "value": 1
+                                                       },
+                                                       "SIZE_2MB": {
+                                                            "value": 2
+                                                       },
+                                                       "SIZE_1GB": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_LARGE": {
+                                                            "value": 4
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-pinning-policy",
+                                        "type": "leaf",
+                                        "description": "CPU pinning policy describes association between virtual CPUs in guest and the physical CPUs in the host. DEDICATED : Virtual CPUs are pinned to physical CPUs SHARED : Multiple VMs may share the same physical CPUs. ANY : Any policy is acceptable for the VM",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "DEDICATED": {
+                                                            "value": 0
+                                                       },
+                                                       "SHARED": {
+                                                            "value": 1
+                                                       },
+                                                       "ANY": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-thread-pinning-policy",
+                                        "type": "leaf",
+                                        "description": "CPU thread pinning policy describes how to place the guest CPUs when the host supports hyper threads: AVOID : Avoids placing a guest on a host with threads. SEPARATE: Places vCPUs on separate cores, and avoids placing two vCPUs on two threads of same core. ISOLATE : Places each vCPU on a different core, and places no vCPUs from a different guest on the same core. PREFER : Attempts to place vCPUs on threads of the same core.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "AVOID": {
+                                                            "value": 0
+                                                       },
+                                                       "SEPARATE": {
+                                                            "value": 1
+                                                       },
+                                                       "ISOLATE": {
+                                                            "value": 2
+                                                       },
+                                                       "PREFER": {
+                                                            "value": 3
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "pcie-device",
+                                        "type": "list",
+                                        "description": "List of pcie passthrough devices.",
+                                        "cardinality": "0..N",
+                                        "properties": [
+                                             {
+                                                  "name": "device-id",
+                                                  "type": "leaf",
+                                                  "description": "Device identifier.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "string",
+                                                  "properties": []
+                                             },
+                                             {
+                                                  "name": "count",
+                                                  "type": "leaf",
+                                                  "description": "Number of devices to attach to the VM.",
+                                                  "cardinality": "0..1",
+                                                  "data-type": "uint64",
+                                                  "properties": []
+                                             }
+                                        ],
+                                        "key": [
+                                             "device-id"
+                                        ]
+                                   },
+                                   {
+                                        "name": "numa-policy",
+                                        "type": "choice",
+                                        "cardinality": "0..1",
+                                        "properties": [
+                                             {
+                                                  "name": "numa-unware",
+                                                  "type": "case",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "numa-unware",
+                                                            "type": "leaf",
+                                                            "cardinality": "0..1",
+                                                            "data-type": "empty",
+                                                            "properties": []
+                                                       }
+                                                  ]
+                                             },
+                                             {
+                                                  "name": "numa-aware",
+                                                  "type": "case",
+                                                  "cardinality": "0..1",
+                                                  "properties": [
+                                                       {
+                                                            "name": "numa-node-policy",
+                                                            "type": "container",
+                                                            "description": "This policy defines numa topology of the guest. Specifically identifies if the guest should be run on a host with one numa node or multiple numa nodes. As an example a guest may want 8 vcpus and 4 GB of memory. But may want the vcpus and memory distributed across multiple numa nodes. The NUMA node 1 may run with 6 vcpus and 3GB, and NUMA node 2 may run with 2 vcpus and 1GB.",
+                                                            "cardinality": "0..1",
+                                                            "properties": [
+                                                                 {
+                                                                      "name": "node-cnt",
+                                                                      "type": "leaf",
+                                                                      "description": "The number of numa nodes to expose to the VM.",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": "uint16",
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "mem-policy",
+                                                                      "type": "leaf",
+                                                                      "description": "This policy specifies how the memory should be allocated in a multi-node scenario. STRICT : The memory must be allocated strictly from the memory attached to the NUMA node. PREFERRED : The memory should be allocated perferentially from the memory attached to the NUMA node",
+                                                                      "cardinality": "0..1",
+                                                                      "data-type": {
+                                                                           "enumeration": {
+                                                                                "enum": {
+                                                                                     "STRICT": {
+                                                                                          "value": 0
+                                                                                     },
+                                                                                     "PREFERRED": {
+                                                                                          "value": 1
+                                                                                     }
+                                                                                }
+                                                                           }
+                                                                      },
+                                                                      "properties": []
+                                                                 },
+                                                                 {
+                                                                      "name": "node",
+                                                                      "type": "list",
+                                                                      "cardinality": "0..N",
+                                                                      "properties": [
+                                                                           {
+                                                                                "name": "id",
+                                                                                "type": "leaf",
+                                                                                "description": "NUMA node identification. Typically it's 0 or 1",
+                                                                                "cardinality": "0..1",
+                                                                                "data-type": "uint64",
+                                                                                "properties": []
+                                                                           },
+                                                                           {
+                                                                                "name": "memory-mb",
+                                                                                "type": "leaf",
+                                                                                "description": "Memory size expressed in MB for this NUMA node.",
+                                                                                "cardinality": "0..1",
+                                                                                "data-type": "uint64",
+                                                                                "properties": []
+                                                                           },
+                                                                           {
+                                                                                "name": "vcpu",
+                                                                                "type": "leaf-list",
+                                                                                "description": "List of vcpus to allocate on this numa node.",
+                                                                                "cardinality": "0..N",
+                                                                                "data-type": "uint64",
+                                                                                "properties": []
+                                                                           },
+                                                                           {
+                                                                                "name": "om-numa-type",
+                                                                                "type": "choice",
+                                                                                "description": "Openmano Numa type selection",
+                                                                                "cardinality": "0..1",
+                                                                                "properties": [
+                                                                                     {
+                                                                                          "name": "cores",
+                                                                                          "type": "case",
+                                                                                          "cardinality": "0..1",
+                                                                                          "properties": [
+                                                                                               {
+                                                                                                    "name": "num-cores",
+                                                                                                    "type": "leaf",
+                                                                                                    "cardinality": "0..1",
+                                                                                                    "data-type": "uint8",
+                                                                                                    "properties": []
+                                                                                               }
+                                                                                          ]
+                                                                                     },
+                                                                                     {
+                                                                                          "name": "paired-threads",
+                                                                                          "type": "case",
+                                                                                          "cardinality": "0..1",
+                                                                                          "properties": [
+                                                                                               {
+                                                                                                    "name": "paired-threads",
+                                                                                                    "type": "container",
+                                                                                                    "cardinality": "0..1",
+                                                                                                    "properties": [
+                                                                                                         {
+                                                                                                              "name": "num-paired-threads",
+                                                                                                              "type": "leaf",
+                                                                                                              "cardinality": "0..1",
+                                                                                                              "data-type": "uint8",
+                                                                                                              "properties": []
+                                                                                                         },
+                                                                                                         {
+                                                                                                              "name": "paired-thread-ids",
+                                                                                                              "type": "list",
+                                                                                                              "description": "List of thread pairs to use in case of paired-thread numa",
+                                                                                                              "cardinality": "0..16",
+                                                                                                              "properties": [
+                                                                                                                   {
+                                                                                                                        "name": "thread-a",
+                                                                                                                        "type": "leaf",
+                                                                                                                        "cardinality": "0..1",
+                                                                                                                        "data-type": "uint8",
+                                                                                                                        "properties": []
+                                                                                                                   },
+                                                                                                                   {
+                                                                                                                        "name": "thread-b",
+                                                                                                                        "type": "leaf",
+                                                                                                                        "cardinality": "0..1",
+                                                                                                                        "data-type": "uint8",
+                                                                                                                        "properties": []
+                                                                                                                   }
+                                                                                                              ],
+                                                                                                              "key": [
+                                                                                                                   "thread-a"
+                                                                                                              ]
+                                                                                                         }
+                                                                                                    ]
+                                                                                               }
+                                                                                          ]
+                                                                                     },
+                                                                                     {
+                                                                                          "name": "threads",
+                                                                                          "type": "case",
+                                                                                          "cardinality": "0..1",
+                                                                                          "properties": [
+                                                                                               {
+                                                                                                    "name": "num-threads",
+                                                                                                    "type": "leaf",
+                                                                                                    "cardinality": "0..1",
+                                                                                                    "data-type": "uint8",
+                                                                                                    "properties": []
+                                                                                               }
+                                                                                          ]
+                                                                                     }
+                                                                                ]
+                                                                           }
+                                                                      ],
+                                                                      "key": [
+                                                                           "id"
+                                                                      ]
+                                                                 }
+                                                            ]
+                                                       }
+                                                  ]
+                                             }
+                                        ]
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "vswitch-epa",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "ovs-acceleration",
+                                        "type": "leaf",
+                                        "description": "Specifies Open vSwitch acceleration mode. MANDATORY: OVS acceleration is required PREFERRED: OVS acceleration is preferred",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "MANDATORY": {
+                                                            "value": 0
+                                                       },
+                                                       "PREFERRED": {
+                                                            "value": 1
+                                                       },
+                                                       "DISABLED": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "ovs-offload",
+                                        "type": "leaf",
+                                        "description": "Specifies Open vSwitch hardware offload mode. MANDATORY: OVS offload is required PREFERRED: OVS offload is preferred",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "MANDATORY": {
+                                                            "value": 0
+                                                       },
+                                                       "PREFERRED": {
+                                                            "value": 1
+                                                       },
+                                                       "DISABLED": {
+                                                            "value": 2
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "hypervisor-epa",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "type",
+                                        "type": "leaf",
+                                        "description": "Specifies the type of hypervisor. KVM: KVM XEN: XEN",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_KVM": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_KVM": {
+                                                            "value": 1
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "version",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "host-epa",
+                              "type": "container",
+                              "description": "Specifies the host level EPA attributes.",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "cpu-model",
+                                        "type": "leaf",
+                                        "description": "Host CPU model. Examples include: SandyBridge, IvyBridge",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_WESTMERE": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_WESTMERE": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_SANDYBRIDGE": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_SANDYBRIDGE": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_IVYBRIDGE": {
+                                                            "value": 4
+                                                       },
+                                                       "REQUIRE_IVYBRIDGE": {
+                                                            "value": 5
+                                                       },
+                                                       "PREFER_HASWELL": {
+                                                            "value": 6
+                                                       },
+                                                       "REQUIRE_HASWELL": {
+                                                            "value": 7
+                                                       },
+                                                       "PREFER_BROADWELL": {
+                                                            "value": 8
+                                                       },
+                                                       "REQUIRE_BROADWELL": {
+                                                            "value": 9
+                                                       },
+                                                       "PREFER_NEHALEM": {
+                                                            "value": 10
+                                                       },
+                                                       "REQUIRE_NEHALEM": {
+                                                            "value": 11
+                                                       },
+                                                       "PREFER_PENRYN": {
+                                                            "value": 12
+                                                       },
+                                                       "REQUIRE_PENRYN": {
+                                                            "value": 13
+                                                       },
+                                                       "PREFER_CONROE": {
+                                                            "value": 14
+                                                       },
+                                                       "REQUIRE_CONROE": {
+                                                            "value": 15
+                                                       },
+                                                       "PREFER_CORE2DUO": {
+                                                            "value": 16
+                                                       },
+                                                       "REQUIRE_CORE2DUO": {
+                                                            "value": 17
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-arch",
+                                        "type": "leaf",
+                                        "description": "Host CPU architecture.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_X86": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_X86": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_X86_64": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_X86_64": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_I686": {
+                                                            "value": 4
+                                                       },
+                                                       "REQUIRE_I686": {
+                                                            "value": 5
+                                                       },
+                                                       "PREFER_IA64": {
+                                                            "value": 6
+                                                       },
+                                                       "REQUIRE_IA64": {
+                                                            "value": 7
+                                                       },
+                                                       "PREFER_ARMV7": {
+                                                            "value": 8
+                                                       },
+                                                       "REQUIRE_ARMV7": {
+                                                            "value": 9
+                                                       },
+                                                       "PREFER_ARMV8": {
+                                                            "value": 10
+                                                       },
+                                                       "REQUIRE_ARMV8": {
+                                                            "value": 11
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-vendor",
+                                        "type": "leaf",
+                                        "description": "Host CPU Vendor.",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_INTEL": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_INTEL": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_AMD": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_AMD": {
+                                                            "value": 3
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-socket-count",
+                                        "type": "leaf",
+                                        "description": "Number of sockets on the host.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-core-count",
+                                        "type": "leaf",
+                                        "description": "Number of cores on the host.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-core-thread-count",
+                                        "type": "leaf",
+                                        "description": "Number of threads per cores on the host.",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "om-cpu-model-string",
+                                        "type": "leaf",
+                                        "description": "Openmano CPU model string",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "cpu-feature",
+                                        "type": "leaf-list",
+                                        "description": "Enumeration for CPU features. AES: CPU supports advanced instruction set for AES (Advanced Encryption Standard). CAT: Cache Allocation Technology (CAT) allows an Operating System, Hypervisor, or similar system management agent to specify the amount of L3 cache (currently the last-level cache in most server and client platforms) space an application can fill (as a hint to hardware functionality, certain features such as power management may override CAT settings). CMT: Cache Monitoring Technology (CMT) allows an Operating System, Hypervisor, or similar system management agent to determine the usage of cache based on applications running on the platform. The implementation is directed at L3 cache monitoring (currently the last-level cache in most server and client platforms). DDIO: Intel Data Direct I/O (DDIO) enables Ethernet server NICs and controllers talk directly to the processor cache without a detour via system memory. This enumeration specifies if the VM requires a DDIO capable host.",
+                                        "cardinality": "0..N",
+                                        "data-type": {
+                                             "enumeration": {
+                                                  "enum": {
+                                                       "PREFER_AES": {
+                                                            "value": 0
+                                                       },
+                                                       "REQUIRE_AES": {
+                                                            "value": 1
+                                                       },
+                                                       "PREFER_CAT": {
+                                                            "value": 2
+                                                       },
+                                                       "REQUIRE_CAT": {
+                                                            "value": 3
+                                                       },
+                                                       "PREFER_CMT": {
+                                                            "value": 4
+                                                       },
+                                                       "REQUIRE_CMT": {
+                                                            "value": 5
+                                                       },
+                                                       "PREFER_DDIO": {
+                                                            "value": 6
+                                                       },
+                                                       "REQUIRE_DDIO": {
+                                                            "value": 7
+                                                       },
+                                                       "REQUIRE_VME": {
+                                                            "value": 8
+                                                       },
+                                                       "PREFER_VME": {
+                                                            "value": 9
+                                                       },
+                                                       "REQUIRE_DE": {
+                                                            "value": 10
+                                                       },
+                                                       "PREFER_DE": {
+                                                            "value": 11
+                                                       },
+                                                       "REQUIRE_PSE": {
+                                                            "value": 12
+                                                       },
+                                                       "PREFER_PSE": {
+                                                            "value": 13
+                                                       },
+                                                       "REQUIRE_TSC": {
+                                                            "value": 14
+                                                       },
+                                                       "PREFER_TSC": {
+                                                            "value": 15
+                                                       },
+                                                       "REQUIRE_MSR": {
+                                                            "value": 16
+                                                       },
+                                                       "PREFER_MSR": {
+                                                            "value": 17
+                                                       },
+                                                       "REQUIRE_PAE": {
+                                                            "value": 18
+                                                       },
+                                                       "PREFER_PAE": {
+                                                            "value": 19
+                                                       },
+                                                       "REQUIRE_MCE": {
+                                                            "value": 20
+                                                       },
+                                                       "PREFER_MCE": {
+                                                            "value": 21
+                                                       },
+                                                       "REQUIRE_CX8": {
+                                                            "value": 22
+                                                       },
+                                                       "PREFER_CX8": {
+                                                            "value": 23
+                                                       },
+                                                       "REQUIRE_APIC": {
+                                                            "value": 24
+                                                       },
+                                                       "PREFER_APIC": {
+                                                            "value": 25
+                                                       },
+                                                       "REQUIRE_SEP": {
+                                                            "value": 26
+                                                       },
+                                                       "PREFER_SEP": {
+                                                            "value": 27
+                                                       },
+                                                       "REQUIRE_MTRR": {
+                                                            "value": 28
+                                                       },
+                                                       "PREFER_MTRR": {
+                                                            "value": 29
+                                                       },
+                                                       "REQUIRE_PGE": {
+                                                            "value": 30
+                                                       },
+                                                       "PREFER_PGE": {
+                                                            "value": 31
+                                                       },
+                                                       "REQUIRE_MCA": {
+                                                            "value": 32
+                                                       },
+                                                       "PREFER_MCA": {
+                                                            "value": 33
+                                                       },
+                                                       "REQUIRE_CMOV": {
+                                                            "value": 34
+                                                       },
+                                                       "PREFER_CMOV": {
+                                                            "value": 35
+                                                       },
+                                                       "REQUIRE_PAT": {
+                                                            "value": 36
+                                                       },
+                                                       "PREFER_PAT": {
+                                                            "value": 37
+                                                       },
+                                                       "REQUIRE_PSE36": {
+                                                            "value": 38
+                                                       },
+                                                       "PREFER_PSE36": {
+                                                            "value": 39
+                                                       },
+                                                       "REQUIRE_CLFLUSH": {
+                                                            "value": 40
+                                                       },
+                                                       "PREFER_CLFLUSH": {
+                                                            "value": 41
+                                                       },
+                                                       "REQUIRE_DTS": {
+                                                            "value": 42
+                                                       },
+                                                       "PREFER_DTS": {
+                                                            "value": 43
+                                                       },
+                                                       "REQUIRE_ACPI": {
+                                                            "value": 44
+                                                       },
+                                                       "PREFER_ACPI": {
+                                                            "value": 45
+                                                       },
+                                                       "REQUIRE_MMX": {
+                                                            "value": 46
+                                                       },
+                                                       "PREFER_MMX": {
+                                                            "value": 47
+                                                       },
+                                                       "REQUIRE_FXSR": {
+                                                            "value": 48
+                                                       },
+                                                       "PREFER_FXSR": {
+                                                            "value": 49
+                                                       },
+                                                       "REQUIRE_SSE": {
+                                                            "value": 50
+                                                       },
+                                                       "PREFER_SSE": {
+                                                            "value": 51
+                                                       },
+                                                       "REQUIRE_SSE2": {
+                                                            "value": 52
+                                                       },
+                                                       "PREFER_SSE2": {
+                                                            "value": 53
+                                                       },
+                                                       "REQUIRE_SS": {
+                                                            "value": 54
+                                                       },
+                                                       "PREFER_SS": {
+                                                            "value": 55
+                                                       },
+                                                       "REQUIRE_HT": {
+                                                            "value": 56
+                                                       },
+                                                       "PREFER_HT": {
+                                                            "value": 57
+                                                       },
+                                                       "REQUIRE_TM": {
+                                                            "value": 58
+                                                       },
+                                                       "PREFER_TM": {
+                                                            "value": 59
+                                                       },
+                                                       "REQUIRE_IA64": {
+                                                            "value": 60
+                                                       },
+                                                       "PREFER_IA64": {
+                                                            "value": 61
+                                                       },
+                                                       "REQUIRE_PBE": {
+                                                            "value": 62
+                                                       },
+                                                       "PREFER_PBE": {
+                                                            "value": 63
+                                                       },
+                                                       "REQUIRE_RDTSCP": {
+                                                            "value": 64
+                                                       },
+                                                       "PREFER_RDTSCP": {
+                                                            "value": 65
+                                                       },
+                                                       "REQUIRE_PNI": {
+                                                            "value": 66
+                                                       },
+                                                       "PREFER_PNI": {
+                                                            "value": 67
+                                                       },
+                                                       "REQUIRE_PCLMULQDQ": {
+                                                            "value": 68
+                                                       },
+                                                       "PREFER_PCLMULQDQ": {
+                                                            "value": 69
+                                                       },
+                                                       "REQUIRE_DTES64": {
+                                                            "value": 70
+                                                       },
+                                                       "PREFER_DTES64": {
+                                                            "value": 71
+                                                       },
+                                                       "REQUIRE_MONITOR": {
+                                                            "value": 72
+                                                       },
+                                                       "PREFER_MONITOR": {
+                                                            "value": 73
+                                                       },
+                                                       "REQUIRE_DS_CPL": {
+                                                            "value": 74
+                                                       },
+                                                       "PREFER_DS_CPL": {
+                                                            "value": 75
+                                                       },
+                                                       "REQUIRE_VMX": {
+                                                            "value": 76
+                                                       },
+                                                       "PREFER_VMX": {
+                                                            "value": 77
+                                                       },
+                                                       "REQUIRE_SMX": {
+                                                            "value": 78
+                                                       },
+                                                       "PREFER_SMX": {
+                                                            "value": 79
+                                                       },
+                                                       "REQUIRE_EST": {
+                                                            "value": 80
+                                                       },
+                                                       "PREFER_EST": {
+                                                            "value": 81
+                                                       },
+                                                       "REQUIRE_TM2": {
+                                                            "value": 82
+                                                       },
+                                                       "PREFER_TM2": {
+                                                            "value": 83
+                                                       },
+                                                       "REQUIRE_SSSE3": {
+                                                            "value": 84
+                                                       },
+                                                       "PREFER_SSSE3": {
+                                                            "value": 85
+                                                       },
+                                                       "REQUIRE_CID": {
+                                                            "value": 86
+                                                       },
+                                                       "PREFER_CID": {
+                                                            "value": 87
+                                                       },
+                                                       "REQUIRE_FMA": {
+                                                            "value": 88
+                                                       },
+                                                       "PREFER_FMA": {
+                                                            "value": 89
+                                                       },
+                                                       "REQUIRE_CX16": {
+                                                            "value": 90
+                                                       },
+                                                       "PREFER_CX16": {
+                                                            "value": 91
+                                                       },
+                                                       "REQUIRE_XTPR": {
+                                                            "value": 92
+                                                       },
+                                                       "PREFER_XTPR": {
+                                                            "value": 93
+                                                       },
+                                                       "REQUIRE_PDCM": {
+                                                            "value": 94
+                                                       },
+                                                       "PREFER_PDCM": {
+                                                            "value": 95
+                                                       },
+                                                       "REQUIRE_PCID": {
+                                                            "value": 96
+                                                       },
+                                                       "PREFER_PCID": {
+                                                            "value": 97
+                                                       },
+                                                       "REQUIRE_DCA": {
+                                                            "value": 98
+                                                       },
+                                                       "PREFER_DCA": {
+                                                            "value": 99
+                                                       },
+                                                       "REQUIRE_SSE4_1": {
+                                                            "value": 100
+                                                       },
+                                                       "PREFER_SSE4_1": {
+                                                            "value": 101
+                                                       },
+                                                       "REQUIRE_SSE4_2": {
+                                                            "value": 102
+                                                       },
+                                                       "PREFER_SSE4_2": {
+                                                            "value": 103
+                                                       },
+                                                       "REQUIRE_X2APIC": {
+                                                            "value": 104
+                                                       },
+                                                       "PREFER_X2APIC": {
+                                                            "value": 105
+                                                       },
+                                                       "REQUIRE_MOVBE": {
+                                                            "value": 106
+                                                       },
+                                                       "PREFER_MOVBE": {
+                                                            "value": 107
+                                                       },
+                                                       "REQUIRE_POPCNT": {
+                                                            "value": 108
+                                                       },
+                                                       "PREFER_POPCNT": {
+                                                            "value": 109
+                                                       },
+                                                       "REQUIRE_TSC_DEADLINE_TIMER": {
+                                                            "value": 110
+                                                       },
+                                                       "PREFER_TSC_DEADLINE_TIMER": {
+                                                            "value": 111
+                                                       },
+                                                       "REQUIRE_XSAVE": {
+                                                            "value": 112
+                                                       },
+                                                       "PREFER_XSAVE": {
+                                                            "value": 113
+                                                       },
+                                                       "REQUIRE_AVX": {
+                                                            "value": 114
+                                                       },
+                                                       "PREFER_AVX": {
+                                                            "value": 115
+                                                       },
+                                                       "REQUIRE_F16C": {
+                                                            "value": 116
+                                                       },
+                                                       "PREFER_F16C": {
+                                                            "value": 117
+                                                       },
+                                                       "REQUIRE_RDRAND": {
+                                                            "value": 118
+                                                       },
+                                                       "PREFER_RDRAND": {
+                                                            "value": 119
+                                                       },
+                                                       "REQUIRE_FSGSBASE": {
+                                                            "value": 120
+                                                       },
+                                                       "PREFER_FSGSBASE": {
+                                                            "value": 121
+                                                       },
+                                                       "REQUIRE_BMI1": {
+                                                            "value": 122
+                                                       },
+                                                       "PREFER_BMI1": {
+                                                            "value": 123
+                                                       },
+                                                       "REQUIRE_HLE": {
+                                                            "value": 124
+                                                       },
+                                                       "PREFER_HLE": {
+                                                            "value": 125
+                                                       },
+                                                       "REQUIRE_AVX2": {
+                                                            "value": 126
+                                                       },
+                                                       "PREFER_AVX2": {
+                                                            "value": 127
+                                                       },
+                                                       "REQUIRE_SMEP": {
+                                                            "value": 128
+                                                       },
+                                                       "PREFER_SMEP": {
+                                                            "value": 129
+                                                       },
+                                                       "REQUIRE_BMI2": {
+                                                            "value": 130
+                                                       },
+                                                       "PREFER_BMI2": {
+                                                            "value": 131
+                                                       },
+                                                       "REQUIRE_ERMS": {
+                                                            "value": 132
+                                                       },
+                                                       "PREFER_ERMS": {
+                                                            "value": 133
+                                                       },
+                                                       "REQUIRE_INVPCID": {
+                                                            "value": 134
+                                                       },
+                                                       "PREFER_INVPCID": {
+                                                            "value": 135
+                                                       },
+                                                       "REQUIRE_RTM": {
+                                                            "value": 136
+                                                       },
+                                                       "PREFER_RTM": {
+                                                            "value": 137
+                                                       },
+                                                       "REQUIRE_MPX": {
+                                                            "value": 138
+                                                       },
+                                                       "PREFER_MPX": {
+                                                            "value": 139
+                                                       },
+                                                       "REQUIRE_RDSEED": {
+                                                            "value": 140
+                                                       },
+                                                       "PREFER_RDSEED": {
+                                                            "value": 141
+                                                       },
+                                                       "REQUIRE_ADX": {
+                                                            "value": 142
+                                                       },
+                                                       "PREFER_ADX": {
+                                                            "value": 143
+                                                       },
+                                                       "REQUIRE_SMAP": {
+                                                            "value": 144
+                                                       },
+                                                       "PREFER_SMAP": {
+                                                            "value": 145
+                                                       }
+                                                  }
+                                             }
+                                        },
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "om-cpu-feature",
+                                        "type": "leaf-list",
+                                        "description": "Openmano CPU features",
+                                        "cardinality": "0..N",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               },
+               {
+                    "name": "vdu-dependency",
+                    "type": "list",
+                    "description": "List of VDU dependencies.",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "vdu-source-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../vdu/id"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "vdu-depends-on-ref",
+                              "type": "leaf",
+                              "description": "Reference to the VDU that source VDU depends.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../vdu/id"
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "vdu-source-ref"
+                    ]
+               },
+               {
+                    "name": "placement-groups",
+                    "type": "list",
+                    "description": "List of placement groups at VNF level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "member-vdus",
+                              "type": "list",
+                              "description": "List of VDUs that are part of this placement group",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "member-vdu-ref",
+                                        "type": "leaf",
+                                        "cardinality": "0..1",
+                                        "data-type": {
+                                             "leafref": {
+                                                  "path": "../../../vdu/id"
+                                             }
+                                        },
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "member-vdu-ref"
+                              ]
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "description": "Place group construct to define the compute resource placement strategy in cloud environment",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "requirement",
+                              "type": "leaf",
+                              "description": "This is free text space used to describe the intent/rationale behind this placement group. This is for human consumption only",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "strategy",
+                              "type": "leaf",
+                              "description": "Strategy associated with this placement group Following values are possible - COLOCATION: Colocation strategy imply intent to share the physical infrastructure (hypervisor/network) among all members of this group. - ISOLATION: Isolation strategy imply intent to not share the physical infrastructure (hypervisor/network) among the members of this group. ",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "COLOCATION": {
+                                                  "value": 0
+                                             },
+                                             "ISOLATION": {
+                                                  "value": 1
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         }
+                    ],
+                    "key": [
+                         "name"
+                    ]
+               },
+               {
+                    "name": "http-endpoint",
+                    "type": "list",
+                    "description": "List of http endpoints to be used by monitoring params",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "path",
+                              "type": "leaf",
+                              "description": "The HTTP path on the management server",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "https",
+                              "type": "leaf",
+                              "description": "Pick HTTPS instead of HTTP , Default is false",
+                              "cardinality": "0..1",
+                              "data-type": "boolean",
+                              "properties": []
+                         },
+                         {
+                              "name": "port",
+                              "type": "leaf",
+                              "description": "The port-number type represents a 16-bit port number of an Internet transport-layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "uint16": {
+                                        "range": "0..65535"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "username",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth username",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "password",
+                              "type": "leaf",
+                              "description": "The HTTP basic auth password",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "polling_interval_secs",
+                              "type": "leaf",
+                              "description": "The HTTP polling interval in seconds",
+                              "cardinality": "0..1",
+                              "data-type": "uint8",
+                              "properties": []
+                         },
+                         {
+                              "name": "method",
+                              "type": "leaf",
+                              "description": "Type of HTTP operation",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "POST": {
+                                                  "value": 0
+                                             },
+                                             "PUT": {
+                                                  "value": 1
+                                             },
+                                             "GET": {
+                                                  "value": 2
+                                             },
+                                             "DELETE": {
+                                                  "value": 3
+                                             },
+                                             "OPTIONS": {
+                                                  "value": 4
+                                             },
+                                             "PATCH": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "headers",
+                              "type": "list",
+                              "description": "Custom HTTP headers to put on HTTP request",
+                              "cardinality": "0..N",
+                              "properties": [
+                                   {
+                                        "name": "key",
+                                        "type": "leaf",
+                                        "description": "HTTP header key",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "value",
+                                        "type": "leaf",
+                                        "description": "HTTP header value",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ],
+                              "key": [
+                                   "key"
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "path"
+                    ]
+               },
+               {
+                    "name": "monitoring-param",
+                    "type": "list",
+                    "description": "List of monitoring parameters at the NS level",
+                    "cardinality": "0..N",
+                    "properties": [
+                         {
+                              "name": "id",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "name",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "http-endpoint-ref",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "leafref": {
+                                        "path": "../../http-endpoint/path"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-method",
+                              "type": "leaf",
+                              "description": "The method to extract a value from a JSON response NAMEKEY - Use the name as the key for a non-nested value. JSONPATH - Use jsonpath-rw implemenation to extract a value. OBJECTPATH - Use objectpath implemenation to extract a value.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "NAMEKEY": {
+                                                  "value": 0
+                                             },
+                                             "JSONPATH": {
+                                                  "value": 1
+                                             },
+                                             "OBJECTPATH": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "description",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "group-tag",
+                              "type": "leaf",
+                              "description": "A simple tag to group monitoring parameters",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-type",
+                              "type": "leaf",
+                              "description": "The type of the parameter value",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "INT": {
+                                                  "value": 0
+                                             },
+                                             "DECIMAL": {
+                                                  "value": 1
+                                             },
+                                             "STRING": {
+                                                  "value": 2
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-integer",
+                              "type": "leaf",
+                              "description": "Current value for an integer parameter",
+                              "cardinality": "0..1",
+                              "data-type": "int64",
+                              "properties": []
+                         },
+                         {
+                              "name": "value-decimal",
+                              "type": "leaf",
+                              "description": "Current value for a decimal parameter",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "decimal64": {
+                                        "fraction-digits": "4"
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "value-string",
+                              "type": "leaf",
+                              "description": "Current value for a string parameter",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "widget-type",
+                              "type": "leaf",
+                              "description": "Type of the widget, typically used by the UI.",
+                              "cardinality": "0..1",
+                              "data-type": {
+                                   "enumeration": {
+                                        "enum": {
+                                             "HISTOGRAM": {
+                                                  "value": 0
+                                             },
+                                             "BAR": {
+                                                  "value": 1
+                                             },
+                                             "GAUGE": {
+                                                  "value": 2
+                                             },
+                                             "SLIDER": {
+                                                  "value": 3
+                                             },
+                                             "COUNTER": {
+                                                  "value": 4
+                                             },
+                                             "TEXTBOX": {
+                                                  "value": 5
+                                             }
+                                        }
+                                   }
+                              },
+                              "properties": []
+                         },
+                         {
+                              "name": "units",
+                              "type": "leaf",
+                              "cardinality": "0..1",
+                              "data-type": "string",
+                              "properties": []
+                         },
+                         {
+                              "name": "json-query-params",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "json-path",
+                                        "type": "leaf",
+                                        "description": "The jsonpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "object-path",
+                                        "type": "leaf",
+                                        "description": "The objectpath to use to extract value from JSON structure",
+                                        "cardinality": "0..1",
+                                        "data-type": "string",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "numeric-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-value",
+                                        "type": "leaf",
+                                        "description": "Minimum value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-value",
+                                        "type": "leaf",
+                                        "description": "Maxium value for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint64",
+                                        "properties": []
+                                   }
+                              ]
+                         },
+                         {
+                              "name": "text-constraints",
+                              "type": "container",
+                              "cardinality": "0..1",
+                              "properties": [
+                                   {
+                                        "name": "min-length",
+                                        "type": "leaf",
+                                        "description": "Minimum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   },
+                                   {
+                                        "name": "max-length",
+                                        "type": "leaf",
+                                        "description": "Maximum string length for the parameter",
+                                        "cardinality": "0..1",
+                                        "data-type": "uint8",
+                                        "properties": []
+                                   }
+                              ]
+                         }
+                    ],
+                    "key": [
+                         "id"
+                    ]
+               }
+          ],
+          "key": [
+               "id"
+          ]
+     }
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaFactory.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaFactory.js
new file mode 100644 (file)
index 0000000..258b894
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+ * Created by onvelocity on 1/27/16.
+ *
+ * This class provides methods to get the metadata about descriptor models.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import utils from './../utils'
+import DescriptorModelMetaProperty from './DescriptorModelMetaProperty'
+import CommonUtils from 'utils/utils';
+const assign = Object.assign;
+
+const exportInnerTypesMap = {
+       'constituent-vnfd': 'nsd.constituent-vnfd',
+       'vdu': 'vnfd.vdu'
+};
+
+function getPathForType(type) {
+       if (exportInnerTypesMap[type]) {
+               return exportInnerTypesMap[type];
+       }
+       return type;
+}
+
+let modelMetaByPropertyNameMap = [];
+
+let cachedDescriptorModelMetaRequest = null;
+
+export default {
+       init() {
+               if (!cachedDescriptorModelMetaRequest) {
+                       cachedDescriptorModelMetaRequest = new Promise(function(resolve, reject) {
+                               CommonUtils.getDescriptorModelMeta().then(function(data) {
+                                       let DescriptorModelMetaJSON = data;
+                                       modelMetaByPropertyNameMap = Object.keys(DescriptorModelMetaJSON).reduce((map, key) => {
+                                               function mapProperties(parentMap, parentObj) {
+                                                       parentMap[':meta'] = parentObj;
+                                                       const properties = parentObj && parentObj.properties ? parentObj.properties : [];
+                                                       properties.forEach(p => {
+                                                               parentMap[p.name] = mapProperties({}, assign(p, {':qualified-type': parentObj[':qualified-type'] + '.' + p.name}));
+                                                               return map;
+                                                       }, parentMap);
+                                                       return parentMap;
+                                               }
+                                               map[key] = mapProperties({}, assign(DescriptorModelMetaJSON[key], {':qualified-type': key}));
+                                               return map;
+                                       }, {});
+
+                                       (() => {
+                                               // initialize the UI centric properties that CONFD could care less about
+                                               utils.assignPathValue(modelMetaByPropertyNameMap, 'nsd.meta.:meta.preserve-line-breaks', true);
+                                               utils.assignPathValue(modelMetaByPropertyNameMap, 'vnfd.meta.:meta.preserve-line-breaks', true);
+                                               utils.assignPathValue(modelMetaByPropertyNameMap, 'vnfd.vdu.cloud-init.:meta.preserve-line-breaks', true);
+                                               utils.assignPathValue(modelMetaByPropertyNameMap, 'nsd.constituent-vnfd.vnf-configuration.config-template.:meta.preserve-line-breaks', true);
+                                       })();
+                                       resolve();
+                               }, function(error) {
+                                       cachedDescriptorModelMetaRequest = null;
+                               })
+                       })
+               }
+
+               return cachedDescriptorModelMetaRequest;
+       },
+       createModelInstanceForType(typeOrPath) {
+               const modelMeta = this.getModelMetaForType(typeOrPath);
+               return DescriptorModelMetaProperty.createModelInstance(modelMeta);
+       },
+       getModelMetaForType(typeOrPath, filterProperties = () => true) {
+               // resolve paths like 'nsd' or 'vnfd.vdu' or 'nsd.constituent-vnfd'
+               const found = utils.resolvePath(modelMetaByPropertyNameMap, getPathForType(typeOrPath));
+               if (found) {
+                       const uiState = _.cloneDeep(found[':meta']);
+                       uiState.properties = uiState.properties.filter(filterProperties);
+                       return uiState;
+               }
+               console.warn('no model uiState found for type', typeOrPath);
+       },
+       getModelFieldNamesForType(typeOrPath) {
+               // resolve paths like 'nsd' or 'vnfd.vdu' or 'nsd.constituent-vnfd'
+               const found = utils.resolvePath(modelMetaByPropertyNameMap, getPathForType(typeOrPath));
+               if (found) {
+                       return found[':meta'].properties.map(p => p.name);
+               }
+               console.warn('no model uiState found for type', typeOrPath);
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaProperty.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaProperty.js
new file mode 100644 (file)
index 0000000..efd06c0
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 1/27/16.
+ *
+ * This class provides utility methods for interrogating an instance of model uiState object.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import guid from './../guid'
+import changeCase from 'change-case'
+import InstanceCounter from './../InstanceCounter'
+import DescriptorModelFields from './DescriptorModelFields'
+import DescriptorTemplateFactory from './DescriptorTemplateFactory'
+
+export default {
+       isLeaf(property = {}) {
+               return /leaf|choice/.test(property.type);
+       },
+       isList(property = {}) {
+               return /list|leaf-list/.test(property.type);
+       },
+       isLeafList(property = {}) {
+               return property.type === 'leaf-list';
+       },
+       isArray(property = {}) {
+               // give '1' or '0..N' or '0..1' or '0..5' determine if represents an array
+               // '0..1' is not an array
+               // '0..2' is an array
+               // '0..N' is an array
+               const cardinality = String(property.cardinality).toUpperCase();
+               const pos = cardinality.lastIndexOf('.') + 1;
+               const val = cardinality.substr(pos);
+               return val === 'N' || parseInt(val, 10) > 1;
+       },
+       isEnumeration(property = {}) {
+               const type = property['data-type'] || {};
+               return type.hasOwnProperty('enumeration');
+       },
+       isRequired(property = {}) {
+               return /^1/.test(property.cardinality);
+       },
+       isObject(property = {}) {
+               return !/^(leaf|leaf-list)$/.test(property.type);
+       },
+       isSimpleList(property = {}) {
+               return _.contains(DescriptorModelFields.simpleList, property.name);
+       },
+       isPrimativeDataType(property = {}) {
+               const Property = this;
+               return /string|int/.test(property['data-type']) || Property.isEnumeration(property) || Property.isGuid(property);
+       },
+       defaultValue(property = {}) {
+               if (property.defaultValue) {
+                       return property.defaultValue;
+               }
+               if (this.isObject(property)) {
+                       return {};
+               }
+               return '';
+       },
+       getContainerMethod(property, container, methodName) {
+               const name = changeCase.camel(methodName + '-' + property.name);
+               if (typeof container[name] === 'function') {
+                       return container[name].bind(container);
+               }
+       },
+       getContainerCreateMethod(property, container) {
+               const name = changeCase.camel('create-' + property.name);
+               if (typeof container[name] === 'function') {
+                       return container[name].bind(container);
+               }
+       },
+       containerHasCreateMethod(container, property = {}) {
+               const find = changeCase.camel('create-' + property.name);
+               return typeof container[find] === 'function';
+       },
+       getEnumeration(property = {}, value) {
+               const enumeration = property['data-type'].enumeration.enum;
+               if (typeof enumeration === 'string') {
+                       return [{name: enumeration, value: enumeration, isSelected: String(value) === enumeration}];
+               }
+               return Object.keys(enumeration).map(enumName => {
+                       let enumValue = enumName;
+                       // warn we only support named enums and systematically ignore enum values
+                       //const enumObj = enumeration[enumName];
+                       //if (enumObj) {
+                       //      enumValue = enumObj.value || enumName;
+                       //}
+                       return {name: enumName, value: enumValue, isSelected: String(enumValue) === String(value)};
+               });
+       },
+       isGuid(property = {}) {
+               const type = property['data-type'];
+               if (typeof type === 'object' && type.leafref && type.leafref.path) {
+                       return /\bid$/.test(type.leafref.path);
+               }
+               return /uuid/.test(property['data-type']);
+       },
+       createModelInstance(property) {
+               const Property = this;
+               const defaultValue = Property.defaultValue.bind(this);
+               function createModel(uiState, parentMeta) {
+                       const model = {};
+                       if (Property.isLeaf(uiState)) {
+                               if (uiState.name === 'name') {
+                                       return changeCase.param(parentMeta.name) + '-' + InstanceCounter.count(parentMeta[':qualified-type']);
+                               }
+                               if (_.isArray(parentMeta.key) && _.contains(parentMeta.key, uiState.name)) {
+                                       if (/uuid/.test(uiState['data-type'])) {
+                                               return guid();
+                                       }
+                                       if (uiState['data-type'] === 'string') {
+                                               const prefix = uiState.name.replace('id', '');
+                                               return  (prefix ? changeCase.param(prefix) + '-' : '') + guid(5);
+                                       }
+                                       if (/int/.test(uiState['data-type'])) {
+                                               return InstanceCounter.count(uiState[':qualified-type']);
+                                       }
+                               }
+                               return defaultValue(uiState);
+                       } else if (Property.isList(uiState)) {
+                               return [];
+                       } else {
+                               uiState.properties.forEach(p => {
+                                       model[p.name] = createModel(p, uiState);
+                               });
+                       }
+                       return model;
+               }
+               if (property) {
+                       if (Property.isPrimativeDataType(property)) {
+                               return defaultValue(property);
+                       }
+                       if (property.type === 'leaf') {
+                               return defaultValue(property);
+                       }
+                       if (/list/.test(property.type)) {
+                               property.type = 'container';
+                       }
+                       const modelInstance = createModel(property, property);
+                       modelInstance.uiState = {type: property.name};
+                       const modelFragment = DescriptorTemplateFactory.createModelForType(property[':qualified-type'] || property.name) || {};
+                       Object.assign(modelInstance, modelFragment);
+                       return modelInstance;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js
new file mode 100644 (file)
index 0000000..7581ed5
--- /dev/null
@@ -0,0 +1,190 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/20/15.
+ */
+
+import _ from 'lodash'
+import utils from './../utils'
+import DescriptorModelFields from './DescriptorModelFields'
+import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
+
+let nsdFields = null;
+let vldFields = null;
+let vnfdFields = null;
+let cvnfdFields = null;
+
+
+
+
+/**
+ * Serialize DescriptorModel JSON into CONFD JSON. Also, cleans up the data as needed.
+ *
+ * @type {{serialize: (function(*=)), ':clean': (function(*=)), nsd: {serialize: (function(*=))}, vld: {serialize: (function(*=))}, vnfd-connection-point-ref: {serialize: (function(*=))}, constituent-vnfd: {serialize: (function(*=))}, vnfd: {serialize: (function(*=))}, vdu: {serialize: (function(*=))}}}
+ */
+const DescriptorModelSerializer = {
+       serialize(model) {
+               const type = model.uiState && model.uiState.type;
+               const serializer = this[type];
+               if (serializer) {
+                       model = serializer.serialize(model);
+                       this[':clean'](model);
+                       return model;
+               }
+               return false;
+       },
+       ':clean'(model) {
+               // remove uiState from all elements accept nsd and vnfd
+               // remove empty / blank value fields
+               function clean(m) {
+                       Object.keys(m).forEach(k => {
+                               const isEmptyObject = typeof m[k] === 'object' && _.isEmpty(m[k]);
+                               if (typeof m[k] === 'undefined' || isEmptyObject || m[k] === '') {
+                                       delete m[k];
+                               }
+                               const isMetaAllowed = /^nsd|vnfd$/.test(m.uiState && m.uiState.type);
+                               if (k === 'uiState') {
+                                       if (isMetaAllowed) {
+                                               // remove any transient ui state properties
+                                               const uiState = _.pick(m.uiState, DescriptorModelFields.meta);
+                                               if (!_.isEmpty(uiState)) {
+                                                       // uiState field must be a string
+                                                       m['meta'] = JSON.stringify(uiState);
+                                               }
+                                       }
+                                       delete m[k];
+                               }
+                               if (typeof m[k] === 'object') {
+                                       clean(m[k]);
+                               }
+                       });
+               }
+               clean(model);
+               return model;
+       },
+       nsd: {
+               serialize(nsdModel) {
+                       if(!nsdFields) nsdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd').concat('uiState');
+                       const confd = _.pick(nsdModel, nsdFields);
+
+                       // vnfd is defined in the ETSI etsi_gs reference manual but RIFT does not use it
+                       delete confd.vnfd;
+
+                       // map the vnfd instances into the CONFD constituent-vnfd ref instances
+                       confd['constituent-vnfd'] = confd['constituent-vnfd'].map((d, index) => {
+
+                               const constituentVNFD = {
+                                       'member-vnf-index': d['member-vnf-index'],
+                                       'vnfd-id-ref': d['vnfd-id-ref']
+                               };
+
+                               if (d['vnf-configuration']) {
+                                       const vnfConfig = _.cloneDeep(d['vnf-configuration']);
+                                       const configType = vnfConfig['config-type'] || 'none';
+                                       // make sure we send the correct values based on config type
+                                       if (configType === 'none') {
+                                               constituentVNFD['vnf-configuration'] = {'config-type': 'none'};
+                                               const configPriority = utils.resolvePath(vnfConfig, 'input-params.config-priority');
+                                               const configPriorityValue = _.isNumber(configPriority) ? configPriority : d.uiState['member-vnf-index'];
+                                               utils.assignPathValue(constituentVNFD['vnf-configuration'], 'input-params.config-priority', configPriorityValue);
+                                       } else {
+                                               // remove any unused configuration options
+                                               ['netconf', 'rest', 'script', 'juju'].forEach(type => {
+                                                       if (configType !== type) {
+                                                               delete vnfConfig[type];
+                                                       }
+                                               });
+                                               constituentVNFD['vnf-configuration'] = vnfConfig;
+                                       }
+                               }
+
+                               if (d.hasOwnProperty('start-by-default')) {
+                                       constituentVNFD['start-by-default'] = d['start-by-default'];
+                               }
+
+                               return constituentVNFD;
+
+                       });
+
+                       // serialize the VLD instances
+                       confd.vld = confd.vld.map(d => {
+                               return DescriptorModelSerializer.serialize(d);
+                       });
+
+                       return confd;
+
+               }
+       },
+       vld: {
+               serialize(vldModel) {
+                       if(!vldFields) vldFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.vld');
+                       const confd = _.pick(vldModel, vldFields);
+                       const property = 'vnfd-connection-point-ref';
+
+                       // TODO: There is a bug in RIFT-REST that is not accepting empty
+                       // strings for string properties.
+                       // once that is fixed, remove this piece of code.
+                       // fix-start
+                       for (var key in confd) {
+                               if (confd.hasOwnProperty(key) && confd[key] === '') {
+                                       delete confd[key];
+                               }
+                       }
+
+                       const deepProperty = 'provider-network';
+                       for (var key in confd[deepProperty]) {
+                               if (confd[deepProperty].hasOwnProperty(key) && confd[deepProperty][key] === '') {
+                                       delete confd[deepProperty][key];
+                               }
+                       }
+                       // fix-end
+
+
+                       confd[property] = confd[property].map(d => DescriptorModelSerializer[property].serialize(d));
+                       return confd;
+               }
+       },
+       'vnfd-connection-point-ref': {
+               serialize(ref) {
+                       return _.pick(ref, ['member-vnf-index-ref', 'vnfd-id-ref', 'vnfd-connection-point-ref']);
+               }
+       },
+       'constituent-vnfd': {
+               serialize(cvnfdModel) {
+                       if(!cvnfdFields) cvnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.constituent-vnfd');
+                       return _.pick(cvnfdModel, cvnfdFields);
+               }
+       },
+       vnfd: {
+               serialize(vnfdModel) {
+                       if(!vnfdFields) vnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('vnfd').concat('uiState');
+                       const confd = _.pick(vnfdModel, vnfdFields);
+                       confd.vdu = confd.vdu.map(d => DescriptorModelSerializer.serialize(d));
+                       return confd;
+               }
+       },
+       vdu: {
+               serialize(vduModel) {
+                       const confd = _.omit(vduModel, ['uiState']);
+                       return confd;
+               }
+       }
+};
+
+export default DescriptorModelSerializer;
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplateFactory.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplateFactory.js
new file mode 100644 (file)
index 0000000..28e7480
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 1/27/16.
+ *
+ * This class creates the initial descriptor model JSON objects.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import DescriptorTemplates from './DescriptorTemplates'
+import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
+
+const keys = Object.keys;
+
+function resolveInitHandlers(model) {
+       function init(m) {
+               keys(m).map(key => {
+                       const value = m[key];
+                       if (_.isFunction(value)) {
+                               m[key] = value(m, key, model);
+                       }
+                       if (_.isArray(value)) {
+                               value.forEach(v => init(v));
+                       }
+                       if (_.isObject(value)) {
+                               init(value);
+                       }
+               });
+               return m;
+       }
+       return init(model);
+}
+
+export default {
+       createModelForType(type) {
+               const template = DescriptorTemplates[type];
+               if (template) {
+                       const model = _.cloneDeep(template);
+                       return resolveInitHandlers(model);
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js
new file mode 100644 (file)
index 0000000..89e0a87
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/6/15.
+ *
+ * Model fragments used to construct partially completed models.
+ */
+
+'use strict';
+
+import guid from './../guid'
+import InstanceCounter from './../InstanceCounter'
+
+export default {
+       'vnfd': {
+               'id': '5b9af24e-2c8f-4792-9d6e-ff9eabb97f15',
+               'name': 'vnfd-1',
+               'short-name': 'vnfd-1',
+               'description': 'A simple VNF descriptor w/ one VDU',
+               'version': '1.0',
+               'connection-point': [
+                       {
+                               'name': 'cp1',
+                               'type': 'VPORT'
+                       }
+               ],
+               'vdu': [
+                       {
+                               'id': 'abd6831e-f811-4580-9aad-1de9c6424180',
+                               'name': 'vdu-1',
+                               'vm-flavor': {
+                                       'vcpu-count': 4,
+                                       'memory-mb': 16384,
+                                       'storage-gb': 16
+                               },
+                               'image': '',
+                               'external-interface': [
+                                       {
+                                               'name': 'eth0',
+                                               'vnfd-connection-point-ref': 'cp1',
+                                               'virtual-interface': {
+                                                       'type': 'VIRTIO'
+                                               }
+                                       }
+                               ]
+                       }
+               ]
+       },
+       'vnfd.internal-vld': {
+               'id': () => guid(),
+               'name': () => 'vld-' + InstanceCounter.count('new.vnfd.internal-vld'),
+               'description': 'Virtual link for internal fabric',
+               'type': 'ELAN'
+       }
+};
diff --git a/skyquake/plugins/composer/src/src/libraries/model/IconFactory.js b/skyquake/plugins/composer/src/src/libraries/model/IconFactory.js
new file mode 100644 (file)
index 0000000..6815fcb
--- /dev/null
@@ -0,0 +1,58 @@
+class IconFactory {
+
+    static getIconForType(type) {
+        const icon = IconFactory.types[type];
+        if (icon) {
+            return icon;
+        }
+        return IconFactory.types.common;
+    }
+
+    static getUrlForType(type, isBlack) {
+        const file = (IconFactory.types[type] || {file: 'default-icon-white.svg'}).file;
+        if (isBlack) {
+            return 'images/' + file.replace(/-white\.svg$/, '.svg');
+        }
+        return 'images/' + file;
+    }
+
+    static get types() {
+        return {
+            vdu: {
+                width: 350,
+                translate: '0, 8',
+                file: 'default-icon-white.svg',
+                d: `M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z`},
+            vnfd: {
+                width: 350,
+                file: 'default-icon-white.svg',
+                d: `M241.72,51.26c-92.14,0-166.83,75.48-166.83,168.59s74.69,168.59,166.83,168.59S408.55,313,408.55,219.85,333.86,51.26,241.72,51.26Z`},
+            vnffgd: {
+                width: 350,
+                file: 'default-icon-white.svg',
+                d: `M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z`},
+            'constituent-vnfd': {
+                width: 350,
+                file: 'default-icon-white.svg',
+                d: `M241.72,51.26c-92.14,0-166.83,75.48-166.83,168.59s74.69,168.59,166.83,168.59S408.55,313,408.55,219.85,333.86,51.26,241.72,51.26Z`},
+            nsd: {
+                width: 350,
+                file: 'default-icon.svg',
+                d: `M325.55,87.34c0,34.54-27.71,62.55-61.89,62.55s-61.89-28-61.89-62.55S229.48,24.8,263.66,24.8,325.55,52.8,325.55,87.34Zm-220.1,96.09c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S139.63,183.43,105.45,183.43ZM259,235.18c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S293.23,235.18,259,235.18Zm153.6-51.74c-34.18,0-61.89,28-61.89,62.55s27.71,62.55,61.89,62.55,61.89-28,61.89-62.55S446.83,183.43,412.64,183.43ZM213,127.14l-66,80.5m116.59-57.75v85.29m42.76-104.42,64,64.68`},
+                // d: `M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z`},
+            vld: {
+                width: 350,
+                file: 'default-icon-white.svg',
+                d: `M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z`},
+            'internal-vld': {
+                width: 350,
+                file: 'default-icon-white.svg',
+                d: `M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z`},
+            catalog: ``,
+            common: ``
+        }
+    }
+
+}
+
+export default IconFactory;
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/Classifier.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/Classifier.js
new file mode 100644 (file)
index 0000000..eed796c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
+import ClassifierConnectionPointRef from './ClassifierConnectionPointRef'
+
+/**
+ * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * methods are add to access the fields needed to do that.
+ */
+export default class Classifier extends DescriptorModel {
+
+       static get type() {
+               return 'classifier';
+       }
+
+       static get className() {
+               return 'Classifier';
+       }
+
+       static get qualifiedType() {
+               return 'nsd.vnffgd.' + Classifier.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = Classifier.type;
+               this.uiState['qualified-type'] = Classifier.qualifiedType;
+               this.className = Classifier.className;
+               this.position = new Position();
+               this._vnfdConnectionPointRef = new ClassifierConnectionPointRef(this);
+       }
+
+       get matchAttributes() {
+               if (!this.model['match-attributes']) {
+                       this.model['match-attributes'] = {};
+               }
+               return this.model['match-attributes'].map(d => DescriptorModelFactory.newClassifierMatchAttributes(d, this));
+       }
+
+       set matchAttributes(obj) {
+               return this.updateModelList('match-attributes', obj, DescriptorModelFactory.ClassifierMatchAttributes);
+       }
+
+       createMatchAttributes() {
+               const model = DescriptorModelMetaFactory.createModelInstanceForType(DescriptorModelFactory.ClassifierMatchAttributes.qualifiedType);
+               return this.matchAttributes = DescriptorModelFactory.newClassifierMatchAttributes(model, this);
+       }
+
+       removeMatchAttributes(matchAttributes) {
+               return this.removeModelListItem('matchAttributes', matchAttributes);
+       }
+
+       get vnfdConnectionPointRef() {
+               return this._vnfdConnectionPointRef || {};
+       }
+
+       // vnfdConnectionPointRef is read only by design
+
+       addVnfdConnectionPoint(cp) {
+               this.vnfdConnectionPointRef.vnfdRef = cp.parent.vnfdRef;
+               this.vnfdConnectionPointRef.vnfdId = cp.vnfdId;
+               this.vnfdConnectionPointRef.vnfdIndex = cp.vnfdIndex;
+               this.vnfdConnectionPointRef.vnfdConnectionPointName = cp.name;
+               this.vnfdConnectionPointRef.cpNumber = cp.cpNumber;
+       }
+
+       remove() {
+               return this.parent.removeClassifier(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/ClassifierConnectionPointRef.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/ClassifierConnectionPointRef.js
new file mode 100644 (file)
index 0000000..7668125
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+export default class ClassifierConnectionPointRef {
+
+       constructor(parent) {
+               this.parent = parent;
+       }
+
+       get key() {
+               return this.parent.model['member-vnf-index-ref'] + '/' + this.parent.model['vnfd-connection-point-ref'];
+       }
+
+       get title() {
+               return this.vnfdConnectionPointName;
+       }
+
+       get vnfdId() {
+               return this.parent.model['vnfd-id-ref'];
+       }
+
+       set vnfdId(id) {
+               return this.parent.model['vnfd-id-ref'] = id;
+       }
+
+       get vnfdIndex() {
+               return this.parent.model['member-vnf-index-ref'];
+       }
+
+       set vnfdIndex(index) {
+               return this.parent.model['member-vnf-index-ref'] = index;
+       }
+
+       get vnfdConnectionPointName() {
+               return this.parent.model['vnfd-connection-point-ref'];
+       }
+
+       set vnfdConnectionPointName(name) {
+               return this.parent.model['vnfd-connection-point-ref'] = name;
+       }
+
+       get cpNumber() {
+               return this.parent.uiState.cpNumber;
+       }
+
+       set cpNumber(n) {
+               this.parent.uiState.cpNumber = n;
+       }
+
+       get vnfdRef() {
+               return this.parent.uiState.vnfdRef;
+       }
+
+       set vnfdRef(n) {
+               this.parent.uiState.vnfdRef = n;
+       }
+
+       get order() {
+               return this.model['order'];
+       }
+
+       set order(n) {
+               this.model['order'] = n;
+       }
+
+       remove() {
+               return this.parent.removeVnfdConnectionPointRef();
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/ClassifierMatchAttributes.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/ClassifierMatchAttributes.js
new file mode 100644 (file)
index 0000000..f6d7957
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import RspConnectionPointRef from './RspConnectionPointRef'
+import VnfdConnectionPointRef from './VnfdConnectionPointRef'
+
+/**
+ * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * methods are add to access the fields needed to do that.
+ */
+export default class ClassifierMatchAttributes extends DescriptorModel {
+
+       static get type() {
+               return 'match-attributes';
+       }
+
+       static get className() {
+               return 'ClassifierMatchAttributes';
+       }
+
+       static get qualifiedType() {
+               return 'nsd.vnffgd.classifier.' + ClassifierMatchAttributes.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = ClassifierMatchAttributes.type;
+               this.uiState['qualified-type'] = ClassifierMatchAttributes.qualifiedType;
+               this.className = ClassifierMatchAttributes.className;
+               this.position = new Position();
+       }
+
+       getFieldValue(name) {
+               return this.model[name];
+       }
+
+       setFieldValue(name, value) {
+               this.model[name] = value;
+       }
+
+       remove() {
+               return this.parent.removeMatchAttributes(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/ConnectionPoint.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/ConnectionPoint.js
new file mode 100644 (file)
index 0000000..7d07571
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import RspConnectionPointRef from './RspConnectionPointRef'
+import VnfdConnectionPointRef from './VnfdConnectionPointRef'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+/**
+ * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * methods are add to access the fields needed to do that.
+ */
+export default class ConnectionPoint extends DescriptorModel {
+
+       static get type() {
+               return 'connection-point';
+       }
+
+       static get className() {
+               return 'VirtualNetworkFunctionConnectionPoint';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.' + ConnectionPoint.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = ConnectionPoint.type;
+               this.uiState['qualified-type'] = ConnectionPoint.qualifiedType;
+               this.className = 'VirtualNetworkFunctionConnectionPoint';
+               this.location = 'bottom-left';
+               this.position = new Position(parent.position.value());
+               this.position.top = parent.position.bottom;
+               this.position.width = 14;
+               this.position.height = 14;
+       }
+
+       get id() {
+               return this.model.name;
+       }
+
+       get key() {
+               return this.parent.key + '/' + this.model.name;
+       }
+
+       get name() {
+               return this.model.name;
+       }
+
+       get vnfdIndex() {
+               return this.parent.vnfdIndex;
+       }
+
+       get vnfdId() {
+               return this.parent.vnfdId;
+       }
+
+       get cpNumber() {
+               return this.uiState.cpNumber;
+       }
+
+       set cpNumber(n) {
+               this.uiState.cpNumber = n;
+       }
+
+       get order() {
+               return this.model['order'];
+       }
+
+       set order(n) {
+               this.model['order'] = n;
+       }
+
+       /**
+        * Convenience method to generate a VnfdConnectionPointRef instance from any given VirtualNetworkFunctionConnectionPoint.
+        *
+        * @returns {RspConnectionPointRef}
+        */
+       toRspConnectionPointRef() {
+               const ref = new RspConnectionPointRef({});
+               ref.vnfdId = this.vnfdId;
+               ref.vnfdIndex = this.vnfdIndex;
+               ref.vnfdConnectionPointName = this.name;
+               ref.cpNumber = this.cpNumber;
+               ref.order = this.order;
+               return ref;
+       }
+
+       toVnfdConnectionPointRef() {
+               const ref = new VnfdConnectionPointRef({});
+               ref.vnfdId = this.vnfdId;
+               ref.vnfdIndex = this.vnfdIndex;
+               ref.vnfdConnectionPointName = this.name;
+               ref.cpNumber = this.cpNumber;
+               ref.order = this.order;
+               return ref;
+       }
+
+       canConnectTo(obj) {
+               return (DescriptorModelFactory.isVirtualLink(obj) || DescriptorModelFactory.isConnectionPoint(obj)) && obj.parent !== this.parent;
+       }
+
+       remove() {
+               return this.parent.removeConnectionPoint(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/ConstituentVnfd.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/ConstituentVnfd.js
new file mode 100644 (file)
index 0000000..aa4b07c
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+export default class ConstituentVnfd extends DescriptorModel {
+
+       static get type() {
+               return 'constituent-vnfd';
+       }
+
+       static get className() {
+               return 'ConstituentVnfd';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'constituent-vnfd';
+               this.uiState['qualified-type'] = 'nsd.constituent-vnfd';
+               this.className = 'ConstituentVnfd';
+               this.addProp('vnfdRef', DescriptorModelFactory.newVirtualNetworkFunctionReadOnlyWrapper({}, this));
+       }
+
+       get id() {
+               return this.vnfdIndex;
+       }
+
+       get vld() {
+               if (this.vnfdRef) {
+                       return this.vnfdRef.vld;
+               }
+               return [];
+       }
+
+       get connectionPoint() {
+               if (this.vnfdRef) {
+                       return this.vnfdRef.connectionPoint;
+               }
+               return [];
+       }
+
+       get connectors() {
+               return this.connectionPoint
+       }
+
+       get vnfdRef() {
+               return this.getProp('vnfdRef');
+       }
+
+       set vnfdRef(ref) {
+               this.addProp('vnfdRef', DescriptorModelFactory.newVirtualNetworkFunctionReadOnlyWrapper(ref, this));
+               // since this vnfd reference is not part of
+               // the YANG, we need to provide info needed
+               // for the details editor to manipulate it.
+               this.uiState.vnfdIndex = this.vnfdIndex;
+               this.uiState.displayName = this.title;
+       }
+
+       get vnfdIndex() {
+               return this.model['member-vnf-index'];
+       }
+
+       set vnfdIndex(index) {
+               this.model['member-vnf-index'] = index;
+       }
+
+       get vnfdId() {
+               return this.model['vnfd-id-ref'];
+       }
+
+       set vnfdId(id) {
+               this.model['vnfd-id-ref'] = id;
+       }
+
+       get name() {
+               return this.vnfdRef.name;
+       }
+
+       get 'short-name'() {
+               return this.vnfdRef['short-name'];
+       }
+
+       get title() {
+               return (this['short-name'] || this.name) + `/${this.vnfdIndex}`;
+       }
+
+       get vnfdServiceFunctionChain() {
+               return this.vnfdRef.model['service-function-chain'] || 'UNAWARE';
+       }
+
+       remove() {
+               return this.parent.removeConstituentVnfd(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/ConstituentVnfdConnectionPoint.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/ConstituentVnfdConnectionPoint.js
new file mode 100644 (file)
index 0000000..5596ffd
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import ConnectionPoint from './ConnectionPoint'
+
+export default class ConstituentVnfdConnectionPoint extends ConnectionPoint {
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.uid = parent.uid + this.key;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/ForwardingGraph.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/ForwardingGraph.js
new file mode 100644 (file)
index 0000000..ef99af6
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import Classifier from './Classifier'
+import DescriptorModel from '../DescriptorModel'
+import RecordServicePath from './RecordServicePath'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
+
+export default class ForwardingGraph extends DescriptorModel {
+
+       static get type() {
+               return 'vnffgd';
+       }
+
+       static get className() {
+               return 'ForwardingGraph';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'vnffgd';
+               this.uiState['qualified-type'] = 'nsd.vnffgd';
+               this.className = 'ForwardingGraph';
+       }
+
+       get rsp() {
+               if (!this.model.rsp) {
+                       this.model.rsp = [];
+               }
+               return this.model.rsp.map(d => DescriptorModelFactory.newRecordServicePath(d, this));
+       }
+
+       set rsp(obj) {
+               this.updateModelList('rsp', obj, RecordServicePath);
+       }
+
+       createRsp() {
+               const model = DescriptorModelMetaFactory.createModelInstanceForType('nsd.vnffgd.rsp');
+               return this.rsp = new RecordServicePath(model, this);
+       }
+
+       removeRsp(obj) {
+               this.children.filter(d => d.id === obj.id).forEach(rsp => rsp.remove());
+       }
+
+       get recordServicePaths() {
+               return this.rsp;
+       }
+
+       removeRecordServicePath(child) {
+               this.rsp = this.rsp.filter(rsp => rsp.uid !== child.uid);
+               this.removeChild(child);
+       }
+
+       get classifier() {
+               if (!this.model['classifier']) {
+                       this.model['classifier'] = [];
+               }
+               return this.model['classifier'].map(d => DescriptorModelFactory.newClassifier(d, this));
+       }
+
+       set classifier(obj) {
+               this.updateModelList('classifier', obj, Classifier);
+       }
+
+       createClassifier(model) {
+               model = model || DescriptorModelMetaFactory.createModelInstanceForType(DescriptorModelFactory.Classifier.qualifiedType);
+               return this.classifier = DescriptorModelFactory.newClassifier(model, this);
+       }
+
+       removeClassifier(child) {
+               return this.removeModelListItem('classifier', child);
+       }
+
+       remove() {
+               if (this.parent) {
+                       return this.parent.removeVnffgd(this);
+               }
+       }
+
+       getColor() {
+
+       }
+
+       createClassifierForRecordServicePath(rsp) {
+               const classifier = this.createClassifier();
+               classifier.model['rsp-id-ref'] = rsp.id;
+       }
+
+       removeVnfdConnectionPointRefForVnfdIndex(vnfdIndex) {
+               this.rsp.forEach(rsp => rsp.removeVnfdConnectionPointRefForVnfdIndex(vnfdIndex));
+       }
+
+}
+
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalConnectionPoint.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalConnectionPoint.js
new file mode 100644 (file)
index 0000000..6648dc9
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+export default class InternalConnectionPoint extends DescriptorModel {
+
+       static get type() {
+               return 'internal-connection-point';
+       }
+
+       static get className() {
+               return 'InternalConnectionPoint';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.vdu.' + InternalConnectionPoint.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               // evil type collides with the YANG property 'type' for this object
+               this.type = 'internal-connection-point';
+               this.uiState['qualified-type'] = InternalConnectionPoint.qualifiedType;
+               this.className = 'InternalConnectionPoint';
+               this.location = 'bottom-left';
+               this.position = new Position(parent.position.value());
+               this.position.top = parent.position.bottom;
+               this.position.width = 14;
+               this.position.height = 14;
+       }
+
+       get key() {
+               return this.id;
+       }
+
+       toInternalConnectionPointRef() {
+               return DescriptorModelFactory.newInternalConnectionPointRef(this.id);
+       }
+
+       canConnectTo(obj) {
+               return DescriptorModelFactory.isInternalVirtualLink(obj) || (DescriptorModelFactory.isInternalConnectionPoint(obj) && obj.parent !== this.parent);
+       }
+
+       remove() {
+               return this.parent.removeInternalConnectionPoint(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalConnectionPointRef.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalConnectionPointRef.js
new file mode 100644 (file)
index 0000000..a7ea751
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+export default class InternalConnectionPointRef extends DescriptorModel {
+
+       static get type() {
+               return 'internal-connection-point-ref';
+       }
+
+       static get className() {
+               return 'InternalConnectionPointRef';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.internal-vld.' + InternalConnectionPointRef.type;
+       }
+
+       constructor(m, parent) {
+               super(!m || typeof m === 'string' ? {id: m, isLeaf: true} : m, parent);
+               this.uid = this.id;
+               this.type = InternalConnectionPointRef.type;
+               this.uiState['qualified-type'] = InternalConnectionPointRef.qualifiedType;
+               this.className = InternalConnectionPointRef.className;
+       }
+
+       toString() {
+               return this.valueOf();
+       }
+
+       remove() {
+               return this.parent.removeInternalConnectionPointRefForId(this.id);
+       }
+
+       valueOf() {
+               return this.id;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalVirtualLink.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/InternalVirtualLink.js
new file mode 100644 (file)
index 0000000..c3822d5
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+export default class InternalVirtualLink extends DescriptorModel {
+
+       static get type() {
+               return 'internal-vld';
+       }
+
+       static get className() {
+               return 'InternalVirtualLink';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.' + InternalVirtualLink.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = InternalVirtualLink.type;
+               this.uiState['qualified-type'] = InternalVirtualLink.qualifiedType;
+               this.className = InternalVirtualLink.className;
+       }
+
+       get title() {
+               return super.title || (this.type + '/' + this.id);
+       }
+
+       get connection() {
+               const list = this.model['internal-connection-point-ref'] || (this.model['internal-connection-point-ref'] = []);
+               return list.map(d => DescriptorModelFactory.newInternalConnectionPointRef(d, this));
+       }
+
+       set connection(connections) {
+               return this.updateModelList('internal-connection-point-ref', connections, DescriptorModelFactory.InternalConnectionPointRef);
+       }
+
+       addConnectionPoint(icp) {
+               icp.model['internal-vld-ref'] = this.id;
+               this.parent.removeAnyConnectionsForConnector(icp);
+               this.connection = icp.toInternalConnectionPointRef();
+       }
+
+       removeInternalConnectionPointRefForId(id) {
+               return this.connection = this.connection.filter(d => d.id !== id).map(d => d.id);
+       }
+
+       remove() {
+               return this.parent.removeInternalVirtualLink(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/NetworkService.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/NetworkService.js
new file mode 100644 (file)
index 0000000..16fb159
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import ColorGroups from '../../ColorGroups'
+import DescriptorModel from '../DescriptorModel'
+import ForwardingGraph from './ForwardingGraph'
+import VirtualLink from './VirtualLink'
+import ConstituentVnfd from './ConstituentVnfd'
+import PhysicalNetworkFunction from './PhysicalNetworkFunction'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
+
+const indexAsInteger = d => 1 + (parseInt(d.model['member-vnf-index'], 10) || 0);
+
+const suffixAsInteger = function (field) {
+       return (d) => 1 + (parseInt(String(d.model[field]).split('').reverse().join(''), 10) || 0);
+};
+
+const toBiggestValue = (newIndex, curIndex) => Math.max(newIndex, curIndex);
+
+export default class NetworkService extends DescriptorModel {
+
+       static get type() {
+               return 'nsd';
+       }
+
+       static get className() {
+               return 'NetworkService';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'nsd';
+               this.className = 'NetworkService';
+               this._connectors = [];
+       }
+
+       get constituentVnfd() {
+               if (!this.model['constituent-vnfd']) {
+                       this.model['constituent-vnfd'] = [];
+               }
+               return this.model['constituent-vnfd'].map(d => DescriptorModelFactory.newConstituentVnfd(d, this));
+       }
+
+       set constituentVnfd(obj) {
+               const updateNextVnfdIndex = (cvnfd) => {
+                       const items = this.constituentVnfd;
+                       const length = items.length;
+                       // the default value is set to an instance count but we want it to be a sequence no
+                       cvnfd.model['member-vnf-index'] = 0;
+                       cvnfd.model['member-vnf-index'] = items.map(indexAsInteger).reduce(toBiggestValue, length);
+               };
+               this.updateModelList('constituent-vnfd', obj, ConstituentVnfd, updateNextVnfdIndex);
+       }
+
+       createConstituentVnfd(model) {
+               model = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.constituent-vnfd');
+               return this.constituentVnfd = DescriptorModelFactory.newConstituentVnfd(model, this);
+       }
+
+       removeConstituentVnfd(cvnfd) {
+               cvnfd = this.findChildByUid(cvnfd);
+               this.vld.forEach(vld => vld.removeVnfdConnectionPointRefForVnfdIndex(cvnfd.vnfdIndex));
+               this.vnffgd.forEach(fg => fg.removeVnfdConnectionPointRefForVnfdIndex(cvnfd.vnfdIndex));
+               return this.removeModelListItem('constituentVnfd', cvnfd);
+       }
+
+       get pnfd() {
+               if (!this.model.pnfd) {
+                       this.model.pnfd = [];
+               }
+               return this.model.pnfd.map(d => DescriptorModelFactory.newPhysicalNetworkFunction(d, this));
+       }
+
+       set pnfd(obj) {
+               this.updateModelList('pnfd', obj, PhysicalNetworkFunction);
+       }
+
+       createPnfd(model) {
+               model = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.pnfd');
+               return this.pnfd = DescriptorModelFactory.newPhysicalNetworkFunction(model, this);
+       }
+
+       removePnfd(pnfd) {
+               return this.removeModelListItem('pnfd', pnfd);
+       }
+
+
+       get vld() {
+               if (!this.model.vld) {
+                       this.model.vld = [];
+               }
+               return this.model.vld.map(d => DescriptorModelFactory.newVirtualLink(d, this));
+       }
+
+       set vld(obj) {
+               this.updateModelList('vld', obj, VirtualLink);
+       }
+
+       createVld() {
+               const model = DescriptorModelMetaFactory.createModelInstanceForType('nsd.vld');
+               return this.vld = DescriptorModelFactory.newVirtualLink(model, this);
+       }
+
+       removeVLD(vld) {
+               return this.removeModelListItem('vld', vld);
+       }
+
+
+       get vnffgd() {
+               if (!this.model.vnffgd) {
+                       this.model.vnffgd = [];
+               }
+               return this.model.vnffgd.map(d => DescriptorModelFactory.newForwardingGraph(d, this)).map((fg, i) => {
+                       fg.uiState.colors = ColorGroups.getColorPair(i);
+                       return fg;
+               });
+       }
+
+       set vnffgd(obj) {
+               const onAddForwardingGraph = (fg) => {
+                       const index = this.vnffgd.map(suffixAsInteger('short-name')).reduce(toBiggestValue, this.vnffgd.length);
+                       fg.model['short-name'] = 'FG-' + index;
+               };
+               this.updateModelList('vnffgd', obj, ForwardingGraph, onAddForwardingGraph);
+       }
+
+       createVnffgd(model) {
+               model = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.vnffgd');
+               return this.vnffgd = DescriptorModelFactory.newForwardingGraph(model, this);
+       }
+
+       removeVnffgd(fg) {
+               return this.removeModelListItem('vnffgd', fg);
+       }
+
+       get forwardingGraphs() {
+               return this.vnffgd;
+       }
+
+
+       // NOTE temporarily disable NSD connection points
+       // https://trello.com/c/crVgg2A1/88-do-not-render-nsd-connection-in-the-composer
+       //get connectionPoint() {
+       //      if (this.model && this.model['connection-point']) {
+       //              return this.model['connection-point'];
+       //      }
+       //      return [];
+       //}
+       //
+       //get connectors() {
+       //      const parent = this;
+       //      if (!this._connectors.length) {
+       //              this._connectors = this.connectionPoint.map(cp => {
+       //                      return DescriptorModelFactory.newConnectionPoint(parent, cp);
+       //              });
+       //      }
+       //      return this._connectors;
+       //}
+
+       removeAnyConnectionsForConnector(cpc) {
+               // todo need to also remove connection points from related ForwardingGraph paths
+               this.vld.forEach(vldc => vldc.removeVnfdConnectionPointRefKey(cpc.key));
+       }
+
+       createConstituentVnfdForVnfd(vnfdRef) {
+               const cvnfd = this.createConstituentVnfd();
+               cvnfd.vnfdRef = vnfdRef;
+               cvnfd.vnfdId = vnfdRef.id;
+               return cvnfd;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/NetworkServiceConnectionPoint.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/NetworkServiceConnectionPoint.js
new file mode 100644 (file)
index 0000000..7d8ebd3
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import RspConnectionPointRef from './RspConnectionPointRef'
+import VnfdConnectionPointRef from './VnfdConnectionPointRef'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+/**
+ * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * methods are add to access the fields needed to do that.
+ */
+export default class ConnectionPoint extends DescriptorModel {
+
+       static get type() {
+               return 'connection-point';
+       }
+
+       static get className() {
+               return 'VirtualNetworkFunctionConnectionPoint';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.' + ConnectionPoint.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = ConnectionPoint.type;
+               this.uiState['qualified-type'] = ConnectionPoint.qualifiedType;
+               this.className = 'VirtualNetworkFunctionConnectionPoint';
+               this.location = 'bottom-left';
+               this.position = new Position(parent.position.value());
+               this.position.top = parent.position.bottom;
+               this.position.width = 14;
+               this.position.height = 14;
+       }
+
+       get id() {
+               return this.model.name;
+       }
+
+       get key() {
+               return this.parent.key + '/' + this.model.name;
+       }
+
+       get name() {
+               return this.model.name;
+       }
+
+       get vnfdIndex() {
+               return this.parent.vnfdIndex;
+       }
+
+       get vnfdId() {
+               return this.parent.vnfdId;
+       }
+
+       get cpNumber() {
+               return this.uiState.cpNumber;
+       }
+
+       set cpNumber(n) {
+               this.uiState.cpNumber = n;
+       }
+
+       /**
+        * Convenience method to generate a VnfdConnectionPointRef instance from any given VirtualNetworkFunctionConnectionPoint.
+        *
+        * @returns {RspConnectionPointRef}
+        */
+       toRspConnectionPointRef() {
+               const ref = new RspConnectionPointRef({});
+               ref.vnfdId = this.vnfdId;
+               ref.vnfdIndex = this.vnfdIndex;
+               ref.vnfdConnectionPointName = this.name;
+               ref.cpNumber = this.cpNumber;
+               return ref;
+       }
+
+       toVnfdConnectionPointRef() {
+               const ref = new VnfdConnectionPointRef({});
+               ref.vnfdId = this.vnfdId;
+               ref.vnfdIndex = this.vnfdIndex;
+               ref.vnfdConnectionPointName = this.name;
+               ref.cpNumber = this.cpNumber;
+               return ref;
+       }
+
+       canConnectTo(obj) {
+               return (DescriptorModelFactory.isVirtualLink(obj) || DescriptorModelFactory.isConnectionPoint(obj)) && obj.parent !== this.parent;
+       }
+
+       remove() {
+               return this.parent.removeConnectionPoint(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/PhysicalNetworkFunction.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/PhysicalNetworkFunction.js
new file mode 100644 (file)
index 0000000..25993f1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+
+export default class PhysicalNetworkFunction extends DescriptorModel {
+
+       static get type() {
+               return 'pnfd';
+       }
+
+       static get className() {
+               return 'PhysicalNetworkFunction';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'pnfd';
+               this.className = 'PhysicalNetworkFunction';
+       }
+
+       get connectionPoint() {
+               if (this.model && this.model['connection-points']) {
+                       return this.model['connection-points'];
+               }
+               return [];
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/RecordServicePath.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/RecordServicePath.js
new file mode 100644 (file)
index 0000000..8c43f10
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import DescriptorModel from '../DescriptorModel'
+import RspConnectionPointRef from './RspConnectionPointRef'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
+
+export default class RecordServicePath extends DescriptorModel {
+
+       static get type() {
+               return 'rsp';
+       }
+
+       static get className() {
+               return 'RecordServicePath';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'rsp';
+               this.uiState['qualified-type'] = 'nsd.vnffgd.rsp';
+               this.className = 'RecordServicePath';
+       }
+
+       get vnfdConnectionPointRef() {
+               if (!this.model['vnfd-connection-point-ref']) {
+                       this.model['vnfd-connection-point-ref'] = [];
+               }
+               return this.model['vnfd-connection-point-ref'].map(d => DescriptorModelFactory.newRspConnectionPointRef(d, this));
+       }
+
+       set vnfdConnectionPointRef(obj) {
+               this.updateModelList('vnfd-connection-point-ref', obj, RspConnectionPointRef);
+       }
+
+       createVnfdConnectionPointRef(connectionPoint) {
+               let ref;
+               if (DescriptorModelFactory.isConnectionPoint(connectionPoint)) {
+                       ref = connectionPoint.toRspConnectionPointRef();
+               } else {
+                       const model = DescriptorModelMetaFactory.createModelInstanceForType('nsd.vnffgd.rsp.vnfd-connection-point-ref');
+                       ref = new RspConnectionPointRef(model, this);
+               }
+               this.vnfdConnectionPointRef = ref;
+               return ref;
+       }
+
+       get connectionPoints() {
+               return this.vnfdConnectionPointRef;
+       }
+       remove() {
+               return this.parent.removeRecordServicePath(this);
+       }
+
+       /**
+        * Remove all connection points refs associate with this vnfd.
+        *
+        * @param vnfdIndex
+        */
+       removeVnfdConnectionPointRefForVnfdIndex(vnfdIndex) {
+               if (typeof vnfdIndex !== 'undefined') {
+                       const len = this.vnfdConnectionPointRef.length;
+                       this.vnfdConnectionPointRef = this.vnfdConnectionPointRef.filter(d => d.vnfdIndex !== vnfdIndex);
+                       return len !== this.vnfdConnectionPointRef.length;
+               }
+       }
+
+       removeRspConnectionPointRef(child) {
+               return this.removeModelListItem('vnfdConnectionPointRef', child);
+       }
+
+       createClassifier() {
+               this.parent.createClassifierForRecordServicePath(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/RspConnectionPointRef.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/RspConnectionPointRef.js
new file mode 100644 (file)
index 0000000..dc0b83a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import VnfdConnectionPointRef from './VnfdConnectionPointRef'
+
+export default class RspConnectionPointRef extends VnfdConnectionPointRef {
+
+       static get type() {
+               return 'rsp-connection-point-ref';
+       }
+
+       static get className() {
+               return 'RspConnectionPointRef';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'rsp-connection-point-ref';
+               this.uiState['qualified-type'] = 'nsd.vnffgd.rsp.vnfd-connection-point-ref';
+               this.className = 'RspConnectionPointRef';
+       }
+
+       remove() {
+               return this.parent.removeRspConnectionPointRef(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualDeploymentUnit.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualDeploymentUnit.js
new file mode 100644 (file)
index 0000000..b808452
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+export default class VirtualDeploymentUnit extends DescriptorModel {
+
+       static get type() {
+               return 'vdu';
+       }
+
+       static get className() {
+               return 'VirtualDeploymentUnit';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'vdu';
+               this.uiState['qualified-type'] = 'vnfd.vdu';
+               this.className = 'VirtualDeploymentUnit';
+       }
+
+       get key() {
+               return this.parent.key + '/' + super.key;
+       }
+
+       get connectionPoint() {
+               const list = this.model['internal-connection-point'] || (this.model['internal-connection-point'] = []);
+               return list.map(d => DescriptorModelFactory.newVirtualDeploymentUnitInternalConnectionPoint(d, this));
+       }
+
+       set connectionPoint(obj) {
+               return this.updateModelList('internal-connection-point', obj, DescriptorModelFactory.VirtualDeploymentUnitInternalConnectionPoint);
+       }
+
+       //get internalConnectionPoint() {
+       //      //https://trello.com/c/ZOyKQd3z/122-hide-lines-representing-interface-connection-point-references-both-internal-and-external-interfaces
+       //      const vduc = this;
+       //      if (this.model && this.model['internal-interface']) {
+       //              const icpMap = this.model['internal-connection-point'].reduce((r, d) => {
+       //                      r[d.id] = d;
+       //                      return r;
+       //              }, {});
+       //              return this.model['internal-interface'].reduce((result, internalIfc) => {
+       //                      const id = internalIfc['vdu-internal-connection-point-ref'];
+       //                      const keyPrefix = vduc.parent ? vduc.parent.key + '/' : '';
+       //                      if (icpMap[id]) {
+       //                              const icp = Object.assign({}, icpMap[id], {
+       //                                      key: keyPrefix + id,
+       //                                      name: internalIfc.name,
+       //                                      'virtual-interface': internalIfc['virtual-interface']
+       //                              });
+       //                              result.push(icp);
+       //                      }
+       //                      return result;
+       //              }, []);
+       //      }
+       //      return [];
+       //}
+
+       removeInternalConnectionPoint(icp) {
+               this.parent.removeAnyConnectionsForConnector(icp);
+               return this.removeModelListItem('connectionPoint', icp);
+       }
+
+       //get externalConnectionPoint() {
+       //      // https://trello.com/c/ZOyKQd3z/122-hide-lines-representing-interface-connection-point-references-both-internal-and-external-interfaces
+       //      //const vduc = this;
+       //      //if (vduc.model && vduc.model['external-interface']) {
+       //      //      return vduc.model['external-interface'].reduce((result, externalIfc) => {
+       //      //              const id = externalIfc['vnfd-connection-point-ref'];
+       //      //              const keyPrefix = vduc.parent ? vduc.parent.key + '/' : '';
+       //      //              result.push({id: id, key: keyPrefix + id});
+       //      //              return result;
+       //      //      }, []);
+       //      //}
+       //      return [];
+       //}
+       //
+       get connectors() {
+               return this.connectionPoint;
+       }
+
+       //get connection() {
+       //      return this.externalConnectionPoint;
+       //}
+
+       remove() {
+               return this.parent.removeVirtualDeploymentUnit(this);
+       }
+
+}
+
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualDeploymentUnitInternalConnectionPoint.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualDeploymentUnitInternalConnectionPoint.js
new file mode 100644 (file)
index 0000000..47947c8
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import InternalConnectionPoint from './InternalConnectionPoint'
+import RspConnectionPointRef from './RspConnectionPointRef'
+import VnfdConnectionPointRef from './VnfdConnectionPointRef'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+/**
+ * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * methods are add to access the fields needed to do that.
+ */
+export default class VirtualDeploymentUnitInternalConnectionPoint extends InternalConnectionPoint {
+
+       static get type() {
+               return 'internal-connection-point';
+       }
+
+       static get className() {
+               return 'VirtualDeploymentUnitInternalConnectionPoint';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.vdu.' + VirtualDeploymentUnitInternalConnectionPoint.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = VirtualDeploymentUnitInternalConnectionPoint.type;
+               this.uiState['qualified-type'] = VirtualDeploymentUnitInternalConnectionPoint.qualifiedType;
+               this.className = 'VirtualNetworkFunctionConnectionPoint';
+       }
+
+       remove() {
+               return this.parent.removeInternalConnectionPoint(this);
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualLink.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualLink.js
new file mode 100644 (file)
index 0000000..50c4653
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import UID from '../../../libraries/UniqueId'
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
+
+export default class VirtualLink extends DescriptorModel {
+
+       static get type() {
+               return 'vld';
+       }
+
+       static get className() {
+               return 'VirtualLink';
+       }
+
+       static get qualifiedType() {
+               return 'nsd.' + VirtualLink.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = VirtualLink.type;
+               this.uiState['qualified-type'] = VirtualLink.qualifiedType;
+               this.className = VirtualLink.className;
+       }
+
+       get title() {
+               const title = this.model['short-name'] || this.model.name || (this.model.type + '/' + this.id);
+               if (title && title.length > 18) {
+                       return title.substr(0, 18) + '...';
+               }
+               return title;
+       }
+
+       get connection() {
+               if (!this.model['vnfd-connection-point-ref']) {
+                       this.model['vnfd-connection-point-ref'] = [];
+               }
+               return this.model['vnfd-connection-point-ref'].map(d => DescriptorModelFactory.newVnfdConnectionPointRef(d, this));
+       }
+
+       set connection(connections) {
+               this.updateModelList('vnfd-connection-point-ref', connections, DescriptorModelFactory.VnfdConnectionPointRef);
+       }
+
+       createVnfdConnectionPointRef(model) {
+               model = model || DescriptorModelMetaFactory.createModelInstanceForType('nsd.vld.vnfd-connection-point-ref');
+               return this.connection = DescriptorModelFactory.newVnfdConnectionPointRef(model, this);
+       }
+
+       removeVnfdConnectionPointRefKey(cpRefKey) {
+               const child = this.connection.filter(d => d.key === cpRefKey)[0];
+               return this.removeModelListItem('connection', child);
+       }
+
+       addConnectionPoint(cp) {
+               this.parent.removeAnyConnectionsForConnector(cp);
+               const cpRef = cp.toVnfdConnectionPointRef();
+               this.connection = this.connection.concat(cpRef);
+       }
+
+       findConnectionPointRef(vnfdId, vnfdIndex, vnfdConnectionPointName) {
+               return this.connection.filter(d => d.vnfdId === vnfdId && d.vnfdIndex === vnfdIndex && d.vnfdConnectionPointName === vnfdConnectionPointName)[0];
+       }
+
+       remove() {
+               const nsdc = this.parent;
+               return nsdc.removeVLD(this);
+       }
+
+       removeVnfdConnectionPointRefForVnfdIndex(vnfdIndex) {
+               const size = this.connection.length;
+               if (typeof vnfdIndex !== 'undefined') {
+                       this.connection = this.connection.filter(d => d.vnfdIndex !== vnfdIndex).map(d => d.model);
+               }
+               return size !== this.connection.length;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunction.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunction.js
new file mode 100644 (file)
index 0000000..73e10d3
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import utils from '../../utils'
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
+
+export default class VirtualNetworkFunction extends DescriptorModel {
+
+       static get type() {
+               return 'vnfd';
+       }
+
+       static get className() {
+               return 'VirtualNetworkFunction';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'vnfd';
+               this.className = 'VirtualNetworkFunction';
+       }
+
+       get vdu() {
+               const list = this.model.vdu || (this.model.vdu = []);
+               return list.map(d => DescriptorModelFactory.newVirtualDeploymentUnit(d, this));
+       }
+
+       set vdu(obj) {
+               this.updateModelList('vdu', obj, DescriptorModelFactory.VirtualDeploymentUnit);
+       }
+
+       createVdu() {
+               const model = DescriptorModelMetaFactory.createModelInstanceForType('vnfd.vdu');
+               return this.vdu = DescriptorModelFactory.newVirtualDeploymentUnit(model, this);
+       }
+
+       removeVirtualDeploymentUnit(vdu) {
+               vdu.connectors.forEach(cp => this.removeAnyConnectionsForConnector(cp));
+               return this.vdu = this.vdu.filter(d => d.id !== vdu.id);
+       }
+
+       get vld() {
+               const list = this.model['internal-vld'] || (this.model['internal-vld'] = []);
+               return list.map(d => DescriptorModelFactory.newInternalVirtualLink(d, this));
+       }
+
+       set vld(obj) {
+               this.updateModelList('internal-vld', obj, DescriptorModelFactory.InternalVirtualLink);
+       }
+
+       createVld() {
+               const model = DescriptorModelMetaFactory.createModelInstanceForType('vnfd.internal-vld');
+               return this.vld = DescriptorModelFactory.newInternalVirtualLink(model, this);
+       }
+
+       /**
+        * @deprecated use `removeInternalVirtualLink()`
+        * @param vld
+        * @returns {*}
+        */
+       removeVld(vld) {
+               return this.removeModelListItem('vld', vld);
+       }
+
+       get connectionPoint() {
+               const list = this.model['connection-point'] || (this.model['connection-point'] = []);
+               return list.map(d => DescriptorModelFactory.newVirtualNetworkFunctionConnectionPoint(d, this));
+       }
+
+       set connectionPoint(obj) {
+               return this.updateModelList('connection-point', obj, DescriptorModelFactory.VirtualNetworkFunctionConnectionPoint);
+       }
+
+       removeConnectionPoint(cp) {
+               return this.removeModelListItem('connectionPoint', cp);
+       }
+
+       get connectors() {
+               return this.connectionPoint;
+       }
+
+       remove() {
+               if (this.parent) {
+                       this.parent.removeConstituentVnfd(this);
+                       this.connectors.forEach(cpc => this.parent.removeAnyConnectionsForConnector(cpc));
+               }
+       }
+
+       removeAnyConnectionsForConnector(cpc) {
+               this.vld.forEach(vld => vld.removeInternalConnectionPointRefForId(cpc.id));
+       }
+
+       removeInternalVirtualLink(ivl) {
+               return this.removeModelListItem('vld', ivl);
+       }
+
+}
+
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunctionConnectionPoint.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunctionConnectionPoint.js
new file mode 100644 (file)
index 0000000..87c8fd4
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import Position from '../../graph/Position'
+import DescriptorModel from '../DescriptorModel'
+import ConnectionPoint from './ConnectionPoint'
+import RspConnectionPointRef from './RspConnectionPointRef'
+import VnfdConnectionPointRef from './VnfdConnectionPointRef'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+/**
+ * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * methods are add to access the fields needed to do that.
+ */
+export default class VirtualNetworkFunctionConnectionPoint extends ConnectionPoint {
+
+       static get type() {
+               return 'connection-point';
+       }
+
+       static get className() {
+               return 'VirtualNetworkFunctionConnectionPoint';
+       }
+
+       static get qualifiedType() {
+               return 'vnfd.' + VirtualNetworkFunctionConnectionPoint.type;
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = VirtualNetworkFunctionConnectionPoint.type;
+               this.uiState['qualified-type'] = VirtualNetworkFunctionConnectionPoint.qualifiedType;
+               this.className = 'VirtualNetworkFunctionConnectionPoint';
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunctionReadOnlyWrapper.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VirtualNetworkFunctionReadOnlyWrapper.js
new file mode 100644 (file)
index 0000000..bb8d21a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+import DescriptorModelFactory from '../DescriptorModelFactory'
+
+export default class VirtualNetworkFunctionReadOnlyWrapper extends DescriptorModel {
+
+       constructor(model, parent) {
+               super(model, parent);
+       }
+
+       get vld() {
+               if (!this.model['internal−vld']) {
+                       this.model['internal−vld'] = [];
+               }
+               return this.model['internal−vld'].map(d => DescriptorModelFactory.newInternalVirtualLink(d, this.parent));
+       }
+
+       get connectionPoint() {
+               if (!this.model['connection-point']) {
+                       this.model['connection-point'] = [];
+               }
+               return this.model['connection-point'].map(d => DescriptorModelFactory.newConstituentVnfdConnectionPoint(d, this.parent));
+       }
+
+       get connectors() {
+               return this.connectionPoint;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/model/descriptors/VnfdConnectionPointRef.js b/skyquake/plugins/composer/src/src/libraries/model/descriptors/VnfdConnectionPointRef.js
new file mode 100644 (file)
index 0000000..4cbaeaa
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import DescriptorModel from '../DescriptorModel'
+
+/**
+ * This class creates the identity of a VirtualNetworkFunctionConnectionPoint on a VNFD. Visually
+ * this class represents an svg:Path between the parent VLD and VirtualNetworkFunctionConnectionPoint.
+ *
+ *     VNFD.VirtualNetworkFunctionConnectionPoint ====path==== VLD
+ *
+ * The VNFD is referenced by nsd.constituent-vnfd.member-vnf-index.
+ * The VirtualNetworkFunctionConnectionPoint is referenced by vnfd.connection-point.name.
+ */
+export default class VnfdConnectionPointRef extends DescriptorModel {
+
+       static get type() {
+               return 'vnfd-connection-point-ref';
+       }
+
+       static get className() {
+               return 'VnfdConnectionPointRef';
+       }
+
+       constructor(model, parent) {
+               super(model, parent);
+               this.type = 'vnfd-connection-point-ref';
+               this.uiState['qualified-type'] = 'nsd.vld.vnfd-connection-point-ref';
+               this.className = 'VnfdConnectionPointRef';
+       }
+
+       get key() {
+               return this.model['member-vnf-index-ref'] + '/' + this.model['vnfd-connection-point-ref'];
+       }
+
+       get title() {
+               return this.type;
+       }
+
+       get vnfdId() {
+               return this.model['vnfd-id-ref'];
+       }
+
+       set vnfdId(id) {
+               return this.model['vnfd-id-ref'] = id;
+       }
+
+       get vnfdIndex() {
+               return this.model['member-vnf-index-ref'];
+       }
+
+       set vnfdIndex(index) {
+               return this.model['member-vnf-index-ref'] = index;
+       }
+
+       get vnfdConnectionPointName() {
+               return this.model['vnfd-connection-point-ref'];
+       }
+
+       set vnfdConnectionPointName(name) {
+               return this.model['vnfd-connection-point-ref'] = name;
+       }
+
+       get cpNumber() {
+               return this.uiState.cpNumber;
+       }
+
+       set cpNumber(n) {
+               this.uiState.cpNumber = n;
+       }
+
+       get order() {
+               return this.model['order'];
+       }
+
+       set order(n) {
+               this.model['order'] = n;
+       }
+
+       remove() {
+               if (this.parent) {
+                       return this.parent.removeVnfdConnectionPointRefKey(this.key);
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/utils.js b/skyquake/plugins/composer/src/src/libraries/utils.js
new file mode 100644 (file)
index 0000000..01e6675
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+'use strict';
+
+import changeCase from 'change-case';
+
+export default {
+       addAuthorizationStub(xhr) {
+               xhr.setRequestHeader('Authorization', 'Basic YWRtaW46YWRtaW4=');
+       },
+       getSearchParams(url) {
+               var a = document.createElement('a');
+               a.href = url;
+               var params = {};
+               var items = a.search.replace('?', '').split('&');
+               for (var i = 0; i < items.length; i++) {
+                       if (items[i].length > 0) {
+                               var key_value = items[i].split('=');
+                               params[key_value[0]] = decodeURIComponent(key_value[1]);
+                       }
+               }
+               return params;
+       },
+       parseJSONIgnoreErrors(txt) {
+               try {
+                       return JSON.parse(txt);
+               } catch (ignore) {
+                       return {};
+               }
+       },
+       resolvePath(obj, path) {
+               // supports a.b, a[1] and foo[bar], etc.
+               // where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]
+               // then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;
+               path = path.split(/[\.\[\]]/).filter(d => d);
+               return path.reduce((r, p) => {
+                       if (r) {
+                               return r[p];
+                       }
+               }, obj);
+       },
+       assignPathValue(obj, path, value) {
+               path = path.split(/[\.\[\]]/).filter(d => d);
+               // enable look-ahead to determine if type is array or object
+               const pathCopy = path.slice();
+               // last item in path used to assign value on the resolved object
+               const name = path.pop();
+               const resolvedObj = path.reduce((r, p, i) => {
+                       if (typeof(r[p]) !== 'object') {
+                               // look-ahead to see if next path item is a number
+                               const isArray = !isNaN(parseInt(pathCopy[i + 1], 10));
+                               r[p] = isArray ? [] : {}
+                       }
+                       return r[p];
+               }, obj);
+               resolvedObj[name] = value;
+       },
+       updatePathValue(obj, path, value) {
+               // todo: replace implementation of assignPathValue with this impl and
+               // remove updatePathValue (only need one function, not both)
+               // same as assignPathValue except removes property if value is undefined
+               path = path.split(/[\.\[\]]/).filter(d => d);
+               const isRemove = typeof value === 'undefined';
+               // enable look-ahead to determine if type is array or object
+               const pathCopy = path.slice();
+               // last item in path used to assign value on the resolved object
+               const name = path.pop();
+               const resolvedObj = path.reduce((r, p, i) => {
+                       // look-ahead to see if next path item is a number
+                       const index = parseInt(pathCopy[i + 1], 10);
+                       const isArray = !isNaN(index);
+                       if (typeof(r[p]) !== 'object') {
+                               r[p] = isArray ? [] : {}
+                       }
+                       if (isRemove && ((i + 1) === path.length)) {
+                               if (isArray) {
+                                       r[p] = r[p].filter((d, i) => i !== index);
+                               } else {
+                                       delete r[p][name];
+                               }
+                       }
+                       return r[p];
+               }, obj);
+               if (!isRemove) {
+                       resolvedObj[name] = value;
+               }
+       },
+       removePathValue(obj, path) {
+               // note updatePathValue removes value if third argument is undefined
+               return this.updatePathValue(obj, path);
+       },
+
+       suffixAsInteger: (field) => {
+               return (obj) =>{
+                       const str = String(obj[field]);
+                       const value = str.replace(str.replace(/[\d]+$/, ''), '');
+                       return 1 + parseInt(value, 10) || 0;
+               };
+       },
+
+       toBiggestValue: (maxIndex, curIndex) => Math.max(maxIndex, curIndex)
+
+}
diff --git a/skyquake/plugins/composer/src/src/libraries/zoomFactor.js b/skyquake/plugins/composer/src/src/libraries/zoomFactor.js
new file mode 100644 (file)
index 0000000..470599a
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+export default function zoomFactor(element = document.body) {
+       let factor;
+       const rect = element.getBoundingClientRect();
+       const physicalW = rect.right - rect.left;
+       const logicalW = element.offsetWidth;
+       factor = Math.round((physicalW / logicalW) * 100) / 100;
+       // if fullscreen mode offsetWidth is 0
+       if (isNaN(factor)) {
+               factor = 1;
+       }
+       return factor;
+}
diff --git a/skyquake/plugins/composer/src/src/sources/CatalogDataSource.js b/skyquake/plugins/composer/src/src/sources/CatalogDataSource.js
new file mode 100644 (file)
index 0000000..e742a9e
--- /dev/null
@@ -0,0 +1,160 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import $ from 'jquery'
+import alt from '../alt'
+import utils from '../libraries/utils'
+import serializers from '../libraries/model/DescriptorModelSerializer'
+import CatalogDataSourceActions from '../actions/CatalogDataSourceActions'
+let Utils = require('utils/utils.js');
+const CatalogDataSource = {
+
+       loadCatalogs: function() {
+               return {
+                       remote: function() {
+                               return new Promise(function(resolve, reject) {
+                                       $.ajax({
+                                               beforeSend: Utils.addAuthorizationStub,
+                                               url: 'api/catalog?api_server=' + utils.getSearchParams(window.location).api_server,
+                                               // url: '/composer/big-honking-catalog',
+                                               // url: '/composer/ping-pong-catalog',
+                                               // url: '/composer/empty-nsd-catalog',
+                                               success: function(data) {
+                                                       if (typeof data == 'string') {
+                                                               data = JSON.parse(data);
+                                                       }
+                                                       const context = Object.assign({}, this, {data: data});
+                                                       resolve(context);
+                                               },
+                                               error: function(error) {
+                                                       if (typeof error == 'string') {
+                                                               error = JSON.parse(error);
+                                                       }
+                                                       reject(error);
+                                               }
+                                       }).fail(function(xhr){
+                                   //Authentication and the handling of fail states should be wrapped up into a connection class.
+                                   Utils.checkAuthentication(xhr.status);
+                               });
+                               });
+                       },
+                       success: CatalogDataSourceActions.loadCatalogsSuccess,
+                       error: CatalogDataSourceActions.loadCatalogsError
+               }
+       },
+
+       deleteCatalogItem: function() {
+               return {
+                       remote: function(state, catalogType, itemId) {
+                               return new Promise(function(resolve, reject) {
+                                       $.ajax({
+                                               url: 'api/catalog/' + catalogType + '/' + itemId + '?api_server=' + utils.getSearchParams(window.location).api_server,
+                                               type: 'DELETE',
+                                               beforeSend: utils.addAuthorizationStub,
+                                               success: function(data) {
+                                                       resolve({
+                                                               data: data,
+                                                               catalogType: catalogType,
+                                                               itemId: itemId
+                                                       });
+                                               },
+                                               error: function(error) {
+                                                       reject({
+                                                               error: error,
+                                                               catalogType: catalogType,
+                                                               itemId: itemId
+                                                       });
+                                               }
+                                       });
+                               });
+                       },
+                       success: CatalogDataSourceActions.deleteCatalogItemSuccess,
+                       error: CatalogDataSourceActions.deleteCatalogItemError
+               }
+       },
+
+       saveCatalogItem: function () {
+               return {
+                       remote: function (state, item = {}) {
+                               const method = item.uiState.isNew ? 'POST' : 'PUT';
+                               const payload = serializers.serialize(item);
+                               return new Promise((resolve, reject) => {
+                                       if (payload === false) {
+                                               reject({
+                                                       error: 'unable to serialize item: ' + item.id,
+                                                       catalogType: item.uiState.type,
+                                                       itemId: payload.id
+                                               });
+                                       }
+                                       if (method === 'POST') {
+                                               $.ajax({
+                                                       url: 'api/catalog/' + item.uiState.type + '?api_server=' + utils.getSearchParams(window.location).api_server,
+                                                       type: method,
+                                                       beforeSend: utils.addAuthorizationStub,
+                                                       data: payload,
+                                                       dataType: 'json',
+                                                       success: function(data) {
+                                                               resolve({
+                                                                       data: data,
+                                                                       catalogType: item.uiState.type,
+                                                                       itemId: payload.id
+                                                               });
+                                                       },
+                                                       error: function(error) {
+                                                               reject({
+                                                                       error: error,
+                                                                       catalogType: item.uiState.type,
+                                                                       itemId: payload.id
+                                                               });
+                                                       }
+                                               });
+                                       } else {
+                                               $.ajax({
+                                                       url: 'api/catalog/' + item.uiState.type + '/' + payload.id + '?api_server=' + utils.getSearchParams(window.location).api_server,
+                                                       type: method,
+                                                       beforeSend: utils.addAuthorizationStub,
+                                                       data: payload,
+                                                       dataType: 'json',
+                                                       success: function(data) {
+                                                               resolve({
+                                                                       data: data,
+                                                                       catalogType: item.uiState.type,
+                                                                       itemId: payload.id
+                                                               });
+                                                       },
+                                                       error: function(error) {
+                                                               reject({
+                                                                       error: error,
+                                                                       catalogType: item.uiState.type,
+                                                                       itemId: payload.id
+                                                               });
+                                                       }
+                                               });
+                                       }
+                               });
+                       },
+                       success: CatalogDataSourceActions.saveCatalogItemSuccess,
+                       error: CatalogDataSourceActions.saveCatalogItemError
+               };
+       }
+};
+
+export default CatalogDataSource;
diff --git a/skyquake/plugins/composer/src/src/sources/CatalogPackageManagerSource.js b/skyquake/plugins/composer/src/src/sources/CatalogPackageManagerSource.js
new file mode 100644 (file)
index 0000000..be11dfc
--- /dev/null
@@ -0,0 +1,117 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import $ from 'jquery'
+import alt from '../alt'
+import utils from '../libraries/utils'
+import CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'
+let Utils = require('utils/utils.js');
+function getApiServerOrigin() {
+       return utils.getSearchParams(window.location).upload_server + ':4567';
+}
+
+function ajaxRequest(path, catalogPackage, resolve, reject, method = 'GET') {
+       $.ajax({
+               url: getApiServerOrigin() + path,
+               type: method,
+               beforeSend: Utils.addAuthorizationStub,
+               dataType: 'json',
+               success: function(data) {
+                       if (typeof data == 'string') {
+                               data = JSON.parse(data);
+                       }
+                       resolve({
+                               data: data,
+                               state: catalogPackage
+                       });
+               },
+               error: function(error) {
+                       if (typeof error == 'string') {
+                               error = JSON.parse(error);
+                       }
+                       reject({
+                               data: error,
+                               state: catalogPackage
+                       });
+               }
+       }).fail(function(xhr){
+                                   //Authentication and the handling of fail states should be wrapped up into a connection class.
+                                   Utils.checkAuthentication(xhr.status);
+                               });
+}
+
+const CatalogPackageManagerSource = {
+
+       requestCatalogPackageDownload: function () {
+               return {
+                       remote: function (state, download, format, grammar) {
+                               return new Promise((resolve, reject) => {
+                                       // the server does not add a status in the payload
+                                       // so we add one so that the success handler will
+                                       // be able to follow the flow of this download
+                                       const setStatusBeforeResolve = (response = {}) => {
+                                               response.data.status = 'download-requested';
+                                               resolve(response);
+                                       };
+                                       // RIFT-13485 requires to send type (nsd/vnfd) as a path element.
+                                       // Backend no longer supports mixed multi-package download.
+                                       // Probably does not even support multi-package download of same type.
+                                       // Hence, pick the type from the first element.
+                                       const path = '/api/export/' + download['catalogItems'][0]['uiState']['type'] + '?schema=' + format + '&grammar=' + grammar + '&format=yaml&ids=' + download.ids;
+                                       ajaxRequest(path, download, setStatusBeforeResolve, reject);
+                               });
+                       },
+                       success: CatalogPackageManagerActions.downloadCatalogPackageStatusUpdated,
+                       error: CatalogPackageManagerActions.downloadCatalogPackageError
+               };
+       },
+
+       requestCatalogPackageDownloadStatus: function() {
+               return {
+                       remote: function(state, download) {
+                               const transactionId = download.transactionId;
+                               return new Promise(function(resolve, reject) {
+                                       const path = '/api/export/' + transactionId + '/state';
+                                       ajaxRequest(path, download, resolve, reject);
+                               });
+                       },
+                       success: CatalogPackageManagerActions.downloadCatalogPackageStatusUpdated,
+                       error: CatalogPackageManagerActions.downloadCatalogPackageError
+               }
+       },
+
+       requestCatalogPackageUploadStatus: function () {
+               return {
+                       remote: function (state, upload) {
+                               const transactionId = upload.transactionId;
+                               return new Promise(function (resolve, reject) {
+                                       const action = upload.riftAction === 'onboard' ? 'upload' : 'update';
+                                       const path = '/api/' + action + '/' + transactionId + '/state';
+                                       ajaxRequest(path, upload, resolve, reject);
+                               });
+                       },
+                       success: CatalogPackageManagerActions.uploadCatalogPackageStatusUpdated,
+                       error: CatalogPackageManagerActions.uploadCatalogPackageError
+               };
+       }
+
+};
+
+export default CatalogPackageManagerSource;
diff --git a/skyquake/plugins/composer/src/src/sources/RiftHeaderSource.js b/skyquake/plugins/composer/src/src/sources/RiftHeaderSource.js
new file mode 100644 (file)
index 0000000..e479d33
--- /dev/null
@@ -0,0 +1,76 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+ // NOTE: THIS FILE HAS BEEN DEPRECATED AND WILL BE REMOVED
+'use strict';
+
+import $ from 'jquery'
+import alt from '../alt'
+import utils from '../libraries/utils'
+import RiftHeaderActions from '../actions/RiftHeaderActions'
+
+function getApiServerOrigin() {
+       return utils.getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+}
+function ajaxRequest(path, catalogPackage, resolve, reject, method = 'GET') {
+       $.ajax({
+               url: '//' + window.location.hostname + ':' + getApiServerOrigin() + path,
+               type: method,
+               beforeSend: utils.addAuthorizationStub,
+               dataType: 'json',
+               success: function(data) {
+                       if (typeof data == 'string') {
+                               data = JSON.parse(data);
+                       }
+                       resolve({
+                               data: data,
+                               state: catalogPackage
+                       });
+               },
+               error: function(error) {
+                       if (typeof error == 'string') {
+                               error = JSON.parse(error);
+                       }
+                       reject({
+                               data: error,
+                               state: catalogPackage
+                       });
+               }
+       });
+}
+
+const RiftHeaderSource = {
+
+       requestLaunchpadConfig: function () {
+               return {
+                       remote: function (state, download) {
+                               return new Promise((resolve, reject) => {
+                                       // const path = '/launchpad/config?api_server=' + utils.getSearchParams(window.location).api_server;
+                                       // ajaxRequest(path, download, resolve, reject);
+                                       resolve();
+                               });
+                       },
+                       success: RiftHeaderActions.requestLaunchpadConfigSuccess,
+                       error: RiftHeaderActions.requestLaunchpadConfigError
+               };
+       },
+};
+
+export default RiftHeaderSource;
diff --git a/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js b/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js
new file mode 100644 (file)
index 0000000..144332c
--- /dev/null
@@ -0,0 +1,604 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import cc from 'change-case'
+import alt from '../alt'
+import UID from '../libraries/UniqueId'
+import guid from '../libraries/guid'
+import React from 'react'
+import DescriptorModel from '../libraries/model/DescriptorModel'
+import DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'
+import CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'
+import CatalogDataSourceActions from '../actions/CatalogDataSourceActions'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import ModalOverlayActions from '../actions/ModalOverlayActions'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import CatalogDataSource from '../sources/CatalogDataSource'
+import ComposerAppStore from '../stores/ComposerAppStore'
+import SelectionManager from '../libraries/SelectionManager'
+import ExportSelectorDialog from '../components/ExportSelectorDialog'
+
+const defaults = {
+       catalogs: [],
+       catalogItemExportFormats: ['mano', 'rift'],
+       catalogItemExportGrammars: ['osm', 'tosca']
+};
+
+const areCatalogItemsMetaDataEqual = function (a, b) {
+       const metaProps = ['id', 'name', 'short-name', 'description', 'vendor', 'version'];
+       const aMetaData = _.pick(a, metaProps);
+       const bMetaData = _.pick(b, metaProps);
+       return _.isEqual(aMetaData, bMetaData);
+};
+
+class CatalogDataStore {
+
+       constructor() {
+               this.catalogs = defaults.catalogs;
+               this.isLoading = true;
+               this.requiresSave = false;
+               this.snapshots = {};
+               this.selectedFormat = defaults.catalogItemExportFormats[0];
+               this.selectedGrammar = defaults.catalogItemExportGrammars[0];
+               this.registerAsync(CatalogDataSource);
+               this.bindActions(CatalogDataSourceActions);
+               this.bindActions(CatalogItemsActions);
+       }
+
+       resetSelectionState = () => {
+               this.selectedFormat = defaults.catalogItemExportFormats[0];
+               this.selectedGrammar = defaults.catalogItemExportGrammars[0];
+       }
+
+       getCatalogs() {
+               return this.catalogs || (this.catalogs = []);
+       }
+
+       getAllSelectedCatalogItems() {
+               return this.getCatalogs().reduce((r, d) => {
+                       d.descriptors.forEach(d => {
+                               if (SelectionManager.isSelected(d) /*d.uiState.selected*/) {
+                                       r.push(d);
+                               }
+                       });
+                       return r;
+               }, []);
+       }
+
+       getFirstSelectedCatalogItem() {
+               return this.getCatalogs().reduce((r, catalog) => {
+                       return r.concat(catalog.descriptors.filter(d => SelectionManager.isSelected(d) /*d.uiState.selected*/));
+               }, [])[0];
+       }
+
+       getCatalogItemById(id) {
+               return this.getCatalogs().reduce((r, catalog) => {
+                       return r.concat(catalog.descriptors.filter(d => d.id === id));
+               }, [])[0];
+       }
+
+       getCatalogItemByUid(uid) {
+               return this.getCatalogs().reduce((r, catalog) => {
+                       return r.concat(catalog.descriptors.filter(d => UID.from(d) === uid));
+               }, [])[0];
+       }
+
+       removeCatalogItem(deleteItem = {}) {
+               this.getCatalogs().map(catalog => {
+                       catalog.descriptors = catalog.descriptors.filter(d => d.id !== deleteItem.id);
+                       return catalog;
+               });
+       }
+
+       addNewItemToCatalog(newItem) {
+               const id = guid();
+               const type = newItem.uiState.type;
+               newItem.id = id;
+               UID.assignUniqueId(newItem.uiState);
+               this.getCatalogs().filter(d => d.type === type).forEach(catalog => {
+                       catalog.descriptors.push(newItem);
+               });
+               // update indexes and integrate new model into catalog
+               this.updateCatalogIndexes(this.getCatalogs());
+               return this.getCatalogItemById(id);
+       }
+
+       updateCatalogIndexes(catalogs) {
+               // associate catalog identity with individual descriptors so we can
+               // update the catalog when any given descriptor is updated also add
+               // vnfd model to the nsd object to make it easier to render an nsd
+               const vnfdLookup = {};
+               const updatedCatalogs = catalogs.map(catalog => {
+                       catalog.descriptors.map(descriptor => {
+                               if (typeof descriptor.meta === 'string' && descriptor.meta.trim() !== '') {
+                                       try {
+                                               descriptor.uiState = JSON.parse(descriptor.meta);
+                                       } catch (ignore) {
+                                               console.warn('Unable to deserialize the uiState property.');
+                                       }
+                               } else if (typeof descriptor.meta === 'object') {
+                                       descriptor.uiState = descriptor.meta;
+                                       descriptor.meta = JSON.stringify(descriptor.meta);
+                               }
+
+                               const uiState = descriptor.uiState || (descriptor.uiState = {});
+                               uiState.catalogId = catalog.id;
+                               uiState.catalogName = catalog.name;
+                               uiState.type = catalog.type;
+                               if (!UID.hasUniqueId(uiState)) {
+                                       UID.assignUniqueId(uiState);
+                               }
+                               if (catalog.type === 'vnfd') {
+                                       vnfdLookup[descriptor.id] = descriptor;
+                               }
+                               return descriptor;
+                       });
+                       return catalog;
+               });
+               updatedCatalogs.filter(d => d.type === 'nsd').forEach(catalog =>  {
+                       catalog.descriptors = catalog.descriptors.map(descriptor => {
+                               const instanceRefCount = parseInt(descriptor.uiState['instance-ref-count'], 10);
+                               if (descriptor['constituent-vnfd']) {
+                                       descriptor.vnfd = descriptor['constituent-vnfd'].map(d => {
+                                               const vnfdId = d['vnfd-id-ref'];
+                                               const vnfd = vnfdLookup[vnfdId];
+                                               if (!vnfd) {
+                                                       throw new ReferenceError('no VNFD found in the VNFD Catalog for the constituent-vnfd: ' + d);
+                                               }
+                                               if (!isNaN(instanceRefCount) && instanceRefCount > 0) {
+                                                       // this will notify user that this item cannot be updated when/if they make a change to it
+                                                       vnfd.uiState['instance-ref-count'] = instanceRefCount;
+                                               }
+                                               // create an instance of this vnfd to carry transient ui state properties
+                                               const instance = _.cloneDeep(vnfd);
+                                               instance.uiState['member-vnf-index'] = d['member-vnf-index'];
+                                               instance['vnf-configuration'] = d['vnf-configuration'];
+                                               instance['start-by-default'] = d['start-by-default'];
+                                               return instance;
+                                       });
+                               }
+                               return descriptor;
+                       });
+               });
+               return updatedCatalogs;
+       }
+
+       updateCatalogItem(item) {
+               // replace the given item in the catalog
+               const catalogs = this.getCatalogs().map(catalog => {
+                       if (catalog.id === item.uiState.catalogId) {
+                               catalog.descriptors = catalog.descriptors.map(d => {
+                                       if (d.id === item.id) {
+                                               return item;
+                                       }
+                                       return d;
+                               });
+                       }
+                       return catalog;
+               });
+               this.setState({catalogs: catalogs});
+       }
+
+       mergeEditsIntoLatestFromServer(catalogsFromServer = []) {
+
+               // if the UI has modified items use them instead of the server items
+
+               const currentData = this.getCatalogs();
+
+               const modifiedItemsMap = currentData.reduce((result, catalog) => {
+                       return result.concat(catalog.descriptors.filter(d => d.uiState.modified));
+               }, []).reduce((r, d) => {
+                       r[d.uiState.catalogId + '/' + d.id] = d;
+                       return r;
+               }, {});
+
+               const itemMetaMap = currentData.reduce((result, catalog) => {
+                       return result.concat(catalog.descriptors.filter(d => d.uiState));
+               }, []).reduce((r, d) => {
+                       r[d.uiState.catalogId + '/' + d.id] = d.uiState;
+                       return r;
+               }, {});
+
+               const newItemsMap = currentData.reduce((result, catalog) => {
+                       result[catalog.id] = catalog.descriptors.filter(d => d.uiState.isNew);
+                       return result;
+               }, {});
+
+               catalogsFromServer.forEach(catalog => {
+                       catalog.descriptors = catalog.descriptors.map(d => {
+                               const key = d.uiState.catalogId + '/' + d.id;
+                               if (modifiedItemsMap[key]) {
+                                       // use local modified item instead of the server item
+                                       return modifiedItemsMap[key];
+                               }
+                               if (itemMetaMap[key]) {
+                                       Object.assign(d.uiState, itemMetaMap[key]);
+                               }
+                               return d;
+                       });
+                       if (newItemsMap[catalog.id]) {
+                               catalog.descriptors = catalog.descriptors.concat(newItemsMap[catalog.id]);
+                       }
+               });
+
+               return catalogsFromServer;
+
+       }
+
+       loadCatalogsSuccess(context) {
+               const fromServer = this.updateCatalogIndexes(context.data);
+               const catalogs = this.mergeEditsIntoLatestFromServer(fromServer);
+               this.setState({
+                       catalogs: catalogs,
+                       isLoading: false
+               });
+       }
+
+       deleteCatalogItemSuccess (response) {
+               let catalogType = response.catalogType;
+               let itemId = response.itemId;
+               const catalogs = this.getCatalogs().map(catalog => {
+                       if (catalog.type === catalogType) {
+                               catalog.descriptors = catalog.descriptors.filter(d => d.id !== itemId);
+                       }
+                       return catalog;
+               });
+
+               this.setState({catalogs: catalogs});
+       }
+
+       deleteCatalogItemError (data) {
+               console.log('Unable to delete', data.catalogType, 'id:', data.itemId, 'Error:', data.error.responseText);
+               ComposerAppActions.showError.defer({
+                       errorMessage: 'Unable to delete ' + data.catalogType + ' id: ' + data.itemId + '. Check if it is in use'
+               });
+       }
+
+       selectCatalogItem(item = {}) {
+               SelectionManager.select(item);
+       }
+
+       catalogItemMetaDataChanged(item) {
+               let requiresSave = false;
+               const catalogs = this.getCatalogs().map(catalog => {
+                       if (catalog.id === item.uiState.catalogId) {
+                               catalog.descriptors = catalog.descriptors.map(d => {
+                                       if (d.id === item.id) {
+                                               // compare just the catalog uiState data (id, name, short-name, description, etc.)
+                                               const modified = !areCatalogItemsMetaDataEqual(d, item);
+                                               if (modified) {
+                                                       if (d.uiState['instance-ref-count'] > 0) {
+                                                               console.log('cannot edit NSD/VNFD with references to instantiated Network Services');
+                                                               ComposerAppActions.showError.defer({
+                                                                       errorMessage: 'Cannot edit NSD/VNFD with references to instantiated Network Services'
+                                                               });
+                                                               return _.cloneDeep(d);
+                                                       } else {
+                                                               item.uiState.modified = modified;
+                                                               requiresSave = true;
+                                                               this.addSnapshot(item);
+                                                       }
+                                               }
+                                               return item;
+                                       }
+                                       return d;
+                               });
+                       }
+                       return catalog;
+               });
+               if (requiresSave) {
+                       this.setState({catalogs: catalogs, requiresSave: true});
+               }
+       }
+
+       catalogItemDescriptorChanged(itemDescriptor) {
+               // when a descriptor object is modified in the canvas we have to update the catalog
+               const catalogId = itemDescriptor.uiState.catalogId;
+               const catalogs = this.getCatalogs().map(catalog => {
+                       if (catalog.id === catalogId) {
+                               // find the catalog
+                               const descriptorId = itemDescriptor.id;
+                               // replace the old descriptor with the updated one
+                               catalog.descriptors = catalog.descriptors.map(d => {
+                                       if (d.id === descriptorId) {
+                                               if (d.uiState['instance-ref-count'] > 0) {
+                                                       console.log('cannot edit NSD/VNFD with references to instantiated Network Services');
+                                                       ComposerAppActions.showError.defer({
+                                                               errorMessage: 'Cannot edit NSD/VNFD with references to instantiated Network Services'
+                                                       });
+                                                       return _.cloneDeep(d);
+                                               } else {
+                                                       itemDescriptor.model.uiState.modified = true;
+                                                       this.addSnapshot(itemDescriptor.model);
+                                                       return itemDescriptor.model;
+                                               }
+                                       }
+                                       return d;
+                               });
+                       }
+                       return catalog;
+               });
+               this.setState({catalogs: catalogs, requiresSave: true})
+       }
+
+       deleteSelectedCatalogItem() {
+               SelectionManager.getSelections().forEach(selectedId => {
+                       const item = this.getCatalogItemByUid(selectedId);
+                       if (item) {
+                               this.deleteCatalogItem(item);
+                       }
+               });
+               SelectionManager.clearSelectionAndRemoveOutline();
+       }
+
+       deleteCatalogItem(item) {
+               const snapshot = JSON.stringify(item);
+               function confirmDeleteCancel(event) {
+                       undo();
+                       event.preventDefault();
+                       ModalOverlayActions.hideModalOverlay();
+               }
+               const remove = () => {
+                       // item is deleted or does not exist on server, so remove from ui
+                       this.removeCatalogItem(item);
+                       this.setState({catalogs: this.getCatalogs()});
+                       const activeItem = ComposerAppStore.getState().item;
+                       if (activeItem && activeItem.id === item.id) {
+                               CatalogItemsActions.editCatalogItem.defer(null);
+                       }
+                       ModalOverlayActions.hideModalOverlay();
+               };
+               const undo = () => {
+                       // item failed to delete on server so revert ui
+                       const revertTo = JSON.parse(snapshot);
+                       this.updateCatalogItem(revertTo);
+                       const activeItem = ComposerAppStore.getState().item;
+                       if (activeItem && activeItem.id === revertTo.id) {
+                               SelectionManager.select(activeItem);
+                               CatalogItemsActions.editCatalogItem.defer(revertTo);
+                               SelectionManager.refreshOutline();
+                       }
+               };
+               if (item) {
+                       if (item.uiState.isNew) {
+                               CatalogDataStore.confirmDelete(remove, confirmDeleteCancel);
+                       } else {
+                               if (item.uiState['instance-ref-count'] > 0) {
+                                       console.log('cannot delete NSD/VNFD with references to instantiated Network Services');
+                                       ComposerAppActions.showError.defer({
+                                               errorMessage: 'Cannot delete NSD/VNFD with references to instantiated Network Services'
+                                       });
+                                       undo();
+                               } else {
+                                       const confirmDeleteOK = event => {
+                                               event.preventDefault();
+                                               item.uiState.deleted = true;
+                                               this.setState({catalogs: this.getCatalogs()});
+                                               ModalOverlayActions.showModalOverlay.defer();
+                                               this.getInstance().deleteCatalogItem(item.uiState.type, item.id)
+                                                       .then(remove, undo)
+                                                       .then(ModalOverlayActions.hideModalOverlay, ModalOverlayActions.hideModalOverlay)
+                                                       .catch(function() {
+                                                               console.log('overcoming ES6 unhandled rejection red herring');
+                                                       });
+                                       };
+                                       CatalogDataStore.confirmDelete(confirmDeleteOK, confirmDeleteCancel);
+                               }
+                       }
+               }
+       }
+
+       static confirmDelete(onClickYes, onClickCancel) {
+               ModalOverlayActions.showModalOverlay.defer((
+                       <div className="actions panel">
+                               <div className="panel-header">
+                                       <h1>Delete the selected catalog item?</h1>
+                               </div>
+                               <div className="panel-body">
+                                       <a className="action confirm-yes primary-action Button" onClick={onClickYes}>Yes, delete selected catalog item</a>
+                                       <a className="action cancel secondary-action Button" onClick={onClickCancel}>No, cancel</a>
+                               </div>
+                       </div>
+               ));
+       }
+
+       createCatalogItem(type = 'nsd') {
+               const model = DescriptorModelMetaFactory.createModelInstanceForType(type);
+               if (model) {
+                       const newItem = this.addNewItemToCatalog(model);
+                       newItem.uiState.isNew = true;
+                       newItem.uiState.modified = true;
+                       newItem.uiState['instance-ref-count'] = 0;
+                       // open the new model for editing in the canvas/details panels
+                       setTimeout(() => {
+                               this.selectCatalogItem(newItem);
+                               CatalogItemsActions.editCatalogItem.defer(newItem);
+                       }, 200);
+               }
+       }
+
+       duplicateSelectedCatalogItem() {
+               const item = this.getFirstSelectedCatalogItem();
+               if (item) {
+                       const newItem = _.cloneDeep(item);
+                       newItem.name = newItem.name + ' Copy';
+                       const nsd = this.addNewItemToCatalog(newItem);
+                       this.selectCatalogItem(nsd);
+                       nsd.uiState.isNew = true;
+                       nsd.uiState.modified = true;
+                       nsd.uiState['instance-ref-count'] = 0;
+                       // note duplicated items get a new id, map the layout position
+                       // of the old id to the new id in order to preserve the layout
+                       if (nsd.uiState.containerPositionMap) {
+                               nsd.uiState.containerPositionMap[nsd.id] = nsd.uiState.containerPositionMap[item.id];
+                               delete nsd.uiState.containerPositionMap[item.id];
+                       }
+                       setTimeout(() => {
+                               this.selectCatalogItem(nsd);
+                               CatalogItemsActions.editCatalogItem.defer(nsd);
+                       }, 200);
+               }
+       }
+
+       addSnapshot(item) {
+               if (item) {
+                       if (!this.snapshots[item.id]) {
+                               this.snapshots[item.id] = [];
+                       }
+                       this.snapshots[item.id].push(JSON.stringify(item));
+               }
+       }
+
+       resetSnapshots(item) {
+               if (item) {
+                       this.snapshots[item.id] = [];
+                       this.addSnapshot(item);
+               }
+       }
+
+       editCatalogItem(item) {
+               if (item) {
+                       this.addSnapshot(item);
+                       // replace the given item in the catalog
+                       const catalogs = this.getCatalogs().map(catalog => {
+                               catalog.descriptors = catalog.descriptors.map(d => {
+                                       // note only one item can be "open" at a time
+                                       // so remove the flag from all the other items
+                                       d.uiState.isOpenForEdit = (d.id === item.id);
+                                       if (d.uiState.isOpenForEdit) {
+                                               return item;
+                                       }
+                                       return d;
+                               });
+                               return catalog;
+                       });
+                       this.setState({catalogs: catalogs});
+                       this.catalogItemMetaDataChanged(item);
+               }
+       }
+
+       cancelCatalogItemChanges() {
+               const activeItem = ComposerAppStore.getState().item;
+               if (activeItem) {
+                       const snapshots = this.snapshots[activeItem.id];
+                       if (snapshots.length) {
+                               const revertTo = JSON.parse(snapshots[0]);
+                               this.updateCatalogItem(revertTo);
+                               // TODO should the cancel action clear the undo/redo stack back to the beginning?
+                               this.resetSnapshots(revertTo);
+                               this.setState({requiresSave: false});
+                               CatalogItemsActions.editCatalogItem.defer(revertTo);
+                       }
+               }
+       }
+
+       saveCatalogItem() {
+               const activeItem = ComposerAppStore.getState().item;
+               if (activeItem) {
+                       if (activeItem.uiState['instance-ref-count'] > 0) {
+                               console.log('cannot save NSD/VNFD with references to instantiated Network Services');
+                               ComposerAppActions.showError.defer({
+                                       errorMessage: 'Cannot save NSD/VNFD with references to instantiated Network Services'
+                               });
+                               return;
+                       }
+                       const success = () => {
+                               delete activeItem.uiState.isNew;
+                               delete activeItem.uiState.modified;
+                               this.updateCatalogItem(activeItem);
+                               // TODO should the save action clear the undo/redo stack back to the beginning?
+                               this.resetSnapshots(activeItem);
+                               ModalOverlayActions.hideModalOverlay.defer();
+                               CatalogItemsActions.editCatalogItem.defer(activeItem);
+                       };
+                       const failure = () => {
+                               ModalOverlayActions.hideModalOverlay.defer();
+                               CatalogItemsActions.editCatalogItem.defer(activeItem);
+                       };
+                       const exception = () => {
+                               console.warn('unable to save catalog item', activeItem);
+                               ModalOverlayActions.hideModalOverlay.defer();
+                               CatalogItemsActions.editCatalogItem.defer(activeItem);
+                       };
+                       ModalOverlayActions.showModalOverlay.defer();
+                       this.getInstance().saveCatalogItem(activeItem).then(success, failure).catch(exception);
+               }
+       }
+
+       exportSelectedCatalogItems(draggedItem) {
+               const onSelectFormat = (selectedFormat, event) => {
+                       this.setState({
+                               selectedFormat: selectedFormat
+                       });
+               };
+
+               const onSelectGrammar = (selectedGrammar, event) => {
+                       this.setState({
+                               selectedGrammar: selectedGrammar
+                       });
+               }
+
+
+               const onCancel = () => {
+                       this.resetSelectionState();
+                       ModalOverlayActions.hideModalOverlay();
+               };
+
+               const onDownload = (event) => {
+                       CatalogPackageManagerActions.downloadCatalogPackage.defer({
+                               selectedItems: selectedItems,
+                               selectedFormat: this.selectedFormat,
+                               selectedGrammar: this.selectedGrammar
+                       });
+                       this.resetSelectionState();
+                       ModalOverlayActions.hideModalOverlay();
+                       return;
+               }
+
+               if (draggedItem) {
+                       // if item is given make sure it is also selected
+                       //draggedItem.uiState.selected = true;
+                       SelectionManager.addSelection(draggedItem);
+                       this.updateCatalogItem(draggedItem);
+               }
+               // collect the selected items and delegate to the catalog package manager action creator
+               const selectedItems = this.getAllSelectedCatalogItems();
+               if (selectedItems.length) {
+                       CatalogDataStore.chooseExportFormat(onSelectFormat, onSelectGrammar, onDownload, onCancel);
+               }
+       }
+
+       static chooseExportFormat(onSelectFormat, onSelectGrammar, onDownload, onCancel) {
+               ModalOverlayActions.showModalOverlay.defer(
+                       <ExportSelectorDialog
+                               onSelectFormat={onSelectFormat}
+                               onSelectGrammar={onSelectGrammar}
+                               onCancel={onCancel}
+                               onDownload={onDownload}
+                               currentlySelectedFormat='mano'
+                               currentlySelectedGrammar='osm'
+                       />
+               );
+       }
+
+}
+
+export default alt.createStore(CatalogDataStore, 'CatalogDataStore');
diff --git a/skyquake/plugins/composer/src/src/stores/CatalogPackageManagerStore.js b/skyquake/plugins/composer/src/src/stores/CatalogPackageManagerStore.js
new file mode 100644 (file)
index 0000000..733e938
--- /dev/null
@@ -0,0 +1,243 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import alt from '../alt'
+import guid from '../libraries/guid'
+import numeral from 'numeral'
+import moment from 'moment'
+import utils from '../libraries/utils'
+import CatalogPackageManagerSource from '../sources/CatalogPackageManagerSource'
+import CatalogPackageManagerActions from '../actions/CatalogPackageManagerActions'
+import CatalogDataSource from '../sources/CatalogDataSource'
+
+import imgDownload from '../../../node_modules/open-iconic/svg/cloud-download.svg'
+import imgOnboard from '../../../node_modules/open-iconic/svg/cloud-upload.svg'
+import imgUpdate from '../../../node_modules/open-iconic/svg/data-transfer-upload.svg'
+
+const defaults = {
+       downloadPackage: {
+               id: '',
+               name: '',
+               icon: imgDownload,
+               catalogItems: [],
+               transactionId: '',
+               progress: 0,
+               message: 'Requesting catalog package export...',
+               pending: false,
+               success: false,
+               error: false,
+               url: '',
+               urlValidUntil: ''
+       },
+       checkStatusDelayInSeconds: 2,
+       downloadUrlTimeToLiveInMinutes: 5
+};
+
+const exception = function ignoreException() {};
+
+const packagePropertyNames = Object.keys(defaults.downloadPackage);
+
+function getCatalogPackageManagerServerOrigin() {
+       return utils.getSearchParams(window.location).upload_server + ':4567';
+}
+
+function delayStatusCheck(statusCheckFunction, catalogPackage) {
+       if (!catalogPackage.checkStatusTimeoutId) {
+               const delayCallback = function () {
+                       delete catalogPackage.checkStatusTimeoutId;
+                       statusCheckFunction(catalogPackage).catch(exception);
+               };
+               catalogPackage.checkStatusTimeoutId = _.delay(delayCallback, defaults.checkStatusDelayInSeconds * 1000);
+       }
+}
+
+class CatalogPackageManagerStore {
+
+       constructor() {
+
+               this.packages = [];
+
+               this.registerAsync(CatalogDataSource);
+               this.registerAsync(CatalogPackageManagerSource);
+               this.bindAction(CatalogPackageManagerActions.REMOVE_CATALOG_PACKAGE, this.removeCatalogPackage);
+               this.bindAction(CatalogPackageManagerActions.DOWNLOAD_CATALOG_PACKAGE, this.downloadCatalogPackage);
+               this.bindAction(CatalogPackageManagerActions.DOWNLOAD_CATALOG_PACKAGE_STATUS_UPDATED, this.onDownloadCatalogPackageStatusUpdated);
+               this.bindAction(CatalogPackageManagerActions.DOWNLOAD_CATALOG_PACKAGE_ERROR, this.onDownloadCatalogPackageError);
+               this.bindAction(CatalogPackageManagerActions.UPLOAD_CATALOG_PACKAGE, this.uploadCatalogPackage);
+               this.bindAction(CatalogPackageManagerActions.UPLOAD_CATALOG_PACKAGE_STATUS_UPDATED, this.onUploadCatalogPackageStatusUpdated);
+               this.bindAction(CatalogPackageManagerActions.UPLOAD_CATALOG_PACKAGE_ERROR, this.onUploadCatalogPackageError);
+
+       }
+
+       addPackage(catalogPackage) {
+               const packages = [catalogPackage].concat(this.packages);
+               this.setState({packages: packages});
+       }
+
+       updatePackage(catalogPackage) {
+               const packages = this.packages.map(d => {
+                       if (d.id === catalogPackage.id) {
+                               return Object.assign({}, d, catalogPackage);
+                       }
+                       return d;
+               });
+               this.setState({packages: packages});
+       }
+
+       removeCatalogPackage(catalogPackage) {
+               const packages = this.packages.filter(d => d.id !== catalogPackage.id);
+               this.setState({packages: packages});
+       }
+
+       uploadCatalogPackage(file) {
+               file.id = file.id || guid();
+               const catalogPackage = _.pick(file, packagePropertyNames);
+               catalogPackage.icon = file.riftAction === 'onboard' ? imgOnboard : imgUpdate;
+               catalogPackage.type = 'upload';
+               this.addPackage(catalogPackage);
+               // note DropZone.js handles the async upload so we don't have to invoke any async action creators
+       }
+
+       onUploadCatalogPackageStatusUpdated(response) {
+               const upload = updateStatusInfo(response);
+               this.updatePackage(upload);
+               // if pending with no transaction id - do nothing
+               // bc DropZone.js will notify upload progress
+               if (upload.pending && upload.transactionId) {
+                       delayStatusCheck(this.getInstance().requestCatalogPackageUploadStatus, upload);
+               } else if (upload.success) {
+                       this.getInstance().loadCatalogs();
+               }
+       }
+
+       onUploadCatalogPackageError(response) {
+               console.warn('onUploadCatalogPackageError', response);
+               const catalogPackage = updateStatusInfo(response);
+               this.updatePackage(catalogPackage);
+       }
+
+       downloadCatalogPackage(data) {
+               let catalogItems = data['selectedItems'] || [];
+               let format = data['selectedFormat'] || 'mano';
+               let grammar = data['selectedGrammar'] || 'osm';
+               if (catalogItems.length) {
+                       const catalogPackage = Object.assign({}, defaults.downloadPackage, {id: guid()});
+                       catalogPackage.name = catalogItems[0].name;
+                       catalogPackage.type = 'download';
+                       if (catalogItems.length > 1) {
+                               catalogPackage.name += ' (' + catalogItems.length + ' items)';
+                       }
+                       catalogPackage.ids = catalogItems.map(d => d.id).sort().toString();
+                       catalogPackage.catalogItems = catalogItems;
+                       this.addPackage(catalogPackage);
+                       this.getInstance().requestCatalogPackageDownload(catalogPackage, format, grammar).catch(exception);
+               }
+       }
+
+       onDownloadCatalogPackageStatusUpdated(response) {
+               const download = updateStatusInfo(response);
+               this.updatePackage(download);
+               if (download.pending) {
+                       delayStatusCheck(this.getInstance().requestCatalogPackageDownloadStatus, download);
+               }
+       }
+
+       onDownloadCatalogPackageError(response) {
+               console.warn('onDownloadCatalogPackageError', response);
+               const catalogPackage = updateStatusInfo(response);
+               this.updatePackage(catalogPackage);
+       }
+
+}
+
+function calculateUploadProgressMessage(size = 0, progress = 0, bytesSent = 0) {
+       const amount = parseFloat(progress) || 0;
+       const loaded = amount === 100 ? size : size * amount / 100;
+       let progressText;
+       if (amount === 100) {
+               progressText = numeral(loaded).format('0.0b') + ' loaded ';
+       } else if (typeof amount === 'number' && amount != 0) {
+               progressText = numeral(bytesSent).format('0.0b') + ' out of ' + numeral(size).format('0.0b');
+       } else {
+               progressText = progress;
+       }
+       return progressText;
+}
+
+function updateStatusInfo(response) {
+       // returns the catalogPackage object with the status fields updated based on the server response
+       const statusInfo = {
+               pending: false,
+               success: false,
+               error: false
+       };
+       const responseData = response.data;
+       const catalogPackage = response.state;
+       switch(responseData.status) {
+       case 'upload-progress':
+               statusInfo.pending = true;
+               statusInfo.progress = parseFloat(responseData.progress) || 0;
+               statusInfo.message = calculateUploadProgressMessage(catalogPackage.size, responseData.progress, responseData.bytesSent);
+               break;
+       case 'upload-success':
+               statusInfo.pending = true;
+               statusInfo.progress = 100;
+               statusInfo.message = 'Upload completed.';
+               statusInfo.transactionId = responseData.transaction_id;
+               break;
+       case 'upload-error':
+               statusInfo.error = true;
+               statusInfo.message = responseData.message;
+               break;
+       case 'download-requested':
+               statusInfo.pending = true;
+               statusInfo.progress = 25;
+               statusInfo.transactionId = responseData.transaction_id;
+               break;
+       case 'pending':
+               statusInfo.pending = true;
+               statusInfo.progress = 50;
+               statusInfo.message = responseData.events[responseData.events.length - 1].text;
+               break;
+       case 'success':
+               statusInfo.success = true;
+               statusInfo.progress = 100;
+               statusInfo.message = responseData.events[responseData.events.length - 1].text;
+               if (catalogPackage.type === 'download') {
+                       statusInfo.urlValidUntil = moment().add(defaults.downloadUrlTimeToLiveInMinutes, 'minutes').toISOString();
+                       if (responseData.filename) {
+                               statusInfo.url = getCatalogPackageManagerServerOrigin() + '/api/export/' + responseData.filename;
+                       } else {
+                               statusInfo.url = getCatalogPackageManagerServerOrigin() + '/api/export/' + catalogPackage.transactionId + '.tar.gz';
+                       }
+               }
+               break;
+       case 'failure':
+               statusInfo.error = true;
+               statusInfo.message = responseData.errors[0].value;
+               break;
+       default:
+               throw new ReferenceError('a status of "request", "success", "failure", "pending", "upload-completed", "upload-error", "download-requested", "upload-progress", "upload-action" is required');
+       }
+       return Object.assign({}, catalogPackage, statusInfo);
+}
+
+export default alt.createStore(CatalogPackageManagerStore, 'CatalogPackageManagerStore');
diff --git a/skyquake/plugins/composer/src/src/stores/CatalogPanelStore.js b/skyquake/plugins/composer/src/src/stores/CatalogPanelStore.js
new file mode 100644 (file)
index 0000000..ad973d7
--- /dev/null
@@ -0,0 +1,48 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import alt from '../alt'
+import CatalogPanelTrayActions from '../actions/CatalogPanelTrayActions'
+
+class CatalogPanelStore {
+
+       constructor() {
+               this.isTrayOpen = 0;
+               this.bindAction(CatalogPanelTrayActions.OPEN, this.openTray);
+               this.bindAction(CatalogPanelTrayActions.CLOSE, this.closeTray);
+               this.bindAction(CatalogPanelTrayActions.TOGGLE_OPEN_CLOSE, this.toggleTrayOpenClose);
+       }
+
+       openTray() {
+               // note incrementing integer will force a state change needed to redraw tray drop zones
+               this.setState({isTrayOpen: this.isTrayOpen + 1});
+       }
+
+       closeTray() {
+               this.setState({isTrayOpen: 0});
+       }
+
+       toggleTrayOpenClose() {
+               this.setState({isTrayOpen: this.isTrayOpen === 0 ? 1 : 0});
+       }
+
+}
+
+export default alt.createStore(CatalogPanelStore, 'CatalogPanelStore');
diff --git a/skyquake/plugins/composer/src/src/stores/ComposerAppStore.js b/skyquake/plugins/composer/src/src/stores/ComposerAppStore.js
new file mode 100644 (file)
index 0000000..67e8e8d
--- /dev/null
@@ -0,0 +1,402 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+import alt from '../alt'
+import UID from '../libraries/UniqueId'
+import DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'
+import PanelResizeAction from '../actions/PanelResizeAction'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import CanvasEditorActions from '../actions/CanvasEditorActions'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import CatalogFilterActions from '../actions/CatalogFilterActions'
+import CanvasPanelTrayActions from '../actions/CanvasPanelTrayActions'
+import SelectionManager from '../libraries/SelectionManager'
+import CatalogDataStore from '../stores/CatalogDataStore'
+import isFullScreen from '../libraries/isFullScreen'
+
+const getDefault = (name, defaultValue) => {
+       const val = window.localStorage.getItem('defaults-' + name);
+       if (val) {
+               if (_.isNumber(val)) {
+                       if (val < 0) {
+                               return setDefault(name, 0);
+                       }
+               }
+               return Number(val);
+       }
+       setDefault(name, defaultValue);
+       return defaultValue;
+};
+
+const setDefault = (name, defaultValue) => {
+       window.localStorage.setItem('defaults-' + name, defaultValue);
+       return defaultValue;
+};
+
+/* the top and bottom positions are managed by css; requires div to be display: absolute*/
+const defaults = {
+       left: getDefault('catalog-panel-start-width', 300),
+       right: getDefault('details-panel-start-width', 365),
+       bottom: 25 + getDefault('defaults-forwarding-graphs-panel-start-height', 0),
+       showMore: false,
+       zoom: getDefault('zoom', 100),
+       filterCatalogBy: 'nsd',
+       defaultPanelTrayOpenZoom: (() => {
+               let zoom = parseFloat(getDefault('panel-tray-zoom', 75));
+               if (isNaN(zoom)) {
+                       zoom = 75;
+               }
+               zoom = Math.min(100, zoom);
+               zoom = Math.max(25, zoom);
+               setDefault('panel-tray-zoom', zoom);
+               return zoom;
+       })()
+};
+
+const autoZoomCanvasScale = d3.scale.linear().domain([0, 300]).range([100, 50]).clamp(true);
+
+const uiTransientState = {};
+
+class ComposerAppStore {
+
+       constructor() {
+               // the catalog item currently being edited in the composer
+               this.item = null;
+               // the left and right sides of the canvas area
+               this.layout = {
+                       left: defaults.left,
+                       right: defaults.right,
+                       bottom: defaults.bottom
+               };
+               uiTransientState.restoreLayout = this.layout;
+               this.zoom = defaults.zoom;
+               this.showMore = defaults.showMore;
+               this.filterCatalogByTypeValue = defaults.filterCatalogBy;
+               // transient ui state
+               this.drag = null;
+               this.message = '';
+               this.messageType = '';
+               this.showJSONViewer = false;
+               this.showClassifiers = {};
+               this.editPathsMode = false;
+               this.fullScreenMode = false;
+               this.bindListeners({
+                       onResize: PanelResizeAction.RESIZE,
+                       editCatalogItem: CatalogItemsActions.EDIT_CATALOG_ITEM,
+                       catalogItemMetaDataChanged: CatalogItemsActions.CATALOG_ITEM_META_DATA_CHANGED,
+                       catalogItemDescriptorChanged: CatalogItemsActions.CATALOG_ITEM_DESCRIPTOR_CHANGED,
+                       toggleShowMoreInfo: CanvasEditorActions.TOGGLE_SHOW_MORE_INFO,
+                       showMoreInfo: CanvasEditorActions.SHOW_MORE_INFO,
+                       showLessInfo: CanvasEditorActions.SHOW_LESS_INFO,
+                       applyDefaultLayout: CanvasEditorActions.APPLY_DEFAULT_LAYOUT,
+                       addVirtualLinkDescriptor: CanvasEditorActions.ADD_VIRTUAL_LINK_DESCRIPTOR,
+                       addForwardingGraphDescriptor: CanvasEditorActions.ADD_FORWARDING_GRAPH_DESCRIPTOR,
+                       addVirtualDeploymentDescriptor: CanvasEditorActions.ADD_VIRTUAL_DEPLOYMENT_DESCRIPTOR,
+                       selectModel: ComposerAppActions.SELECT_MODEL,
+                       outlineModel: ComposerAppActions.OUTLINE_MODEL,
+                       showError: ComposerAppActions.SHOW_ERROR,
+                       clearError: ComposerAppActions.CLEAR_ERROR,
+                       setDragState: ComposerAppActions.SET_DRAG_STATE,
+                       filterCatalogByType: CatalogFilterActions.FILTER_BY_TYPE,
+                       setCanvasZoom: CanvasEditorActions.SET_CANVAS_ZOOM,
+                       showJsonViewer: ComposerAppActions.SHOW_JSON_VIEWER,
+                       closeJsonViewer: ComposerAppActions.CLOSE_JSON_VIEWER,
+                       toggleCanvasPanelTray: CanvasPanelTrayActions.TOGGLE_OPEN_CLOSE,
+                       openCanvasPanelTray: CanvasPanelTrayActions.OPEN,
+                       closeCanvasPanelTray: CanvasPanelTrayActions.CLOSE,
+                       enterFullScreenMode: ComposerAppActions.ENTER_FULL_SCREEN_MODE,
+                       exitFullScreenMode: ComposerAppActions.EXIT_FULL_SCREEN_MODE
+               });
+       }
+
+       onResize(e) {
+               if (e.type === 'resize-manager.resize.catalog-panel') {
+                       const layout = Object.assign({}, this.layout);
+                       layout.left = Math.max(0, layout.left - e.moved.x);
+                       if (layout.left !== this.layout.left) {
+                               this.setState({layout: layout});
+                       }
+               } else if (e.type === 'resize-manager.resize.details-panel') {
+                       const layout = Object.assign({}, this.layout);
+                       layout.right = Math.max(0, layout.right + e.moved.x);
+                       if (layout.right !== this.layout.right) {
+                               this.setState({layout: layout});
+                       }
+               } else if (/^resize-manager\.resize\.canvas-panel-tray/.test(e.type)) {
+                       const layout = Object.assign({}, this.layout);
+                       layout.bottom = Math.max(25, layout.bottom + e.moved.y);
+                       if (layout.bottom !== this.layout.bottom) {
+                               const zoom = autoZoomCanvasScale(layout.bottom) ;
+                               if (this.zoom !== zoom) {
+                                       this.setState({layout: layout, zoom: zoom});
+                               } else {
+                                       this.setState({layout: layout});
+                               }
+                       }
+               } else if (e.type !== 'resize') {
+                       console.log('no resize handler for ', e.type, '. Do you need to add a handler in ComposerAppStore::onResize()?')
+               }
+               SelectionManager.refreshOutline();
+       }
+
+       updateItem(item) {
+               if(!document.body.classList.contains('resizing')) {
+                       this.setState({item: _.cloneDeep(item)});
+               }
+               SelectionManager.refreshOutline();
+       }
+
+       editCatalogItem(item) {
+               if (item && item.uiState) {
+                       item.uiState.isOpenForEdit = true;
+                       if (item.uiState.type !== 'nsd') {
+                               this.closeCanvasPanelTray();
+                       }
+               }
+               SelectionManager.select(item);
+               this.updateItem(item);
+       }
+
+       catalogItemMetaDataChanged(item) {
+               this.updateItem(item);
+       }
+
+       catalogItemDescriptorChanged(itemDescriptor) {
+               this.catalogItemMetaDataChanged(itemDescriptor.model);
+       }
+
+       showMoreInfo() {
+               this.setState({showMore: true});
+       }
+
+       showLessInfo() {
+               this.setState({showMore: false});
+       }
+
+       showError(data) {
+               this.setState({message: data.errorMessage, messageType: 'error'});
+       }
+
+       clearError() {
+               this.setState({message: '', messageType: ''});
+       }
+
+       toggleShowMoreInfo() {
+               this.setState({showMore: !this.showMore});
+       }
+
+       applyDefaultLayout() {
+               if (this.item && this.item.uiState && this.item.uiState.containerPositionMap) {
+                       if (!_.isEmpty(this.item.uiState.containerPositionMap)) {
+                               this.item.uiState.containerPositionMap = {};
+                               CatalogItemsActions.catalogItemMetaDataChanged.defer(this.item);
+                       }
+               }
+       }
+
+       addVirtualLinkDescriptor(dropCoordinates = null) {
+               let vld;
+               if (this.item) {
+                       if (this.item.uiState.type === 'nsd') {
+                               const nsdc = DescriptorModelFactory.newNetworkService(this.item);
+                               vld = nsdc.createVld();
+                       } else if (this.item.uiState.type === 'vnfd') {
+                               const vnfd = DescriptorModelFactory.newVirtualNetworkFunction(this.item);
+                               vld = vnfd.createVld();
+                       }
+                       if (vld) {
+                               vld.uiState.dropCoordinates = dropCoordinates;
+                               SelectionManager.clearSelectionAndRemoveOutline();
+                               SelectionManager.addSelection(vld);
+                               this.updateItem(vld.getRoot().model);
+                               CatalogItemsActions.catalogItemDescriptorChanged.defer(vld.getRoot());
+                       }
+               }
+       }
+
+       addForwardingGraphDescriptor(dropCoordinates = null) {
+               if (this.item && this.item.uiState.type === 'nsd') {
+                       const nsdc = DescriptorModelFactory.newNetworkService(this.item);
+                       const fg = nsdc.createVnffgd();
+                       fg.uiState.dropCoordinates = dropCoordinates;
+                       SelectionManager.clearSelectionAndRemoveOutline();
+                       SelectionManager.addSelection(fg);
+                       this.updateItem(nsdc.model);
+                       CatalogItemsActions.catalogItemDescriptorChanged.defer(nsdc);
+               }
+       }
+
+       addVirtualDeploymentDescriptor(dropCoordinates = null) {
+               if (this.item.uiState.type === 'vnfd') {
+                       const vnfd = DescriptorModelFactory.newVirtualNetworkFunction(this.item);
+                       const vdu = vnfd.createVdu();
+                       vdu.uiState.dropCoordinates = dropCoordinates;
+                       SelectionManager.clearSelectionAndRemoveOutline();
+                       SelectionManager.addSelection(vdu);
+                       this.updateItem(vdu.getRoot().model);
+                       CatalogItemsActions.catalogItemDescriptorChanged.defer(vdu.getRoot());
+               }
+       }
+
+       selectModel(container) {
+               if (SelectionManager.select(container)) {
+                       const model = DescriptorModelFactory.isContainer(container) ? container.getRoot().model : container;
+                       this.catalogItemMetaDataChanged(model);
+               }
+       }
+
+       outlineModel(obj) {
+               const uid = UID.from(obj);
+               requestAnimationFrame(() => {
+                       SelectionManager.outline(Array.from(document.querySelectorAll(`[data-uid="${uid}"]`)));
+               });
+       }
+
+       clearSelection() {
+               SelectionManager.clearSelectionAndRemoveOutline();
+               this.catalogItemMetaDataChanged(this.item);
+       }
+
+       setDragState(dragState) {
+               this.setState({drag: dragState});
+       }
+
+       filterCatalogByType(typeValue) {
+               this.setState({filterCatalogByTypeValue: typeValue})
+       }
+
+       setCanvasZoom(zoom) {
+               this.setState({zoom: zoom});
+       }
+
+       showJsonViewer() {
+               this.setState({showJSONViewer: true});
+       }
+
+       closeJsonViewer() {
+               this.setState({showJSONViewer: false});
+       }
+
+       toggleCanvasPanelTray() {
+               const layout = this.layout;
+               if (layout.bottom > 25) {
+                       this.closeCanvasPanelTray();
+               } else {
+                       this.openCanvasPanelTray();
+               }
+       }
+
+       openCanvasPanelTray() {
+               const layout = {
+                       left: this.layout.left,
+                       right: this.layout.right,
+                       bottom: 300
+               };
+               const zoom = defaults.defaultPanelTrayOpenZoom;
+               if (this.zoom !== zoom) {
+                       this.setState({layout: layout, zoom: zoom, restoreZoom: this.zoom});
+               } else {
+                       this.setState({layout: layout});
+               }
+       }
+
+       closeCanvasPanelTray() {
+               const layout = {
+                       left: this.layout.left,
+                       right: this.layout.right,
+                       bottom: 25
+               };
+               const zoom = this.restoreZoom || autoZoomCanvasScale(layout.bottom);
+               if (this.zoom !== zoom) {
+                       this.setState({layout: layout, zoom: zoom, restoreZoom: null});
+               } else {
+                       this.setState({layout: layout, restoreZoom: null});
+               }
+       }
+
+       enterFullScreenMode() {
+
+               /**
+                * https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
+                * This is an experimental api but works our target browsers and ignored by others
+                */
+               const eventNames = ['fullscreenchange', 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange'];
+
+               const appRoot = document.body;//.getElementById('RIFT_wareLaunchpadComposerAppRoot');
+
+               const comp = this;
+
+               function onFullScreenChange() {
+
+                       if (isFullScreen()) {
+                               const layout = comp.layout;
+                               const restoreLayout = _.cloneDeep(layout);
+                               uiTransientState.restoreLayout = restoreLayout;
+                               layout.left = 0;
+                               layout.right = 0;
+                               comp.setState({fullScreenMode: true, layout: layout, restoreLayout: restoreLayout});
+                       } else {
+                               comp.setState({fullScreenMode: false, layout: uiTransientState.restoreLayout});
+                       }
+
+               }
+
+               if (this.fullScreenMode === false) {
+
+                       if (appRoot.requestFullscreen) {
+                               appRoot.requestFullscreen();
+                       } else if (appRoot.msRequestFullscreen) {
+                               appRoot.msRequestFullscreen();
+                       } else if (appRoot.mozRequestFullScreen) {
+                               appRoot.mozRequestFullScreen();
+                       } else if (appRoot.webkitRequestFullscreen) {
+                               appRoot.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+                       }
+
+                       eventNames.map(name => {
+                               document.removeEventListener(name, onFullScreenChange);
+                               document.addEventListener(name, onFullScreenChange);
+                       });
+
+               }
+
+       }
+
+       exitFullScreenMode() {
+
+               if (document.exitFullscreen) {
+                       document.exitFullscreen();
+               } else if (document.msExitFullscreen) {
+                       document.msExitFullscreen();
+               } else if (document.mozCancelFullScreen) {
+                       document.mozCancelFullScreen();
+               } else if (document.webkitExitFullscreen) {
+                       document.webkitExitFullscreen();
+               }
+
+               this.setState({fullScreenMode: false});
+
+       }
+
+}
+
+export default alt.createStore(ComposerAppStore, 'ComposerAppStore');
diff --git a/skyquake/plugins/composer/src/src/stores/ModalOverlayStore.js b/skyquake/plugins/composer/src/src/stores/ModalOverlayStore.js
new file mode 100644 (file)
index 0000000..5595241
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 10/14/15.
+ */
+'use strict';
+
+import alt from '../alt'
+import React from 'react'
+import ModalOverlayActions from '../actions/ModalOverlayActions'
+import LoadingIndicator from '../components/LoadingIndicator'
+
+class ModalOverlayStore {
+
+       constructor() {
+               this.ui = <LoadingIndicator/>;
+               this.visible = false;
+               this.bindActions(ModalOverlayActions);
+       }
+
+       showModalOverlay(ui = <LoadingIndicator/>) {
+               this.setState({visible: true, ui: ui});
+       }
+
+       hideModalOverlay() {
+               this.setState({visible: false, ui: null});
+       }
+
+}
+
+ModalOverlayStore.config = {
+       onSerialize: function() {
+               return {};
+       }
+};
+
+export default alt.createStore(ModalOverlayStore, 'ModalOverlayStore');
diff --git a/skyquake/plugins/composer/src/src/stores/RiftHeaderStore.js b/skyquake/plugins/composer/src/src/stores/RiftHeaderStore.js
new file mode 100644 (file)
index 0000000..7506f51
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by kkashalk on 11/10/15.
+ */
+
+ // NOTE: THIS FILE HAS BEEN DEPRECATED AND WILL BE REMOVED
+
+'use strict';
+
+import alt from '../alt'
+import React from 'react'
+import utils from '../libraries/utils'
+import RiftHeaderActions from '../actions/RiftHeaderActions'
+import RiftHeaderSource from '../sources/RiftHeaderSource'
+import CatalogDataSource from '../sources/CatalogDataSource'
+import CatalogDataSourceActions from '../actions/CatalogDataSourceActions'
+
+class RiftHeaderStore {
+
+       constructor() {
+               let mgmt_domain_name = unescape(utils.getSearchParams(window.location).mgmt_domain_name);
+               if(mgmt_domain_name.toUpperCase() == 'DASHBOARD' || mgmt_domain_name.toUpperCase() == 'UNDEFINED') {
+                       mgmt_domain_name = '';
+               } else {
+                       mgmt_domain_name = ' : ' + mgmt_domain_name;
+               }
+               this.headerTitle = 'Launchpad' + mgmt_domain_name;
+               this.nsdCount = 0;
+               this.isStandAlone = false;
+               this.registerAsync(CatalogDataSource);
+               this.registerAsync(RiftHeaderSource);
+               this.bindAction(CatalogDataSourceActions.LOAD_CATALOGS_SUCCESS, this.loadCatalogsSuccess);
+               this.bindActions(RiftHeaderActions);
+       }
+       requestLaunchpadConfigSuccess(data) {
+               this.setState({
+                       isStandAlone: true,
+                       headerTitle: 'Launchpad'
+               });
+       }
+       loadCatalogsSuccess(data) {
+               let self = this; {}
+               let descriptorCount = 0;
+               data.data.forEach((catalog) => {
+                       descriptorCount += catalog.descriptors.length;
+               });
+
+               self.setState({
+                       descriptorCount: descriptorCount
+               });
+       }
+}
+
+export default alt.createStore(RiftHeaderStore, 'RiftHeaderStore');
diff --git a/skyquake/plugins/composer/src/src/styles/Animations.scss b/skyquake/plugins/composer/src/src/styles/Animations.scss
new file mode 100644 (file)
index 0000000..838ef5c
--- /dev/null
@@ -0,0 +1,47 @@
+
+.-with-animations {
+       -webkit-animation-duration: 200ms;
+       animation-duration: 200ms;
+       -webkit-animation-fill-mode: both;
+       animation-fill-mode: both;
+}
+
+.deleteItemAnimation {
+       -webkit-animation-name: deleteItemKeyframes;
+       animation-name: deleteItemKeyframes;
+       position: fixed;
+}
+
+@-webkit-keyframes deleteItemKeyframes {
+       0% {
+               opacity: 1;
+               -webkit-filter: blur(0px);
+       }
+
+       50% {
+               opacity: 0.5;
+               -webkit-filter: blur(10px);
+       }
+
+       100% {
+               opacity: 0;
+               -webkit-filter: blur(20px);
+       }
+}
+
+@keyframes deleteItemKeyframes {
+       0% {
+               opacity: 1;
+               -webkit-filter: blur(0px);
+       }
+
+       50% {
+               opacity: 0.5;
+               -webkit-filter: blur(10px);
+       }
+
+       100% {
+               opacity: 0;
+               -webkit-filter: blur(20px);
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/AppRoot.scss b/skyquake/plugins/composer/src/src/styles/AppRoot.scss
new file mode 100644 (file)
index 0000000..92e216e
--- /dev/null
@@ -0,0 +1,131 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "main";
+@import "FullScreen";
+.AppRoot {
+    display: flex;
+    flex: 1;
+    position: relative;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    left: 0;
+    height:100%;
+    /* General */
+    .crouton {
+        color: #FFF;
+        line-height: 140%;
+        border-radius: 3px;
+        position: fixed;
+        top: 0px;
+        left: 0px;
+        right: 0px;
+        max-width: 700px;
+        width: 90%;
+        text-align: center;
+        z-index: 99999;
+        margin: 0 auto;
+        div {
+            padding: 20px;
+            &.info {
+                background-color: #1F8DD6;
+            }
+            &.success {
+                background-color: #50CD84;
+            }
+            &.warning {
+                background-color: #FF8859;
+            }
+            &.error {
+                background-color: #FF5F5F;
+            }
+            span {
+                display: block;
+                margin-bottom: 0;
+                margin-left: 0px;
+            }
+            .buttons {
+                text-align: right;
+                button {
+                    &.btn, &.retry, &.close, &.cancel, &.ignore {
+                        padding: 0px;
+                        border: 1px solid transparent;
+                        border-radius: 3px;
+                    }
+                    &:hover {
+                        opacity: .75;
+                    }
+                    &.retry {
+                        border-color: #FFF;
+                    }
+                    &.btn {
+                        &.close {
+                            border-color: #FF5F5F;
+                            margin-left: 10px;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    .AppHeader {
+        position: absolute;
+        top: 0;
+        right: 0;
+        left: 0;
+        height: 0;
+    }
+    .AppBody {
+               @extend .panel;
+               position: absolute;
+        top: 0px;
+        right: 20px;
+        bottom: 20px;
+        left: 20px;
+        background-color: #e5e5e5;
+        margin: 0.5rem 1rem;
+    }
+    .corner-accent {
+        border: 1px solid #000000;
+        display: block;
+        height: 4px;
+        position: absolute;
+        width: 4px;
+               z-index: 999;
+    }
+    .corner-accent.top {
+        border-bottom: 0 none;
+        top: 6px;
+    }
+       .corner-accent.bottom {
+               border-top: 0 none;
+               bottom: 27px;
+       }
+    .corner-accent.right {
+        border-left: 0 none;
+        right: 35px;
+    }
+    .corner-accent.left {
+        border-right: 0 none;
+        left: 35px;
+    }
+    button:focus {
+        outline: 0;
+    }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/Button.scss b/skyquake/plugins/composer/src/src/styles/Button.scss
new file mode 100644 (file)
index 0000000..8220f0a
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+.Button {
+       display: inline-block;
+       vertical-align: middle;
+       margin: 2px;
+       border: 1px solid transparent;
+       border-radius: 3px;
+       padding: 3px 6px;
+       &:hover {
+               cursor: pointer;
+       }
+       &.primary-action {
+               border-color: rgba(34, 34, 34, 0.38);
+               box-shadow: 0px 0px 8px 0px rgba(255, 255, 255, 0.65);
+       }
+       &:hover {
+               color: #ffffff;
+               border-color: rgba(34, 34, 34, 0.38);
+               box-shadow: 0px 0px 8px 0px rgba(255, 255, 255, 0.65);
+               background-color: #7E9BC1;
+       }
+       &:active, &:visited{
+               background-color:#4C5E74;
+       }
+       img {
+               width: 20px !important;
+               height: 20px !important;
+               margin: 0;
+               box-shadow: none;
+               vertical-align: middle;
+       }
+       span {
+               vertical-align: middle;
+               font-size: 12px;
+               font-variant: small-caps;
+               text-transform: uppercase;
+               margin-left: 3px;
+               white-space: nowrap;
+       }
+       &.inline-hint {
+               display: inline-block !important;
+               transform: scale(0.7);
+               vertical-align: baseline;
+               img {
+                       width: 13px;
+                       height: 13px;
+               }
+               span {
+                       font-size: 11px;
+               }
+       }
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/CanvasPanel.scss b/skyquake/plugins/composer/src/src/styles/CanvasPanel.scss
new file mode 100644 (file)
index 0000000..4b9f153
--- /dev/null
@@ -0,0 +1,49 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+
+.CanvasPanel {
+       position: absolute;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 250px;
+       width: auto;
+       min-width: 300px;
+       overflow: hidden;
+       z-index: 1;
+       .CanvasPanelHeader {
+               h1 {
+                       margin: 0;
+                       min-height: 56px;
+                       padding: 20px;
+                       color: #000000;
+                       font-size: 14px;
+                       font-weight: bold;
+                       text-align: left;
+                       text-transform: uppercase;
+                       line-height: 16px;
+                       background-color: #ffffff;
+               }
+       }
+       .CanvasPanelBody {
+               position: absolute;
+               bottom: 0;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss b/skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss
new file mode 100644 (file)
index 0000000..7e9e336
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+@import 'DataOpenCloseIcon';
+
+$tray-body-height: 250px;
+$tray-head-height: 25px;
+
+.CanvasPanelTray {
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       height: 25px;
+       min-width: 300px;
+       background-color: white;
+       &.-with-transitions {
+               transition: height 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
+       }
+       h1 {
+               border-bottom: 1px solid rgba(143, 143, 143, 0.05);
+               cursor: pointer;
+               color: #666;
+               font-size: 12px;
+               font-style: normal;
+               line-height: 16px;
+               height: 25px;
+               margin: 0;
+               padding-left: 0;
+               padding-right: 0;
+               text-align: center;
+               text-transform: uppercase;
+               background-color: $panel-bg-color-contrast;
+       }
+       > .tray-body {
+               position: absolute;
+               top: 25px;
+               right: 0;
+               left: 0;
+               bottom: 0;
+               overflow: hidden;
+               &:hover {
+                       overflow: auto;
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CanvasZoom.scss b/skyquake/plugins/composer/src/src/styles/CanvasZoom.scss
new file mode 100644 (file)
index 0000000..aae07d3
--- /dev/null
@@ -0,0 +1,40 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.CanvasZoom {
+       border: 1px dashed transparent;
+       position: absolute;
+       bottom: 20px;
+       left: 20px;
+       opacity: 0.25;
+       white-space: nowrap;
+       input {
+               opacity: 0.33;
+               vertical-align: middle;
+       }
+       span {
+               display: inline-block;
+               font-family: "Roboto", sans-serif;
+               font-weight: 100;
+               width: 100px;
+               padding-left: 8px;
+       }
+       &:hover {
+               opacity: 1;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogFilter.scss b/skyquake/plugins/composer/src/src/styles/CatalogFilter.scss
new file mode 100644 (file)
index 0000000..c853dfb
--- /dev/null
@@ -0,0 +1,58 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.CatalogFilter {
+       margin: 0;
+       padding: 0;
+       border-radius: 0;
+       width: 100%;
+       position: absolute;
+       display:flex;
+       button {
+               flex:1 1 50%;
+               vertical-align: bottom;
+               border-radius: 0;
+           box-shadow: none;
+           flex: 1 1 50%;
+           align-items: center;
+           display: flex;
+           div {
+               display:flex;
+               svg {
+                       height:1rem;
+                       width:1rem;
+                       path {
+                               // fill:white;
+                       }
+               }
+               span {
+                       margin:0rem;
+               }
+           }
+           svg {
+                       height:1rem;
+                       width:1rem;
+                       path {
+                               // fill:white;
+                       }
+               }
+               span:last-child {
+                       margin:0 0.5rem;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogItemCanvasEditor.scss b/skyquake/plugins/composer/src/src/styles/CatalogItemCanvasEditor.scss
new file mode 100644 (file)
index 0000000..f6d3d94
--- /dev/null
@@ -0,0 +1,41 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.CatalogItemCanvasEditor {
+       position: relative;
+       .DescriptorModel {
+               position: absolute;
+               height: 100%;
+               width: 100%;
+               margin: 0;
+               top: 0;
+               left: 0;
+               overflow: auto;
+       }
+       path.relation {
+               stroke: #333333;
+               stroke-width: 1;
+               stroke-dasharray: 2, 2;
+               stroke-linejoin: round;
+       }
+       #relation-marker-end {
+               fill: #EAEAEA;
+               stroke: #EAEAEA;
+               stroke-width: 1;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogItems.scss b/skyquake/plugins/composer/src/src/styles/CatalogItems.scss
new file mode 100644 (file)
index 0000000..5d020c0
--- /dev/null
@@ -0,0 +1,195 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+@import "ColorGroups";
+
+%type-header {
+    height:0.8rem;
+    width:100%;
+    color:white;
+    font-size:0.6rem;
+    padding-left: 1.5rem;
+    text-transform:uppercase;
+        line-height: 0.9rem;
+}
+
+.CatalogItems {
+       padding:0;
+       margin: 0;
+       position: absolute;
+       margin-top: 40px;
+       overflow-y: auto;
+       top: -6px;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       .nsd {
+               .type-header {
+                       @extend %type-header;
+                       background:$nsd-primary-color;
+               }
+       }
+       .vnfd {
+               .type-header {
+                       @extend %type-header;
+                       background:$vnfd-primary-color;
+               }
+       }
+       ul {
+               list-style: none;
+               margin: 0;
+               border: 0;
+               padding: 10px;
+               display: flex;
+               flex-wrap: wrap;
+               flex-direction: column;
+       }
+       li {
+               position: relative;
+               width: 100%;
+               min-width: 280px;
+               max-width: 400px;
+               margin: 1px;
+               border: 5px;
+               padding: 4px 8px;
+       }
+       li > div {
+               &.-is-open-for-edit-indicator {
+                       position: absolute;
+                       top: 10px;
+                       left: -4px;
+                       bottom: 10px;
+                       width: 8px;
+                       border-radius: 2px;
+                       background-color: #4d8fb3;
+               }
+
+       }
+       div.catalog-item {
+               cursor: pointer;
+               display: block;
+               overflow: hidden;
+               position: relative;
+               width: 100%;
+               height:auto;
+               min-height: 70px;
+               margin: 0;
+               padding: 0;
+               border-radius: 5px;
+               border: 1px solid #e5e5e5;
+               font-size: 14px;
+               font-weight: 400;
+               font-style: normal;
+               background-color: #ffffff;
+               -webkit-user-select: none;
+               -moz-user-select: none;
+               -ms-user-select: none;
+               user-select: none;
+
+               &:hover {
+                       background-color: #7E9BC1;
+                       dl {
+                               dd {
+                                       color: #ffffff;
+                               }
+                       }
+               }
+               &:active, &:visited {
+                       background-color:#4C5E74;
+               }
+               &.-is-modified {
+
+               }
+               &.-is-deleted {
+                       opacity: 0.25;
+               }
+
+               .-is-modified-indicator {
+                       position: absolute;
+                       top: -20px;
+                       right: -20px;
+                       width: 40px;
+                       height: 40px;
+                       background-color: #FF5F5F;
+                       transform: rotate(-45deg);
+               }
+
+               dl {
+                       margin: 0;
+                       padding: 3px 0 0 80px;
+                       position: relative;
+                       min-height: 70px;
+                       dt {
+                               margin: 0;
+                               padding: 0;
+                               font-size: 14px;
+                               font-weight: 400;
+                               white-space: nowrap;
+                       }
+                       dd {
+                               display: block;
+                               padding:0;
+                               color:#aeaeae;
+                               font-size: 10px;
+                               font-style: normal;
+                       }
+                       dd.logo {
+                               position: absolute;
+                               top:0;
+                               left: 5px;
+                               bottom: -4px;
+                               width: 70px;
+                               margin: 0;
+                               border: 0;
+                               padding: 0;
+                               overflow: hidden;
+                               img.logo {
+                                       margin: 0;
+                                       border: 0;
+                                       padding: 0;
+                                       width: 50px;
+                                       /*height: 50px; logos must scale height to fit a 50x50 pixel box otherwise they will clip*/
+                                       position: absolute;
+                                       top: 50%;
+                                       left: 50%;
+                                       transform: translate(-50%, -50%);
+                               }
+                       }
+               }
+
+               &:first-of-type {
+                       margin-top: 0;
+               }
+
+               span.vendor,
+               span.version {
+                       display: inline-block;
+                       padding-right: 4px;
+               }
+               span.vendor:after {
+                       content: ' /';
+               }
+               span.version:before {
+                       content: ' v';
+               }
+               span.description {
+                       display: none;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogPackageManager.scss b/skyquake/plugins/composer/src/src/styles/CatalogPackageManager.scss
new file mode 100644 (file)
index 0000000..9b434f9
--- /dev/null
@@ -0,0 +1,164 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+
+.CatalogPackageManager {
+       overflow: hidden;
+       > .items {
+               margin: 4px;
+               border: 1px solid transparent;
+               padding: 4px;
+               white-space: nowrap;
+               overflow: auto;
+               -ms-overflow-style: -ms-autohiding-scrollbar;
+               -ms-overflow-style: none;
+               display: flex;
+               flex-wrap: wrap;
+               align-items: flex-start;
+               align-content: flex-start;
+               justify-content: flex-start;
+
+               > .item {
+                       overflow: hidden;
+                       position: relative;
+                       font-size: 12px;
+                       font-weight: 200;
+                       font-style: normal;
+                       height: 40px;
+                       width: 100%;
+                       max-width: 400px;
+                       margin: 5px;
+                       border-radius: 5px;
+                       padding: 4px 8px;
+                       color: #3a3a3a;
+                       background-color: #ffffff;
+
+                       &.-error {
+                               background-color: rgba(139, 0, 0, 0.1);
+                       }
+                       &.-success {
+                               background-color: rgba(0, 139, 0, 0.1);
+                       }
+
+                       h2 {
+                               font-size:12px;
+                               font-weight: 400;
+                               padding-top: 0;
+                               padding-bottom: 0;
+                               padding-left: 30px;
+                       }
+                       img {
+                               width: 25px;
+                               height: 25px;
+                               position: absolute;
+                               top: 4px;
+                               left: 5px;
+                       }
+                       .message {
+                               padding-left: 30px;
+                       }
+                       span {
+                               display: inline-block;
+                       }
+                       em {
+                               display: none;
+                               color: #3C0808;
+                               font-weight: 100;
+                               margin-right: 4px;
+                       }
+                       var {
+                               font-family: monospace, serif;
+                       }
+                       .file-progress {
+                               display: block;
+                       }
+                       .file-progress-indicator {
+                               position: absolute;
+                               left: 30px;
+                               right: 3px;
+                               bottom: 0;
+                               margin: 3px;
+                               border: 1px solid rgba(81, 102, 147, 0.87);
+                               border-radius: 3px;
+                               padding: 0;
+                               height: 3px;
+                               background-color: white;
+                       }
+                       .file-progress-indicator-value {
+                               height: 1px;
+                               border-radius: 3px;
+                               background-color: #64F106;
+                       }
+                       .file-download {
+                       }
+                       .file-download-link {
+                               display: inline;
+                               margin-left: 24px;
+                               padding: 3px;
+                       }
+                       .file-preview {
+                               display: block;
+                               em {
+                                       display: none;
+                               }
+                       }
+                       .file-error {
+                               display: block;
+                               position: absolute;
+                               z-index: 99;
+                               background-color: black;
+                               top: 18px;
+                               left: 30px;
+                               right: 10px;
+                               border-radius: 3px;
+                               padding: 1px 4px !important;
+                       }
+                       .file-success {
+                               display: block;
+                               position: absolute;
+                               z-index: 99;
+                               background-color: black;
+                               top: 18px;
+                               left: 30px;
+                               right: 10px;
+                               border-radius: 3px;
+                               padding: 1px 4px !important;
+                       }
+                       .item-actions {
+                               background-color: rgba(255,255,255,.5);
+                               display: none;
+                               position: absolute;
+                               top: 0;
+                               right: 0;
+                               bottom: 0;
+                               padding: 4px;
+                               text-align: right;
+                               .Button {
+                                       &:hover {
+                                               background-color: transparent;
+                                               border-color: transparent;
+                                       }
+                               }
+                       }
+                       &:hover .item-actions {
+                               display: block;
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogPanel.scss b/skyquake/plugins/composer/src/src/styles/CatalogPanel.scss
new file mode 100644 (file)
index 0000000..68c9936
--- /dev/null
@@ -0,0 +1,52 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'main';
+@import 'variables';
+.CatalogPanel {
+       border-right: 1px solid $panel-border-color;
+       position: absolute;
+       top: 0;
+       left: 0;
+       bottom: 0;
+       width: 300px;
+       min-width: 6px;
+       overflow: hidden;
+       z-index: 3;
+       &.-is-tray-open {
+               .CatalogPanelBody {
+                       bottom: 275px;/*height of the CatalogPanelTray*/
+               }
+       }
+       .CatalogPanelBody {
+               @extend .panel-body;
+               min-width: 300px;
+
+               >div {
+                       position: relative;
+                       height: 100%;
+                       width: 100%;
+               }
+
+               .LoaderWrapper {
+                       display: flex;
+                       justify-content: center;
+               }
+       }
+}
+
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogPanelToolbar.scss b/skyquake/plugins/composer/src/src/styles/CatalogPanelToolbar.scss
new file mode 100644 (file)
index 0000000..33105f8
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import '_variables';
+.CatalogPanelToolbar {
+    display: block;
+    padding: 0;
+    margin: 0;
+       height: auto;
+       border-bottom: 0 solid $panel-border-color-light;
+       white-space: nowrap;
+       text-align: center;
+       h1 {
+               white-space: nowrap;
+               text-align: left;
+        font-size: 14px;
+        line-height: 16px;
+        padding: 20px;
+        text-transform: uppercase;
+        font-weight: bold;
+        background-color: #ffffff;
+       }
+       .btn-bar {
+               height: 55px;
+               padding: 10px 0;
+               background-color: rgba(203, 209, 209, 1);
+               .btn-group {
+                       padding: 0 8px;
+                       display: inline-block;
+                       input {
+                               margin: 0 4px;
+                       }
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/CatalogPanelTray.scss b/skyquake/plugins/composer/src/src/styles/CatalogPanelTray.scss
new file mode 100644 (file)
index 0000000..c3c16a3
--- /dev/null
@@ -0,0 +1,65 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+@import 'DataOpenCloseIcon';
+
+$tray-body-height: 250px;
+$tray-head-height: 25px;
+
+.CatalogPanelTray {
+       position: absolute;
+       overflow: hidden;
+       bottom: 0px;
+       width: 100%;
+       min-width: 300px;
+       height: $tray-head-height + $tray-body-height;
+       color: #aeaeae;
+       background-color: $panel-bg-color;
+       z-index: 0;
+       transition: transform 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
+       &.-close {
+               transform: translate3d(0, $tray-body-height, 0);
+       }
+       h1 {
+               border-bottom: 1px solid rgba(143, 143, 143, 0.05);
+               cursor: pointer;
+               color: #666;
+       font-size: 12px;
+       font-style: normal;
+       line-height: 16px;
+               height: 25px;
+       margin: 0;
+       padding-left: 0;
+       padding-right: 0;
+       text-align: center;
+       text-transform: uppercase;
+               background-color: $panel-bg-color-contrast;
+       }
+       .tray-body {
+               height: $tray-body-height;
+               overflow: auto;
+               z-index: 0;
+               background-color: $panel-bg-color;
+       }
+       &.-is-dragging {
+               .tray-body {
+                       overflow: hidden;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/ComposerAppToolbar.scss b/skyquake/plugins/composer/src/src/styles/ComposerAppToolbar.scss
new file mode 100644 (file)
index 0000000..7b2ef16
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+@import 'main';
+
+.ComposerAppToolbar {
+       @extend .panel-header;
+       top: 56px;
+       left: 300px;
+    right: 0;
+       height: 55px;
+       z-index: 4;
+    position: absolute;
+    padding: 10px 20px;
+    background-color: $panel-bg-color-contrast;
+       white-space: nowrap;
+       div {
+               display: inline-block;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/ConnectionPointSelector.scss b/skyquake/plugins/composer/src/src/styles/ConnectionPointSelector.scss
new file mode 100644 (file)
index 0000000..53e08df
--- /dev/null
@@ -0,0 +1,14 @@
+.ConnectionPointSelector {
+       display: inline-block;
+       //position: fixed;
+       bottom: 2px;
+       font-size: 10px;
+       text-align: center;
+       border-radius: 33px;
+       margin: 0 0 0 -12px;
+       padding: 12px;
+       background-color: rgba(255, 255, 255, 0.66);
+       border-top: 1px solid rgba(192, 192, 192, 0.13);
+       border-bottom: 1px solid rgba(192, 192, 192, 0.13);
+       z-index: 9;
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/DataOpenCloseIcon.scss b/skyquake/plugins/composer/src/src/styles/DataOpenCloseIcon.scss
new file mode 100644 (file)
index 0000000..4be4080
--- /dev/null
@@ -0,0 +1,26 @@
+@import 'variables';
+
+[data-open-close-icon]{
+       &:after {
+               content: " ";
+               display: block;
+               position: absolute;
+               top: 1px;
+               right: 8px;
+               height: 25px;
+               width: 25px;
+               opacity: 0.25;
+               background-size: 20px 20px;
+               background-repeat: no-repeat;
+               background-position: center center;
+               /* background-image required in order for background-size to work*/
+        background-image: url(../../../node_modules/open-iconic/svg/caret-bottom.svg);
+       }
+       &:hover:after {
+               opacity: 1;
+       }
+}
+[data-open-close-icon="closed"]:after {
+       transform: rotate(180deg);
+       transition: all 300ms cubic-bezier(0.77, 0, 0.175, 1);
+}
diff --git a/skyquake/plugins/composer/src/src/styles/DescriptorGraph.scss b/skyquake/plugins/composer/src/src/styles/DescriptorGraph.scss
new file mode 100644 (file)
index 0000000..7efafaa
--- /dev/null
@@ -0,0 +1,170 @@
+@import "_ColorGroups";
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@function dim-color($color) {
+       @return hsl(hue($color), 50%, 80%);
+}
+
+/* TODO this CSS has to be complete refactored - most of it may not even be used anymore!!! */
+
+.DescriptorGraph {
+       background-color: transparent;
+       border: 1px solid transparent;
+       -webkit-user-select: none;
+       -moz-user-select: none;
+       user-select: none;
+       .grid {
+               line {
+                       stroke: #CBD1D1;
+                       stroke-width: 0.5px;
+                       shape-rendering: geometricPrecision;
+               }
+       }
+       .selection-indicator {
+               stroke-dasharray: 2, 2;
+       }
+       .connector {
+               &.-is-not-connected {
+                       fill: white !important;
+               }
+               &.-is-connected {
+                       fill: #9fc4f4 !important;
+               }
+       }
+       .connection,
+       .new-connection {
+               /* note colors are also defined in ColorGroups.js */
+               //stroke: #295725;
+               stroke-width: 5px;
+               &.-selected {
+                       stroke-width: 7px;
+                       stroke: red;
+               }
+       }
+       .connection-point {
+               &:hover {
+                       cursor: pointer;
+               }
+               &.-is-highlight {
+                       stroke: red !important;
+               }
+       }
+
+       .connection-point-number {
+               text-shadow: 0 0 10px rgba(171, 161, 161, 0.89);
+               font-size: 18px;
+               fill: white;
+               stroke: white;
+               &.-is-highlight {
+                       fill: red;
+                       stroke: red;
+               }
+       }
+
+       .relation-marker-end {
+               stroke: transparent;
+               fill: transparent;
+       }
+
+       &.-is-dragging-connection-point {
+               cursor: no-drop !important;
+               .border,
+               .background,
+               &.connector,
+               &.connector:hover,
+               .connector,
+               .connector:hover {
+                       cursor: no-drop !important;
+                       fill-opacity: 0.33;
+                       stroke-opacity: 0.33;
+               }
+               .-is-valid-drop-target {
+                       cursor: copy !important;
+                       .border,
+                       .background,
+                       &.connector,
+                       &.connector:hover,
+                       .connector,
+                       .connector:hover {
+                               cursor: copy !important;
+                               fill-opacity: 1;
+                               stroke-opacity: 1;
+                       }
+                       &.-is-drag-over {
+                               .border {
+                                       stroke-width: 3px;
+                               }
+                       }
+               }
+       }
+
+       .forwarding-graph-paths {
+               pointer-events: none;
+       }
+
+       text {
+
+               pointer-events: none;
+               fill: $common-foreground-color;
+               stroke: $common-foreground-color;
+               font-size: 14px;
+
+               &.type {
+                       text-transform: uppercase;
+                       stroke: white;
+                       fill: white;
+               }
+
+               &.vld-type {
+                       display: none;
+               }
+
+               &.internal-vld-type {
+                       display: none;
+               }
+
+               &:hover {
+                       cursor: default;
+               }
+
+       }
+
+       path {
+
+               stroke-linejoin: round;
+
+               &.relation {
+                       display: none;
+               }
+
+       }
+
+       .color-legend {
+               display: none;
+               &.vnffgd-rsp-color-legend {
+                       display: block;
+                       text {
+                               font-size: xx-small;
+                               color: white;
+                       }
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/styles/DetailsPanel.scss b/skyquake/plugins/composer/src/src/styles/DetailsPanel.scss
new file mode 100644 (file)
index 0000000..729f6de
--- /dev/null
@@ -0,0 +1,47 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'main';
+@import 'variables';
+.DetailsPanel {
+       @extend .panel;
+       border-top: 1px solid mix($panel-border-color, white, 80%);
+       //border-left: 1px solid $panel-border-color;
+       background-color: ($panel-bg-color-contrast);
+       position: absolute;
+       top: 111px;
+       right: 0;
+       bottom: 0;
+       width: 300px;
+       min-width: 6px;
+       z-index: 2;
+       .DetailsPanelBody {
+               @extend .panel-body;
+               position: absolute;
+               overflow: hidden;
+               &:hover {
+                       overflow: auto;
+               }
+               -ms-overflow-style: -ms-autohiding-scrollbar;
+               bottom: 0;
+               top: 0;
+               left: 0;
+               right: 0;
+               min-width: 200px;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/DropZonePanel.scss b/skyquake/plugins/composer/src/src/styles/DropZonePanel.scss
new file mode 100644 (file)
index 0000000..9118cd3
--- /dev/null
@@ -0,0 +1,56 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+
+.DropZonePanel {
+       overflow: hidden;
+       display: flex;
+       flex-wrap: wrap;
+       flex-direction: column;
+       align-content: stretch;
+       &.-close {
+               display: none;
+       }
+       .dz-message {
+               font-size: small;
+               margin: 2px;
+               text-align: center;
+       }
+       .dnd-target {
+               flex-grow: 4;
+               display: block;
+               margin: 4px;
+               padding: 25px 20px;
+               color: $panel-font-color;
+               border: 2px dashed $section-border-color;
+               border-radius: 8px;
+               background-color: $primary-contrast-bg-color;
+               &:hover {
+                       border: 2px dashed darken($section-border-color, 20%);
+                       background-color: $button-bg-color;
+               }
+               &.-drag-hover,
+               &.dz-drag-hover {
+                       cursor: pointer !important;
+                       border-color: darken($section-border-color, 20%);
+                       background-color: darken($primary-contrast-bg-color, 20%);
+                       color: darken($panel-font-color, 20%);
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/EditDescriptorModelProperties.scss b/skyquake/plugins/composer/src/src/styles/EditDescriptorModelProperties.scss
new file mode 100644 (file)
index 0000000..48ce949
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@import "main";
+@import "ColorGroups";
+
+.EditDescriptorModelProperties {
+
+       $field-border-radius: 3px;
+       $field-background-color: white;
+       $child-indent-left-right-margin: 5px;
+
+       font-size: smaller;
+
+       h1 {
+               text-align: left;
+               span:last-child {
+                       i {
+                               display: none;
+                       }
+               }
+       }
+
+       h2 {
+               @extend h1;
+
+       }
+
+       .basic-properties-group {
+               > h1 {
+                       display: none;
+               }
+       }
+
+       .advanced-properties-group {
+       }
+
+       /* label is used as list item headers */
+       h3 {
+               @extend h2;
+               display: inline-block;
+               .name {
+                       color: #586e75;
+               }
+               .value {
+                       display: none;
+                       color: #002b36;
+               }
+               .info {
+                       margin: 4px;
+               }
+       }
+
+       val {
+               display: inline-block;
+               color: #073642;
+       }
+
+       a {
+               &.simple-list-item {
+                       display: inline-block;
+                       width: 230px;
+                       padding: 4px 16px 4px 4px;
+                       white-space: nowrap;
+               }
+               &.vld-list-item,
+               &.internal-vld-list-item{
+                       border: 1px solid $vld-primary-color;
+                       border-radius: 24px;
+                       background: white linear-gradient(to right, $vld-primary-color 34px, white 34px);;
+               }
+               &.vnfd-list-item,
+               &.constituent-vnfd-list-item{
+                       border: 1px solid $vnfd-primary-color;
+                       border-radius: 11px;
+                       background: white linear-gradient(to right, $vnfd-primary-color 34px, white 34px);;
+               }
+               &.vdu-list-item {
+                       border: 1px solid $vdu-primary-color;
+                       border-radius: 11px;
+                       background: white linear-gradient(to right, $vdu-primary-color 34px, white 34px);;
+               }
+               &.vnffgd-list-item {
+                       border: 1px solid $vnffgd-primary-color;
+                       border-radius: 11px;
+                       background: white linear-gradient(to right, $vnffgd-primary-color 34px, white 34px);;
+               }
+       }
+
+       &.-is-tree-view {
+               .property {
+
+                       position: relative;
+                       overflow: hidden;
+
+                       margin: 8px 8px;
+
+                       background-color: rgba(147, 161, 161, 0.5);
+                       border-radius: $field-border-radius;
+
+                       > h3 {
+                               position: absolute;
+                               top: 2px;
+                               right: 18px;
+                               height: 21px;
+                               pointer-events: none;
+                               border-radius: $field-border-radius;
+                               padding: 3px 0;
+                       }
+
+                       > val {
+                               width: 100%;
+                               > .property-content {
+                                       width: 100%;
+                               }
+
+                       }
+
+                       &.-is-focused {
+                               > h3 {
+                                       //z-index: -1;
+                               }
+                       }
+
+                       &.leaf-property {
+                               overflow: hidden;
+                               min-height: 25px;
+                               > h3 {
+                                       background: linear-gradient(to right, transparent, $field-background-color 21px);
+                                       padding-left: 25px;
+                               }
+                               > val {
+                                       border-radius: $field-border-radius;
+                                       > .property-content {
+                                               border-radius: $field-border-radius;
+                                       }
+                               }
+                       }
+
+                       &.property:not(.leaf-property) {
+
+                               padding: 7px $child-indent-left-right-margin 0 $child-indent-left-right-margin;
+
+                               &.list-property {
+                                       > h3 {
+                                               padding: 4px 8px;
+                                       }
+                               }
+
+                               > h3 {
+                                       right: auto;
+                                       top: 0;
+                                       left: 0;
+                                       width: 100%;
+                                       height: 25px;
+                                       z-index: 1;
+                                       padding: 8px;
+                                       //background: red;
+                                       pointer-events: all;
+                               }
+                               > val {
+                                       margin: 28px 0 8px 0;
+                                       > .property-content {
+                                               position: relative;
+                                               border-radius: $field-border-radius;
+                                               margin-top: 4px;
+                                               padding: 4px;
+                                               &:first-of-type {
+                                                       margin-top: 0;
+                                               }
+                                               &.simple-list {
+                                                       min-height: 15px;
+                                                       margin: 11px;
+                                                       .simple-list-item {
+                                                               img,
+                                                               span {
+                                                                       margin: 0 5px;
+                                                                       vertical-align: middle;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       > .property-content:not(.simple-list) {
+                                               &:nth-of-type(odd) {
+                                                       background-color: rgba(238, 232, 213, 0.33);
+                                               }
+                                               &:nth-of-type(even) {
+                                                       background-color: rgba(147, 161, 161, 0.33);
+                                               }
+                                       }
+                                       .tip {
+                                               font-style: italic;
+                                               font-size: small;
+                                               color: #93a1a1;
+                                       }
+                               }
+                       }
+
+                       .actions {
+                               span {
+                                       vertical-align: middle;
+                                       padding: 0 5px;
+                               }
+                       }
+
+               }
+
+       }
+
+       .description {
+               display: none;
+       }
+
+       input,
+       select,
+       textarea {
+               height: 25px;
+               line-height: 25px;
+               max-width: 100%;
+               min-width: 100%;
+               margin: 0;
+               padding: 0 0px 4px 8px;
+               border: 1px solid $field-background-color;
+               border-radius: $field-border-radius;
+               color: #002b36;
+               background-color: $field-background-color;
+               vertical-align: top;
+               &:focus {
+                       color: #002b36;
+                       background-color: white !important;
+               }
+               &::-webkit-input-placeholder {
+                       color: #eee8d5 !important;
+               }
+
+               &:-moz-placeholder { /* Firefox 18- */
+                       color: #eee8d5 !important;
+               }
+
+               &::-moz-placeholder {  /* Firefox 19+ */
+                       color: #eee8d5 !important;
+               }
+
+               &:-ms-input-placeholder {
+                       color: #eee8d5 !important;
+               }
+       }
+
+       select {
+               padding-right: 0;
+               margin-right: 0;
+               -webkit-appearance: none;
+               -webkit-border-radius: $field-border-radius;
+               &.-value-not-set {
+                       color: #eee8d5;
+               }
+       }
+
+       select {
+               appearance: none; // using -prefix-free http://leaverou.github.io/prefixfree/
+        background: $field-background-color url(../../../node_modules/open-iconic/svg/caret-bottom.svg) no-repeat right 8px center;
+               background-size: 10px;
+               border: {
+                       color: $field-background-color;
+                       radius: $field-border-radius;
+                       style: solid;
+                       width: 1px;
+               }
+       }
+
+       // Removes default arrow for IE10+
+       // IE 8/9 get dafault arrow which covers caret image
+       // as long as caret image is small than and positioned
+       // behind default arrow
+       select::-ms-expand {
+               display: none;
+       }
+
+       textarea {
+               height: 50px;
+       }
+
+       input {
+               padding: 0 20px 0 8px;
+               line-height: 25px;
+       }
+
+       input[name$="id"],
+       input.-is-guid {
+               font-size: 10px;
+               font-family: monospace;
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/styles/EditForwardingGraphPaths.scss b/skyquake/plugins/composer/src/src/styles/EditForwardingGraphPaths.scss
new file mode 100644 (file)
index 0000000..d742d93
--- /dev/null
@@ -0,0 +1,429 @@
+.EditForwardingGraphPaths {
+
+       padding: 8px;
+
+       &.-with-transitions {
+               * {
+                       transition: all 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
+               }
+       }
+
+       .NetworkService {
+               position: relative;
+               > .footer-actions {
+                       border-top: 1px solid silver;
+               }
+       }
+
+       .ForwardingGraph {
+
+               margin-top: 20px;
+
+               &:first-child {
+                       margin-top: 0;
+               }
+
+               border-bottom: 1px solid silver;
+
+               > div > .footer-actions {
+                       padding-left: 80px;
+               }
+
+       }
+
+       .RecordServicePath {
+
+               position: relative;
+
+               min-height: 100px;
+
+               white-space: nowrap;
+
+               overflow: visible;
+
+               margin: 8px 0;
+
+               background-color: #CBD1D1;
+
+               .EditableProperty {
+                       display: block;
+                       margin: 12px 0;
+                       width: 200px;
+               }
+
+               .ConstituentVnfd {
+
+                       position: relative;
+                       display: none;
+
+                       > small {
+                               vertical-align: bottom;
+                       }
+
+                       &:hover {
+                               small.vnfd-title {
+                                       display: block;
+                               }
+                       }
+
+                       small.vnfd-title {
+                               display: none;
+                               position: absolute;
+                               top: -20px;
+                               width: 100%;
+                               left: 0;
+                       }
+
+                       .connectors {
+                               border-top: 3px solid silver;
+                               border-radius: 9px;
+                               padding-top: 3px;
+                               .connection-point {
+                                       border: 2px solid;
+                                       margin: 2px;
+                                       * {
+                                               vertical-align: middle;
+                                       }
+                               }
+                       }
+               }
+
+               &.-is-factory {
+                       opacity: 0.33;
+                       &:hover {
+                               opacity: 1;
+                               .ConstituentVnfd {
+                                       display: inline-block;
+                               }
+                       }
+                       .create-record-service-path {
+                               display: none;
+                       }
+                       .EditableProperty {
+                               visibility: hidden;
+                       }
+               }
+
+               &:hover {
+                       > .header-actions {
+                               display: block;
+                               &:hover {
+                                       opacity: 1;
+                               }
+                       }
+                       &.-is-edit-paths-mode {
+                               .ConstituentVnfd {
+                                       display: inline-block;
+
+                               }
+                               .enter-path-edit-mode {
+                                       display: none;
+                               }
+                               .selection {
+                                       display: inline-block;
+                               }
+                               > .header-actions {
+                                       display: none;
+                               }
+                       }
+                       .rsp-create-new-connection-point-line,
+                       .enter-path-edit-mode {
+                               opacity: 1;
+                       }
+
+               }
+
+       }
+
+       .RspConnectionPointRef {
+               border: 2px solid transparent;
+               border-radius: 8px;
+               width: 35px;
+               height: 35px;
+               display: inline-block;
+               margin: 0;
+               padding: 0;
+               font-size: 11px;
+               text-align: center;
+               cursor: pointer;
+               vertical-align: middle;
+               &.create-new-connection-point {
+                       width: auto;
+                       height: auto;
+                       border: dotted red;
+               }
+               small {
+                       vertical-align: baseline;
+               }
+
+       }
+
+       .connection-point {
+               @extend .RspConnectionPointRef;
+               display: inline-block;
+               border: dotted red;
+               text {
+                       fill: #111831;
+                       stroke: #111831;
+               }
+       }
+
+       .Classifier {
+               background-color: #CBD1D1 !important;
+               td {
+                       .match-attr-name {
+                               display: none;
+                       }
+               }
+       }
+
+       .fg-classifier {
+
+               position: relative;
+               margin-bottom: 13px;
+
+               th,
+               td {
+                       padding: 4px;
+                       min-width: 80px;
+                       text-align: left;
+                       vertical-align: top;
+                       &.primary-action-column,
+                       &.secondary-action-column {
+                               max-width: 40px;
+                       }
+                       &.id-property {
+                               display: none;
+                       }
+               }
+
+               th {
+                       line-height: 10px;
+                       vertical-align: bottom;
+               }
+
+               th {
+                       @extend h2;
+               }
+
+               input {
+                       &.match-attr-value {
+                               min-width: 100px;
+                       }
+               }
+
+               .classifier-properties {
+                       line-height: 25px;
+                       .classifier-property {
+                               position: relative;
+                               vertical-align: top;
+                               display: inline-block;
+                               margin: 4px;
+                       }
+               }
+
+               .select-connection-point-ref {
+                       display: none;
+                       position: absolute;
+                       top: 30px;
+                       left: 2px;
+                       width: auto;/* set by the code*/
+                       min-width: 150px;
+                       box-shadow: 0.1px 0.1px 3px silver;
+                       z-index: 9999;
+                       .ConnectionPointSelector {
+                               background-color: white;
+                               border-radius: 3px;
+                               width: 100%;
+                               text-align: left;
+                               margin: 0;
+                               small.Button {
+                                       display: none;
+                               }
+                       }
+               }
+
+               &.-is-edit-classifier-connection-point-ref {
+                       .select-connection-point-ref {
+                               display: block;
+                       }
+               }
+
+       }
+
+       h2 {
+               font-size: 9px;
+               text-transform: uppercase;
+               color: #AEAEAE;
+               img {
+                       border: 0;
+                       width: 30px;
+                       margin: 3px;
+                       vertical-align: middle;
+               }
+       }
+
+       h4 {
+               @extend h2;
+               margin: 4px 4px 4px 80px;
+       }
+
+       .primary-action-column {
+               width: 40px;
+               input {
+                       margin: 8px 12px;
+               }
+       }
+
+       .secondary-action-column {
+               width: 40px;
+       }
+
+       .rsp {
+               display: inline-block;
+       }
+
+       .rsp-line {
+               border: 2px solid red;
+               display: inline-block;
+               width: 20px;
+               vertical-align: middle;
+               &.rsp-create-new-connection-point-line {
+                       border-style: dotted;
+               }
+       }
+
+
+       .header-actions {
+               position: absolute;
+               right: 0;
+       }
+
+       .row-action-column {
+               width: 50px;
+               overflow: visible;
+               white-space: nowrap;
+               text-align: center;
+               padding: 8px;
+               display: inline-block;
+               .action {
+                       cursor: pointer;
+               }
+       }
+
+       .connection-points {
+               display: inline-block;
+               margin-right: 25px;
+               vertical-align: middle;
+               .selection {
+                       display: none;
+                       position: absolute;
+                       bottom: 2px;
+                       font-size: 10px;
+                       text-align: center;
+                       border-radius: 33px;
+                       margin: 0 0 0 -12px;
+                       padding: 12px;
+                       background-color: rgba(255, 255, 255, 0.66);
+                       border-top: 1px solid rgba(192, 192, 192, 0.13);
+                       border-bottom: 1px solid rgba(192, 192, 192, 0.13);
+               }
+               .rsp:first-child {
+                       .rsp-line {
+                               display: none;
+                       }
+               }
+       }
+
+       .create-new-connection-point.Button {
+               padding: 0;
+               img {
+                       width: 34px;
+                       height: 34px;
+               }
+       }
+
+       .header-actions {
+               display: none;
+               opacity: 0.33;
+       }
+
+       .footer-actions {
+               border-color: transparent;
+               opacity: 0.33;
+               &:hover {
+                       opacity: 1;
+               }
+       }
+
+       .vnfd-list {
+               display: inline-block;
+       }
+
+       .rsp-create-new-connection-point-line,
+       .enter-path-edit-mode {
+               opacity: 0.33;
+       }
+
+       .fg-icon {
+               width: 25px;
+               vertical-align: middle;
+       }
+
+       input {
+               width: 100%;
+               overflow: hidden;
+               text-overflow: ellipsis;
+       }
+
+       select {
+               width: auto !important;
+               max-width: none !important;
+               min-width: 150px !important;
+       }
+
+       .classifier-match-attributes {
+               > tbody {
+                       > tr:nth-of-type(odd) {
+                               background-color: rgba(238, 232, 213, 0.33);
+                       }
+                       //> tr:nth-of-type(even) {
+                       //      background-color: rgba(147, 161, 161, 0.33);
+                       //}
+               }
+       }
+
+       .no-service-function-chain-msg {
+               margin-left: 80px;
+       }
+
+       .hint {
+               color: #073642;
+               font-size: 12.8px;
+       }
+
+       .EditableProperty {
+               &.-is-disabled {
+                       h3,
+                       val input {
+                               background: #aeaeae !important;
+                       }
+               }
+       }
+}
+
+.tooltip-indicator {
+       .cpNumber {
+               i {
+                       display: none;
+               }
+               val {
+                       position: absolute;
+                       top: -10px;
+                       left: -5px;
+                       margin-left: 50%;
+                       margin-right: 50%;
+                       padding: 0;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/EditableProperty.scss b/skyquake/plugins/composer/src/src/styles/EditableProperty.scss
new file mode 100644 (file)
index 0000000..529dc20
--- /dev/null
@@ -0,0 +1,45 @@
+@import 'variables';
+@import 'main';
+.EditableProperty {
+
+       position: relative;
+       display: inline-block;
+       vertical-align: middle;
+
+       h3 {
+
+               @extend h1;
+
+               display: inline-block;
+               position: absolute;
+               top: 3px;
+               right: 21px;
+               height: 19px;
+               pointer-events: none;
+               border-radius: $field-border-radius;
+               background: linear-gradient(to right, transparent, $field-background-color 21px);
+               color: #586e75;
+
+               margin: 0;
+               border: 0;
+               padding: 0 0 4px 21px;
+               text-align: right;
+
+               font-size: xx-small;
+               vertical-align: top;
+               line-height: 19px;
+
+               input {
+                       display: none;
+                       color: #002b36;
+                       min-width: 100px;
+                       max-width: 100%;
+               }
+
+               .property-description {
+                       margin: 4px;
+               }
+
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/styles/FileUploadsList.scss b/skyquake/plugins/composer/src/src/styles/FileUploadsList.scss
new file mode 100644 (file)
index 0000000..02eba34
--- /dev/null
@@ -0,0 +1,134 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+.FileUploadList {
+       overflow: hidden;
+       position: absolute;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       >.items {
+               position: absolute;
+               top: 0;
+               right: 0;
+               bottom: 0;
+               left: 0;
+               margin: 4px;
+               border: 1px solid transparent;
+               padding: 4px;
+               white-space: nowrap;
+               overflow: auto;
+               -ms-overflow-style: -ms-autohiding-scrollbar;
+               -ms-overflow-style: none;
+               display: flex;
+               flex-wrap: wrap;
+               >.item {
+                       overflow: hidden;
+                       display: inline-block;
+                       position: relative;
+                       font-size: 0.5em;
+                       height: 40px;
+                       min-width: 260px;
+                       max-width: 260px;
+                       margin: 0;
+                       border-radius: 8px;
+                       border: 1px solid white;
+                       padding: 4px 8px;
+                       color: #D9D9D9;
+                       font-weight: 100;
+                       font-style: normal;
+                       background-color: rgba(92, 92, 92, 0.86);
+                       &.-error {
+                               background-color: darkred;
+                       }
+                       &.-success {
+                               background-color: darkgreen;
+                       }
+                       h2 {
+                               padding-left: 25px;
+                       }
+                       img {
+                               width: 25px;
+                               height: 25px;
+                               position: absolute;
+                               top: 4px;
+                               left:5px;
+                       }
+                       span {
+                               display: none;
+                               padding-left: 25px;
+                       }
+                       em {
+                               display: none;
+                               color: #3C0808;
+                               font-weight: 100;
+                               margin-right: 4px;
+                       }
+                       var {
+                               font-family: monospace, serif;
+                       }
+                       .file-progress {
+                               display: block;
+                       }
+                       .file-progress-indicator {
+                               width: 100%;
+                               margin: 3px;
+                               border: 1px solid rgba(81, 102, 147, 0.87);
+                               border-radius: 3px;
+                               padding: 0;
+                               height: 3px;
+                               background-color: white;
+                       }
+                       .file-progress-indicator-value {
+                               height: 1px;
+                               border-radius: 3px;
+                               background-color: #64F106;
+                       }
+                       .file-preview {
+                               display: block;
+                               em {
+                                       display: none;
+                               }
+                       }
+                       .file-error {
+                               display: block;
+                               position: absolute;
+                               z-index: 99;
+                               background-color: black;
+                               top: 18px;
+                               left: 30px;
+                               right: 10px;
+                               border-radius: 3px;
+                               padding: 1px 4px !important;
+                       }
+                       .file-success {
+                               display: block;
+                               position: absolute;
+                               z-index: 99;
+                               background-color: black;
+                               top: 18px;
+                               left: 30px;
+                               right: 10px;
+                               border-radius: 3px;
+                               padding: 1px 4px !important;
+                       }
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/FileUploadsToolbar.scss b/skyquake/plugins/composer/src/src/styles/FileUploadsToolbar.scss
new file mode 100644 (file)
index 0000000..082779e
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.FileUploadToolbar {
+       position: absolute;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       width: 100px;
+       z-index: 1;
+       .ClosePanel {
+               border-radius: 20px;
+               width: 15px;
+               height: 15px;
+               opacity: 0.5;
+               position: absolute;
+               top: 4px;
+               right: 4px;
+               &:hover {
+                       opacity: 1;
+               }
+       }
+       .ClearAllFiles {
+               position: absolute;
+               top: 38px;
+               right: 8px;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/FullScreen.scss b/skyquake/plugins/composer/src/src/styles/FullScreen.scss
new file mode 100644 (file)
index 0000000..0fa8f34
--- /dev/null
@@ -0,0 +1,22 @@
+body.-is-full-screen {
+       .AppHeader {
+               display: none;
+       }
+       .AppBody {
+               top: 0 !important;
+               bottom: 0 !important;
+       }
+       .CatalogPanel {
+               display: none;
+       }
+       .CanvasPanel {
+               left: 0 !important;
+               right: 0 !important;
+       }
+       .DetailsPanel {
+               display: none;
+       }
+       .corner-accent {
+               display: none;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/GraphDescriptorModel.scss b/skyquake/plugins/composer/src/src/styles/GraphDescriptorModel.scss
new file mode 100644 (file)
index 0000000..dc0c2b5
--- /dev/null
@@ -0,0 +1,5 @@
+
+.DescriptorGraph {
+
+
+}
diff --git a/skyquake/plugins/composer/src/src/styles/GraphRecordServicePaths.scss b/skyquake/plugins/composer/src/src/styles/GraphRecordServicePaths.scss
new file mode 100644 (file)
index 0000000..f2dc39c
--- /dev/null
@@ -0,0 +1,15 @@
+.forwarding-graph-paths {
+       &.-is-highlighting {
+               path.rsp-path {
+                       stroke-opacity: 0.5;
+               }
+       }
+       path.rsp-path {
+               fill: transparent;
+               shape-rendering: geometricPrecision;
+       }
+       path.-is-highlighted {
+               stroke-width: 4px;
+               stroke-opacity: 1 !important;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/GraphVirtualLink.scss b/skyquake/plugins/composer/src/src/styles/GraphVirtualLink.scss
new file mode 100644 (file)
index 0000000..44b39a1
--- /dev/null
@@ -0,0 +1,32 @@
+@import "main";
+
+.DescriptorGraph {
+
+       /* colors are defined in ColorGroups and assigned in the graph code. */
+
+       .VirtualLink {
+
+               @extend .descriptor;
+
+               path.icon {
+                       pointer-events: none;
+               }
+
+               &.-is-selected,
+               &.-selected {
+                       circle.badge {
+                               stroke: red;
+                       }
+               }
+
+       }
+
+       &.-is-dragging-connection-point {
+               .-is-valid-drop-target.-is-drag-over {
+                       circle.badge {
+                               stroke: red;
+                       }
+               }
+       }
+
+}
diff --git a/skyquake/plugins/composer/src/src/styles/LayoutRow.scss b/skyquake/plugins/composer/src/src/styles/LayoutRow.scss
new file mode 100644 (file)
index 0000000..115a9ae
--- /dev/null
@@ -0,0 +1,48 @@
+.layout-row {
+
+       min-width: 600px;
+
+       display: flex;
+       flex-wrap: nowrap;
+
+       vertical-align: baseline;
+       line-height: 30px;
+
+       margin: 0;
+       border: 0;
+       padding: 0;
+
+       > .primary-action-column {
+               flex: 0;
+               min-width: 30px;
+               max-width: 30px;
+               text-align: center;
+               > * {
+                       vertical-align: middle;
+               }
+       }
+
+       > .secondary-action-column {
+               flex: 0;
+               min-width: 30px;
+               max-width: 30px;
+               text-align: center;
+               margin: 0 9px;
+               > * {
+                       vertical-align: middle;
+               }
+       }
+
+       > .columns {
+               flex: auto;
+               > * {
+                       vertical-align: middle;
+               }
+       }
+
+       small.Button {
+               margin: 2px 8px;
+               padding: 0 8px;
+       }
+
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/LoadingIndicator.scss b/skyquake/plugins/composer/src/src/styles/LoadingIndicator.scss
new file mode 100644 (file)
index 0000000..d425604
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.line-scale-pulse-out-rapid > div {
+  background-color: #fff;
+  width: 4px;
+  height: 2rem;
+  border-radius: 2px;
+  margin: 2px;
+  animation-fill-mode: both;
+  display: inline-block;
+  animation: line-scale-pulse-out-rapid 0.9s -0.5s infinite cubic-bezier(0.11, 0.49, 0.38, 0.78); }
+  .line-scale-pulse-out-rapid > div:nth-child(2), .line-scale-pulse-out-rapid > div:nth-child(4) {
+       animation-delay: -0.25s !important; }
+  .line-scale-pulse-out-rapid > div:nth-child(1), .line-scale-pulse-out-rapid > div:nth-child(5) {
+       animation-delay: 0s !important; }
+
+
+.loader-animation-enter, .loader-animation-appear {
+  opacity: 0.01;
+}
+
+.loader-animation-enter.loader-animation-enter-active, .loader-animation-appear.loader-animation-appear-active {
+  opacity: 1.0;
+  transition: opacity 300ms ease-in;
+}
+
+.loader-animation-leave {
+  visibility:hidden;
+  height:0px;
+  width:0px;
+  opacity:1.0;
+}
+
+.loader-animation-leave.loader-animation-leave-active {
+  opacity:0;
+  transition: opacity 300ms ease-in;
+}
diff --git a/skyquake/plugins/composer/src/src/styles/ModalOverlay.scss b/skyquake/plugins/composer/src/src/styles/ModalOverlay.scss
new file mode 100644 (file)
index 0000000..f17992f
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'main';
+.ModalOverlay {
+       display: none;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+       background-color: transparent;
+       .panel-body {
+               position: static;
+               padding: 1.25em;
+       }
+       &.-is-visible {
+               display: block;
+               z-index: 100;
+               position: absolute;
+               top: 0;
+               left: 0;
+               right: 0;
+               bottom: 0;
+       }
+       .background {
+               position: absolute;
+               top: 0;
+               left: 0;
+               right: 0;
+               bottom: 0;
+               background-color: #323232;
+               opacity: 0.8;
+               z-index: 0;
+       }
+       .foreground {
+               position: absolute;
+               top: 0;
+               left: 0;
+               right: 0;
+               bottom: 0;
+               z-index: 1;
+               .ui {
+                       position: fixed;
+                       top: 50%;
+                       left: 50%;
+                       transform: translate(-50%, -50%);
+                       display: inline-block;
+                       font-size: 1.5em;
+                       border-radius: 8px;
+                       h1 {
+                               background-color: white;
+                       }
+                       .actions {
+                               position: fixed;
+                               top: 50%;
+                               left: 50%;
+                               transform: translate(-50%, -50%);
+                               display: inline-block;
+                               font-size: 1em;
+                               border-radius: 8px;
+                               .action {
+                                       white-space: nowrap;
+                                       cursor: pointer;
+                                       margin: 12px;
+                               }
+                               h1 {
+                                       background-color: white;
+                               }
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/ResizableManager.scss b/skyquake/plugins/composer/src/src/styles/ResizableManager.scss
new file mode 100644 (file)
index 0000000..c49918e
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.-is-show-resize-cursor-col-resize {
+       cursor: col-resize !important;
+       *:hover {
+               cursor: inherit !important;
+       }
+}
+.-is-show-resize-cursor-row-resize {
+       cursor: row-resize !important;
+       *:hover {
+               cursor: inherit !important;
+       }
+}
+.-is-show-resize-cursor-nesw-resize {
+       cursor: nesw-resize !important;
+       *:hover {
+               cursor: inherit !important;
+       }
+}
+.-is-show-resize-cursor-nwse-resize {
+       cursor: nwse-resize !important;
+       *:hover {
+               cursor: inherit !important;
+       }
+}
+
+body.resizing * {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+       -moz-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/RiftHeader.scss b/skyquake/plugins/composer/src/src/styles/RiftHeader.scss
new file mode 100644 (file)
index 0000000..34d0f17
--- /dev/null
@@ -0,0 +1,52 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+
+.RiftHeader {
+       .header-app {
+               background-color: #f1f1f1;
+           height: 131px;
+           padding: 20px 0;
+           position: relative;
+
+           h1 {
+                       background: url('../images/header-logo.png') no-repeat left center;
+                       height: 51px;
+                       line-height: 51px;
+                       margin-left: 80px;
+                       padding-left: 118px;
+                       position: absolute;
+                       left: 0;
+                       text-transform: uppercase;
+                       font-size: 1.625rem;
+                       font-weight: normal;
+           }
+       }
+
+       div {
+               background-color: #f1f1f1;
+               padding-left: 1.25rem;
+               display: flex;
+               margin: 0 0 0.5rem 0;
+
+               a {
+                       cursor: pointer;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/ToggleElement.scss b/skyquake/plugins/composer/src/src/styles/ToggleElement.scss
new file mode 100644 (file)
index 0000000..d116b8f
--- /dev/null
@@ -0,0 +1,22 @@
+
+/* simple toggle behavior (requires js to change data-toggle value to 'true' or add class '-is-toggled' */
+[data-toggle] {
+       .toggle-show-less {
+               display: inline;
+       }
+       .toggle-show-more {
+               display: none;
+       }
+}
+[data-toggle="true"],
+[data-toggle].-is-toggled {
+       + .toggleable {
+               display: none !important;
+       }
+       .toggle-show-more {
+               display: inline !important;
+       }
+       .toggle-show-less {
+               display: none !important;
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/TooltipManager.scss b/skyquake/plugins/composer/src/src/styles/TooltipManager.scss
new file mode 100644 (file)
index 0000000..91117c5
--- /dev/null
@@ -0,0 +1,42 @@
+
+$tooltip-arrow-width: 15px;
+$tooltip-background-color: #002b36;
+$tooltip-foreground-color: #93a1a1;
+
+.tooltip-indicator {
+       position: fixed;
+       // TooltipManager.js will set top, left pragmatically
+       z-index: 1;
+       .tooltip-indicator-content {
+               position: relative;
+               display: block;
+               color: $tooltip-foreground-color;
+               background: $tooltip-background-color;
+               margin-left: -50%;
+               margin-right: 50%;
+               margin-top: 15px;
+               padding: 9px;
+               border-radius: 7px;
+       }
+       > i {
+               position: absolute;
+               top: 2px;
+               left: -15px;
+               // TooltipManager will set top, left pragmatically
+               &.arrow-up {
+                       width: 0;
+                       height: 0;
+                       border-left: $tooltip-arrow-width solid transparent;
+                       border-right: $tooltip-arrow-width solid transparent;
+
+                       border-bottom: $tooltip-arrow-width solid $tooltip-background-color;
+               }
+       }
+
+       span {
+               val {
+                       margin-left: 5px;
+                       color: #eee8d5;
+               }
+       }
+}
diff --git a/skyquake/plugins/composer/src/src/styles/_ColorGroups.scss b/skyquake/plugins/composer/src/src/styles/_ColorGroups.scss
new file mode 100644 (file)
index 0000000..b0ea3fb
--- /dev/null
@@ -0,0 +1,31 @@
+
+/**
+These colors are also defined in ColorGroups.js. Hint: ColorGroups.js has a convenience function to generate these variables
+so you can output to console and then copy and paste them here. It saves typing/copy/pasting across the two files.
+**/
+
+$nsd-primary-color: #6c71c4;
+$nsd-secondary-color: #6c71c4;
+
+$vld-primary-color: #073642;
+$vld-secondary-color: #073642;
+
+$internal-vld-primary-color: #073642;
+$internal-vld-secondary-color: #073642;
+
+$vdu-primary-color: #859900;
+$vdu-secondary-color: #859900;
+
+$vnfd-primary-color: #268bd2;
+$vnfd-secondary-color: #268bd2;
+
+$constituent-vnfd-primary-color: #268bd2;
+$constituent-vnfd-secondary-color: #268bd2;
+
+$vnffgd-primary-color: #2aa198;
+$vnffgd-secondary-color: #2aa198;
+
+$common-primary-color: black;
+$common-secondary-color: white;
+$common-background-color: white;
+$common-foreground-color: black;
\ No newline at end of file
diff --git a/skyquake/plugins/composer/src/src/styles/_main.scss b/skyquake/plugins/composer/src/src/styles/_main.scss
new file mode 100644 (file)
index 0000000..15ff765
--- /dev/null
@@ -0,0 +1,455 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'variables';
+
+path[data-outline-indicator-svg-outline-path] {
+       stroke-dasharray: 0;
+       stroke: #b58900;
+       stroke-width: 5px;
+}
+
+$font-path: '../assets';
+$robo-black: $font-path + '/Roboto-Black-webfont.woff';
+$robo-black-italic: $font-path + '/Roboto-BlackItalic-webfont.woff';
+$robo-bold: $font-path + '/Roboto-Bold-webfont.woff';
+$robo-bold-italic: $font-path + '/Roboto-BoldItalic-webfont.woff';
+$robo-light: $font-path + '/Roboto-Light-webfont.woff';
+$robo-light-italic: $font-path + '/Roboto-LightItalic-webfont.woff';
+$robo-medium: $font-path + '/Roboto-Medium-webfont.woff';
+$robo-medium-italic: $font-path + '/Roboto-MediumItalic-webfont.woff';
+$robo-reg: $font-path + '/Roboto-Regular-webfont.woff';
+$robo-reg-italic: $font-path + '/Roboto-Italic-webfont.woff';
+$robo-thin: $font-path + '/Roboto-Thin-webfont.woff';
+$robo-thin-italic: $font-path + '/Roboto-ThinItalic-webfont.woff';
+
+$robo-cond-bold: $font-path + '/RobotoCondensed-Bold-webfont.woff';
+$robo-cond-bold-italic: $font-path + '/RobotoCondensed-BoldItalic-webfont.woff';
+$robo-cond-light: $font-path + '/RobotoCondensed-Light-webfont.woff';
+$robo-cond-light-italic: $font-path + '/RobotoCondensed-LightItalic-webfont.woff';
+$robo-cond-reg: $font-path + '/RobotoCondensed-Regular-webfont.woff';
+$robo-cond-reg-italic: $font-path + '/RobotoCondensed-Italic-webfont.woff';
+
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-thin) format('woff');
+  font-weight: 100;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-thin-italic) format('woff');
+  font-weight: 100;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-light) format('woff');
+  font-weight: 200;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-light-italic) format('woff');
+  font-weight: 200;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-reg) format('woff');
+  font-weight: 400;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-reg-italic) format('woff');
+  font-weight: 400;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-medium) format('woff');
+  font-weight: 500;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-medium-italic) format('woff');
+  font-weight: 500;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-bold) format('woff');
+  font-weight: 700;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-bold-italic) format('woff');
+  font-weight: 700;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-black) format('woff');
+  font-weight: 800;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'Roboto';
+  src: url($robo-black-italic) format('woff');
+  font-weight: 800;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'RobotoCondensed';
+  src: url($robo-cond-light) format('woff');
+  font-weight: 100;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'RobotoCondensed';
+  src: url($robo-cond-light-italic) format('woff');
+  font-weight: 100;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'RobotoCondensed';
+  src: url($robo-cond-reg) format('woff');
+  font-weight: 400;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'RobotoCondensed';
+  src: url($robo-cond-reg-italic) format('woff');
+  font-weight: 400;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'RobotoCondensed';
+  src: url($robo-cond-bold) format('woff');
+  font-weight: 700;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'RobotoCondensed';
+  src: url($robo-cond-bold-italic) format('woff');
+  font-weight: 700;
+  font-style: italic;
+}
+
+$font-family-serif: Georgia, Times, 'Times New Roman', serif;
+$font-family-sans-serif: Roboto, Helvetica, Arial, sans-serif;
+$font-family-display: $font-family-sans-serif;
+$font-family-icons: 'FontAwesome';
+$font-family-default: $font-family-sans-serif;
+
+html, body {
+       background: $primary-bg-color;
+       cursor: auto;
+       font-family: $font-family-sans-serif;
+       overflow: hidden;
+}
+
+::-webkit-scrollbar {
+       //display: none;
+}
+
+html {
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+}
+
+* {
+       margin: 0;
+       border: 0;
+       padding: 0;
+       border-collapse: collapse;
+}
+
+*, *:before, *:after {
+       -webkit-box-sizing: inherit;
+       -moz-box-sizing: inherit;
+       box-sizing: inherit;
+}
+
+h1 {
+       margin: 0;
+       padding: 3px 6px;
+       color: #323232;
+       font-size: 0.75em;
+       font-weight: normal;
+       text-align: center;
+       font-variant-caps: all-small-caps;
+       font-variant: small-caps;
+       text-transform: uppercase;
+}
+
+img {
+       vertical-align: middle;
+}
+
+button,
+input[type="image"] {
+
+    box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+    color: #000000;
+    display: inline-block;
+    font-size: 12px;
+    padding: 8px 34px;
+    text-decoration: none;
+    text-transform: uppercase;
+
+       &:hover {
+               background-color: #7E9BC1;
+               color:#ffffff;
+       }
+       &:active, &:visited{
+               background-color:#4C5E74;
+               color:#ffffff;
+       }
+
+       &.-selected {
+               background-color: rgb(159, 196, 244);
+       }
+
+}
+
+input[type="image"] {
+       width: 28px;
+       height: 28px;
+       margin-right: 12px;
+       border: 0;
+       border-radius: 4px;
+       padding: 4px;
+}
+
+input,
+select,
+textarea {
+       height: 25px;
+       line-height: 25px;
+       max-width: 100%;
+       min-width: 100%;
+       margin: 0;
+       padding: 0 8px;
+       border: 1px solid $field-background-color !important;;
+       border-radius: $field-border-radius;
+       color: #002b36;
+       background-color: $field-background-color !important;
+       vertical-align: top;
+       &:focus {
+               color: #002b36;
+               background-color: white !important;
+       }
+       &::-webkit-input-placeholder {
+               color: #eee8d5 !important;
+       }
+
+       &:-moz-placeholder { /* Firefox 18- */
+               color: #eee8d5 !important;
+       }
+
+       &::-moz-placeholder {  /* Firefox 19+ */
+               color: #eee8d5 !important;
+       }
+
+       &:-ms-input-placeholder {
+               color: #eee8d5 !important;
+       }
+}
+
+select {
+       padding-right: 0;
+       margin-right: 0;
+       -moz-appearance: none;
+       text-indent: 0.01px;
+       text-overflow: '';
+       -webkit-appearance: none;
+       -webkit-border-radius: $field-border-radius;
+       &.-value-not-set {
+               color: #eee8d5;
+       }
+}
+
+select {
+       appearance: none; // using -prefix-free http://leaverou.github.io/prefixfree/
+    background: $field-background-color url(../../../node_modules/open-iconic/svg/caret-bottom.svg) no-repeat right 6px center;
+       background-size: 10px;
+       border: {
+               color: $field-background-color;
+               radius: $field-border-radius;
+               style: solid;
+               width: 1px;
+       }
+}
+
+// Removes default arrow for IE10+
+// IE 8/9 get dafault arrow which covers caret image
+// as long as caret image is small than and positioned
+// behind default arrow
+select::-ms-expand {
+       display: none;
+}
+
+textarea {
+       height: 50px;
+}
+
+input[name$="id"],
+input.-is-guid {
+       font-size: 10px;
+       font-family: monospace;
+}
+
+.ContentEditableDiv {
+       margin: 0;
+       border: 0;
+       padding: 0;
+       overflow: hidden;
+       border-radius: $field-border-radius;
+       height: 25px;
+       line-height: 25px;
+}
+
+.btn-group {
+       white-space: nowrap;
+       button {
+               border-right: 1px solid $button-border-color;
+               &:first-of-type {
+                       border-top-left-radius: 2px;
+                       border-bottom-left-radius: 2px;
+               }
+               &:last-of-type {
+                       border-right: none;
+                       border-top-right-radius: 2px;
+                       border-bottom-right-radius: 2px;
+               }
+       }
+}
+
+.panel {
+       overflow: hidden;
+       -ms-overflow-style: -ms-autohiding-scrollbar;
+       background-color: $panel-bg-color;
+       > div {
+               min-width: 200px;
+       }
+}
+.panel-header {
+       h1 {
+               padding: 16px;
+               white-space: nowrap;
+               text-align: center;
+       }
+}
+.panel-body {
+       position: absolute;
+       overflow: hidden;
+       &:hover {
+               overflow: auto;
+       }
+       -ms-overflow-style: -ms-autohiding-scrollbar;
+       top: 111px;
+       bottom: 0px;
+       left: 0;
+       right: 0;
+
+
+}
+.panel-footer {
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       height: 40px;
+       padding: 0 12px;
+       background-color: $panel-bg-color-contrast;
+       border-top: 1px solid $panel-border-color-light;
+       white-space: nowrap;
+}
+
+.welcome-message {
+       margin: 20px;
+       color: #06173c;
+       font-size: x-large;
+       font-weight: 200;
+       .Button {
+               display: inline-block;
+       }
+}
+
+/* react-tooltip overrides */
+.__react_component_tooltip {
+       transition: opacity 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000) !important;
+}
+
+/* simple css-only drop-down menu */
+.menu {
+       display: inline-flex;
+       position: relative;
+       z-index: 9999;
+       > .Button:after {
+               content: "ˇ";
+               position: absolute;
+               right: 4px;
+               bottom: -13px;
+               font-size: 20px;
+       }
+       .sub-menu {
+               display: none;
+               position: absolute;
+               top: 36px;
+               left: -4px;
+               padding: 4px;
+               background-color: #f1f1f1;
+               box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+               border-radius: 3px;
+               .Button {
+                       display: block;
+                       text-align: left;
+               }
+               &:hover {
+                       display: block;
+               }
+       }
+       > .Button:hover .sub-menu {
+               display: block;
+       }
+       &:hover .sub-menu {
+               display: block;
+       }
+}
+
+.descriptor {
+       text {
+               &.badge {
+                       font-weight: 100;
+                       font-size: 12px;
+                       text-anchor: middle;
+                       fill: white;/* font color */
+                       stroke: white !important;/* font color */
+               }
+       }
+}
+
+.hint {
+       margin: 5px;
+}
diff --git a/skyquake/plugins/composer/src/src/styles/_variables.scss b/skyquake/plugins/composer/src/src/styles/_variables.scss
new file mode 100644 (file)
index 0000000..64e5751
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+$primary-bg-color: #f1f1f1;
+$primary-contrast-bg-color: #cbd1d1;
+$primary-selected-bg-color: rgb(159, 196, 244);
+
+$button-bg-color: rgb(225, 225, 225);
+$button-border-color: rgba(169, 169, 169, 0.5);
+
+$panel-border-color: rgba(143, 143, 143, 0.5);
+$panel-border-color-light: lighten($panel-border-color, 30%);
+$panel-bg-color: #e5e5e5;
+$panel-bg-color-contrast: $primary-contrast-bg-color;
+
+$section-border-color: rgb(175, 175, 185);
+
+$panel-font-color: #666;
+
+$primary-hover-fg-color: rgb(0, 0, 0);
+$primary-hover-bg-color: #7E9BC1;
+$text-secondary-color: #EF8354;
+
+
+$green: #31D2B1;
+$black: #2D3036;
+$white: #F8F9FC;
+$headers: #EFF5FE;
+$grey: #ABB6C6;
+
+$field-border-radius: 3px;
+$field-background-color: white;
+$child-indent-left-right-margin: 5px;
+
+$img-path: '../images';
diff --git a/skyquake/plugins/composer/test/helpers/pack/phantomjs-shims.js b/skyquake/plugins/composer/test/helpers/pack/phantomjs-shims.js
new file mode 100644 (file)
index 0000000..2d6594a
--- /dev/null
@@ -0,0 +1,52 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+(function() {
+
+var Ap = Array.prototype;
+var slice = Ap.slice;
+var Fp = Function.prototype;
+
+if (!Fp.bind) {
+  // PhantomJS doesn't support Function.prototype.bind natively, so
+  // polyfill it whenever this module is required.
+  Fp.bind = function(context) {
+    var func = this;
+    var args = slice.call(arguments, 1);
+
+    function bound() {
+      var invokedAsConstructor = func.prototype && (this instanceof func);
+      return func.apply(
+        // Ignore the context parameter when invoking the bound function
+        // as a constructor. Note that this includes not only constructor
+        // invocations using the new keyword but also calls to base class
+        // constructors such as BaseClass.call(this, ...) or super(...).
+        !invokedAsConstructor && context || this,
+        args.concat(slice.call(arguments))
+      );
+    }
+
+    // The bound function must share the .prototype of the unbound
+    // function so that any object created by one constructor will count
+    // as an instance of both constructors.
+    bound.prototype = func.prototype;
+
+    return bound;
+  };
+}
+})();
diff --git a/skyquake/plugins/composer/test/helpers/test-clean-input-output-model.json b/skyquake/plugins/composer/test/helpers/test-clean-input-output-model.json
new file mode 100644 (file)
index 0000000..2868f91
--- /dev/null
@@ -0,0 +1,583 @@
+[
+       {
+               "id": "GUID-1",
+               "name": "RIFT.ware™ NS Descriptors Catalog",
+               "short-name": "rift.ware-nsd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "nsd",
+               "descriptors": [
+                       {
+                               "id": "ba1dfbcc-626b-11e5-998d-6cb3113b406f",
+                               "name": "ping-pong-nsd",
+                               "short-name": "ping-pong-nsd",
+                               "vendor": "RIFT.io",
+                               "logo": "rift.png",
+                               "description": "Toy NS",
+                               "version": "1.0",
+                               "connection-point": [
+                                       {
+                                               "name": "ping-pong-nsd/cp0"
+                                       },
+                                       {
+                                               "name": "ping-pong-nsd/cp1"
+                                       }
+                               ],
+                               "vld": [
+                                       {
+                                               "id": "ba1c03a8-626b-11e5-998d-6cb3113b406f",
+                                               "name": "ping-pong-vld",
+                                               "short-name": "ping-pong-vld",
+                                               "vendor": "RIFT.io",
+                                               "description": "Toy VL",
+                                               "version": "1.0",
+                                               "type": "ELAN",
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1"
+                                                       },
+                                                       {
+                                                               "member-vnf-index-ref": 2,
+                                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1"
+                                                       }
+                                               ],
+                                               "provider-network": {
+                                                       "name": "physnet1",
+                                                       "overlay-type": "VLAN"
+                                               }
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "member-vnf-index": 1,
+                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f"
+                                       },
+                                       {
+                                               "member-vnf-index": 2,
+                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f"
+                                       }
+                               ],
+                               "vnffgd": [{
+                                       "id": "1d6382bb-52fa-43b6-9489-d764a0a27da9",
+                                       "name": "vnffgd-5",
+                                       "short-name": "FG-1",
+                                       "vendor": "",
+                                       "description": "",
+                                       "version": "",
+                                       "rsp": [
+                                               {
+                                                       "id": "a10b372d-19a1-4d84-a246-82bfceddae12",
+                                                       "name": "rsp-6",
+                                                       "vnfd-connection-point-ref": [
+                                                               {
+                                                                       "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                                                                       "member-vnf-index-ref": 1,
+                                                                       "vnfd-connection-point-ref": "ping-vnfd/cp1"
+                                                               },
+                                                               {
+                                                                       "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                                                                       "member-vnf-index-ref": 2,
+                                                                       "vnfd-connection-point-ref": "pong-vnfd/cp0"
+                                                               }
+                                                       ]
+                                               }
+                                       ],
+                                       "classifier": [
+                                               {
+                                                       "id": "1-a5b8-45b5-8163-f2577555d561",
+                                                       "name": "classifier-1",
+                                                       "rsp-id-ref": "a10b372d-19a1-4d84-a246-82bfceddae12",
+                                                       "match-attributes": [{
+                                                               "id": "1",
+                                                               "ip-proto": "123.0.0.1",
+                                                               "source-ip-address": "10.4.0.1",
+                                                               "destination-ip-address": "10.4.0.2",
+                                                               "source-port": "1234",
+                                                               "destination-port": "4321"
+                                                       }]
+                                               },
+                                               {
+                                                       "id": "2-a5b8-45b5-8163-f2577555d561",
+                                                       "name": "classifier-2",
+                                                       "rsp-id-ref": "a10b372d-19a1-4d84-a246-82bfceddae12",
+                                                       "match-attributes": [{
+                                                               "id": "1",
+                                                               "ip-proto": "123.0.0.1",
+                                                               "source-ip-address": "10.4.0.1",
+                                                               "destination-ip-address": "10.4.0.2",
+                                                               "source-port": "1234",
+                                                               "destination-port": "4321"
+                                                       }]
+                                               },
+                                               {
+                                                       "id": "3-a5b8-45b5-8163-f2577555d561",
+                                                       "name": "classifier-3",
+                                                       "rsp-id-ref": "a10b372d-19a1-4d84-a246-82bfceddae12",
+                                                       "match-attributes": [{
+                                                               "id": "1",
+                                                               "ip-proto": "123.0.0.1",
+                                                               "source-ip-address": "10.4.0.1",
+                                                               "destination-ip-address": "10.4.0.2",
+                                                               "source-port": "1234",
+                                                               "destination-port": "4321"
+                                                       }]
+                                               },
+                                               {
+                                                       "id": "4-a5b8-45b5-8163-f2577555d561",
+                                                       "name": "classifier-4",
+                                                       "rsp-id-ref": "a10b372d-19a1-4d84-a246-82bfceddae12",
+                                                       "match-attributes": [{
+                                                               "id": "1",
+                                                               "ip-proto": "123.0.0.1",
+                                                               "source-ip-address": "10.4.0.1",
+                                                               "destination-ip-address": "10.4.0.2",
+                                                               "source-port": "1234",
+                                                               "destination-port": "4321"
+                                                       }]
+                                               }
+
+                                       ]
+                               }]
+                       },
+                       {
+                               "id": "test1-626b-11e5-998d-6cb3113b406f",
+                               "name": "TEST ping-pong-nsd",
+                               "short-name": "test-ping-pong-nsd",
+                               "vendor": "RIFT.io",
+                               "description": "TEST NS",
+                               "version": "1.0",
+                               "connection-point": [
+                                       {
+                                               "name": "ping-pong-nsd/cp0"
+                                       },
+                                       {
+                                               "name": "ping-pong-nsd/cp1"
+                                       }
+                               ],
+                               "vld": [
+                                       {
+                                               "id": "test1-ba1c03a8-626b-11e5-998d-6cb3113b406f",
+                                               "name": "test1-ping-pong-vld",
+                                               "short-name": "test1-ping-pong-vld",
+                                               "vendor": "RIFT.io",
+                                               "description": "test1 VL",
+                                               "version": "1.0",
+                                               "type": "ELAN",
+                                               "vnfd-connection-point-ref": [
+                                                       {
+                                                               "member-vnf-index-ref": 1,
+                                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1"
+                                                       },
+                                                       {
+                                                               "member-vnf-index-ref": 2,
+                                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1"
+                                                       }
+                                               ],
+                                               "provider-network": {
+                                                       "name": "physnet1",
+                                                       "overlay-type": "VLAN"
+                                               }
+                                       }
+                               ],
+                               "constituent-vnfd": [
+                                       {
+                                               "member-vnf-index": 1,
+                                               "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f"
+                                       },
+                                       {
+                                               "member-vnf-index": 2,
+                                               "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f"
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-2",
+               "name": "RIFT.ware™ VNF Descriptors Catalog",
+               "short-name": "rift.ware-vnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "vnfd",
+               "descriptors": [
+                       {
+                               "id": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                               "name": "ping-vnfd",
+                               "short-name": "ping-vnfd",
+                               "vendor": "RIFT.io",
+                               "description": "This is an example RIFT.ware VNF",
+                               "version": "1.0",
+                               "logo": "data:image/png",
+                               "internal-vld": [
+                                       {
+                                               "id": "ba1478fe-626b-11e5-998d-6cb3113b406f",
+                                               "name": "fabric",
+                                               "short-name": "fabric",
+                                               "description": "Virtual link for internal fabric",
+                                               "type": "ELAN"
+                                       }
+                               ],
+                               "connection-point": [
+                                       {
+                                               "name": "ping-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "ping-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "ba14a504-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "ba153744-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "ba153744-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "ping-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       },
+                       {
+                               "id": "ba1947da-626b-11e5-998d-6cb3113b406f",
+                               "name": "pong-vnfd",
+                               "short-name": "pong-vnfd",
+                               "vendor": "RIFT.io",
+                               "description": "This is an example RIFT.ware VNF",
+                               "version": "1.0",
+                               "logo": "",
+                               "internal-vld": [
+                                       {
+                                               "id": "ba195068-626b-11e5-998d-6cb3113b406f",
+                                               "name": "fabric",
+                                               "short-name": "fabric",
+                                               "description": "Virtual link for internal fabric",
+                                               "type": "ELAN",
+                                               "internal-connection-point-ref": [
+                                                       "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                       "ba198696-626b-11e5-998d-6cb3113b406f"
+                                               ]
+                                       }
+                               ],
+                               "connection-point": [
+                                       {
+                                               "name": "pong-vnfd/cp0",
+                                               "type": "VPORT"
+                                       },
+                                       {
+                                               "name": "pong-vnfd/cp1",
+                                               "type": "VPORT"
+                                       }
+                               ],
+                               "vdu": [
+                                       {
+                                               "id": "1-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "ba198696-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "ba197a98-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "ba198696-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       },
+                                       {
+                                               "id": "2-626b-11e5-998d-6cb3113b406f",
+                                               "name": "iovdu",
+                                               "count": 2,
+                                               "vm-flavor": {
+                                                       "vcpu-count": 4,
+                                                       "memory-mb": 16384,
+                                                       "storage-gb": 16
+                                               },
+                                               "guest-epa": {
+                                                       "trusted-execution": true,
+                                                       "mempage-size": "PREFER_LARGE",
+                                                       "cpu-pinning-policy": "DEDICATED",
+                                                       "cpu-thread-pinning-policy": "AVOID",
+                                                       "numa-node-policy": {
+                                                               "node-cnt": 2,
+                                                               "mem-policy": "PREFERRED",
+                                                               "node": [
+                                                                       {
+                                                                               "id": 0,
+                                                                               "vcpu": [
+                                                                                       "0",
+                                                                                       "1"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       },
+                                                                       {
+                                                                               "id": 1,
+                                                                               "vcpu": [
+                                                                                       "2",
+                                                                                       "3"
+                                                                               ],
+                                                                               "memory-mb": 8192
+                                                                       }
+                                                               ]
+                                                       }
+                                               },
+                                               "vswitch-epa": {
+                                                       "ovs-acceleration": "DISABLED",
+                                                       "ovs-offload": "DISABLED"
+                                               },
+                                               "hypervisor-epa": {
+                                                       "type": "PREFER_KVM"
+                                               },
+                                               "host-epa": {
+                                                       "cpu-model": "PREFER_SANDYBRIDGE",
+                                                       "cpu-arch": "PREFER_X86_64",
+                                                       "cpu-vendor": "PREFER_INTEL",
+                                                       "cpu-socket-count": "PREFER_TWO",
+                                                       "cpu-feature": [
+                                                               "PREFER_AES",
+                                                               "PREFER_CAT"
+                                                       ]
+                                               },
+                                               "image": "rw_openstack.qcow2",
+                                               "internal-connection-point": [
+                                                       {
+                                                               "id": "21-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       },
+                                                       {
+                                                               "id": "22-626b-11e5-998d-6cb3113b406f",
+                                                               "type": "VPORT"
+                                                       }
+                                               ],
+                                               "internal-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vdu-internal-connection-point-ref": "21-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vdu-internal-connection-point-ref": "22-626b-11e5-998d-6cb3113b406f",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ],
+                                               "external-interface": [
+                                                       {
+                                                               "name": "eth0",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp0",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       },
+                                                       {
+                                                               "name": "eth1",
+                                                               "vnfd-connection-point-ref": "pong-vnfd/cp1",
+                                                               "virtual-interface": {
+                                                                       "type": "VIRTIO"
+                                                               }
+                                                       }
+                                               ]
+                                       }
+                               ]
+                       }
+               ]
+       },
+       {
+               "id": "GUID-3",
+               "name": "RIFT.ware™ PNF Descriptors Catalog",
+               "short-name": "rift.ware-pnfd-cat",
+               "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+               "vendor": "RIFT.io",
+               "version": "",
+               "created-on": "",
+               "type": "pnfd",
+               "descriptors": []
+       }
+]
\ No newline at end of file
diff --git a/skyquake/plugins/composer/test/spec/components/ButtonSpec.js b/skyquake/plugins/composer/test/spec/components/ButtonSpec.js
new file mode 100644 (file)
index 0000000..2738e65
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/*global describe, beforeEach, it, expect */
+'use strict';
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils'
+
+import Button from '../../../src/components/Button'
+
+describe('Button', () => {
+       it('says hi', () => {
+               expect('hi').toBe('hi');
+       });
+       // todo write real tests for the components
+});
diff --git a/skyquake/plugins/composer/test/spec/libraries/DescriptorModelFactorySpec.js b/skyquake/plugins/composer/test/spec/libraries/DescriptorModelFactorySpec.js
new file mode 100644 (file)
index 0000000..66376b9
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 2/8/16.
+ */
+/*global describe, beforeEach, it, expect, xit, xdescribe */
+
+'use strict';
+import _ from 'lodash'
+import DescriptorModelSerializer from '../../../src/libraries/model/DescriptorModelSerializer'
+import DescriptorModelFactory from '../../../src/libraries/model/DescriptorModelFactory'
+import SampleCatalogs from 'json!../../../src/assets/ping-pong-catalog.json'
+import TestCatalogs from 'json!../../helpers/test-clean-input-output-model.json'
+
+describe('DescriptorModelFactory', () => {
+       it('exists', () => {
+               expect(DescriptorModelFactory).toBeDefined();
+       });
+       describe('buildCatalogItemFactory', () => {
+               let containers;
+               beforeEach(() => {
+                       const nsdJson = _.cloneDeep(SampleCatalogs[0].descriptors[0]);
+                       // the CatalogItemsStore adds the type to the uiState field when the catalog is loaded
+                       nsdJson.uiState = {type: 'nsd'};
+                       // the user will open a catalog item by dbl clicking on it in the ui that is when we
+                       // parse the item into a DescriptorModel class instance as follows....
+                       const factory = DescriptorModelFactory.buildCatalogItemFactory(SampleCatalogs);
+                       // the result is a list of all the containers defined with then NSD JSON data
+                       containers = [nsdJson].reduce(factory, []);
+               });
+               it('ignores an empty object', () => {
+                       const factory = DescriptorModelFactory.buildCatalogItemFactory([]);
+                       const result = [{}].reduce(factory, []);
+                       expect(result).toEqual([]);
+               });
+               it('parses an NSD object', () => {
+                       const nsdJson = _.cloneDeep(SampleCatalogs[0].descriptors[0]);
+                       nsdJson.uiState = {type: 'nsd'};
+                       const factory = DescriptorModelFactory.buildCatalogItemFactory(SampleCatalogs);
+                       const result = [nsdJson].reduce(factory, [])[0];
+                       expect(result.id).toEqual('ba1dfbcc-626b-11e5-998d-6cb3113b406f');
+               });
+               it('parses the constituent-vnfd classes', () => {
+                       const nsd = containers[0];
+                       const cvnfd = containers.filter(d => DescriptorModelFactory.isConstituentVnfd(d));
+                       expect(nsd.constituentVnfd).toEqual(cvnfd);
+               });
+               describe('ConstituentVnfd', () => {
+                       it('connection-points derive from referenced VNFD', () => {
+                               const constituentVNFDs = containers.filter(d => DescriptorModelFactory.isConstituentVnfd(d)).map(d => d.vnfdId);
+                               expect(constituentVNFDs).toEqual(['ba145e82-626b-11e5-998d-6cb3113b406f', 'ba1947da-626b-11e5-998d-6cb3113b406f']);
+                       });
+               });
+               describe('DescriptorModelSerializer', () => {
+                       it('outputs the same JSON that was parsed by the .buildCatalogItemFactory method', () => {
+                               const inputJSON = _.cloneDeep(TestCatalogs[0].descriptors[0]);
+                               inputJSON.uiState = {type: 'nsd'};
+                               const factory = DescriptorModelFactory.buildCatalogItemFactory(TestCatalogs);
+                               const parsedModel = [inputJSON].reduce(factory, []);
+                               const serialized = DescriptorModelSerializer.serialize(parsedModel[0].model);
+                               const expectedSerializedString = '{"id":"ba1dfbcc-626b-11e5-998d-6cb3113b406f","name":"ping-pong-nsd","short-name":"ping-pong-nsd","vendor":"RIFT.io","logo":"rift.png","description":"Toy NS","version":"1.0","connection-point":[{"name":"ping-pong-nsd/cp0"},{"name":"ping-pong-nsd/cp1"}],"vld":[{"id":"ba1c03a8-626b-11e5-998d-6cb3113b406f","name":"ping-pong-vld","short-name":"ping-pong-vld","vendor":"RIFT.io","description":"Toy VL","version":"1.0","type":"ELAN","vnfd-connection-point-ref":[{"member-vnf-index-ref":1,"vnfd-id-ref":"ba145e82-626b-11e5-998d-6cb3113b406f","vnfd-connection-point-ref":"ping-vnfd/cp1"},{"member-vnf-index-ref":2,"vnfd-id-ref":"ba1947da-626b-11e5-998d-6cb3113b406f","vnfd-connection-point-ref":"pong-vnfd/cp1"}],"provider-network":{"name":"physnet1","overlay-type":"VLAN"}}],"constituent-vnfd":[{"member-vnf-index":1,"vnfd-id-ref":"ba145e82-626b-11e5-998d-6cb3113b406f"},{"member-vnf-index":2,"vnfd-id-ref":"ba1947da-626b-11e5-998d-6cb3113b406f"}],"vnffgd":[{"id":"1d6382bb-52fa-43b6-9489-d764a0a27da9","name":"vnffgd-5","short-name":"FG-1","rsp":[{"id":"a10b372d-19a1-4d84-a246-82bfceddae12","name":"rsp-6","vnfd-connection-point-ref":[{"vnfd-id-ref":"ba145e82-626b-11e5-998d-6cb3113b406f","member-vnf-index-ref":1,"vnfd-connection-point-ref":"ping-vnfd/cp1"},{"vnfd-id-ref":"ba1947da-626b-11e5-998d-6cb3113b406f","member-vnf-index-ref":2,"vnfd-connection-point-ref":"pong-vnfd/cp0"}]}],"classifier":[{"id":"1-a5b8-45b5-8163-f2577555d561","name":"classifier-1","rsp-id-ref":"a10b372d-19a1-4d84-a246-82bfceddae12","match-attributes":[{"id":"1","ip-proto":"123.0.0.1","source-ip-address":"10.4.0.1","destination-ip-address":"10.4.0.2","source-port":"1234","destination-port":"4321"}]},{"id":"2-a5b8-45b5-8163-f2577555d561","name":"classifier-2","rsp-id-ref":"a10b372d-19a1-4d84-a246-82bfceddae12","match-attributes":[{"id":"1","ip-proto":"123.0.0.1","source-ip-address":"10.4.0.1","destination-ip-address":"10.4.0.2","source-port":"1234","destination-port":"4321"}]},{"id":"3-a5b8-45b5-8163-f2577555d561","name":"classifier-3","rsp-id-ref":"a10b372d-19a1-4d84-a246-82bfceddae12","match-attributes":[{"id":"1","ip-proto":"123.0.0.1","source-ip-address":"10.4.0.1","destination-ip-address":"10.4.0.2","source-port":"1234","destination-port":"4321"}]},{"id":"4-a5b8-45b5-8163-f2577555d561","name":"classifier-4","rsp-id-ref":"a10b372d-19a1-4d84-a246-82bfceddae12","match-attributes":[{"id":"1","ip-proto":"123.0.0.1","source-ip-address":"10.4.0.1","destination-ip-address":"10.4.0.2","source-port":"1234","destination-port":"4321"}]}]}]}';
+                               const result = JSON.stringify(serialized);
+                               expect(expectedSerializedString).toEqual(result);
+                       });
+               });
+       });
+});
diff --git a/skyquake/plugins/composer/test/spec/libraries/DescriptorModelSpec.js b/skyquake/plugins/composer/test/spec/libraries/DescriptorModelSpec.js
new file mode 100644 (file)
index 0000000..5388780
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 2/8/16.
+ */
+/*global describe, beforeEach, it, expect, xit */
+
+'use strict';
+import _ from 'lodash'
+import DescriptorModel from 'libraries/model/DescriptorModel'
+
+class TestDescriptorModel extends DescriptorModel {
+       constructor(model, parent) {
+               super(model, parent);
+       }
+}
+describe('DescriptorModel', () => {
+       let parent, child1, child2;
+       beforeEach(() => {
+               parent = new TestDescriptorModel({name: 'parent 1'});
+               child1 = new TestDescriptorModel({name: 'child 1'}, parent);
+               child2 = new TestDescriptorModel({name: 'child 2'}, parent);
+       });
+       it('creates a uid and stores it in the uiState field ":uid"', () => {
+               expect(child1.uid).toEqual(child1.model.uiState[':uid']);
+       });
+       describe('.constructor(model, parent)', () => {
+               it('creates child when parent is given on constructor', () => {
+                       const child = new TestDescriptorModel({name: 'test1'}, parent);
+                       expect(parent.children).toContain(child);
+               });
+       });
+       describe('.findChildByUid', () => {
+               it('finds an existing child', () => {
+                       const result = parent.findChildByUid(child2.uid);
+                       expect(result).toBe(child2);
+               });
+       });
+});
\ No newline at end of file
diff --git a/skyquake/plugins/composer/test/spec/libraries/SelectionManagerSpec.js b/skyquake/plugins/composer/test/spec/libraries/SelectionManagerSpec.js
new file mode 100644 (file)
index 0000000..580357c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/**
+ * Created by onvelocity on 2/8/16.
+ */
+/*global describe, beforeEach, it, expect, xit */
+
+'use strict';
+
+import SelectionManager from 'libraries/SelectionManager'
+
+describe('SelectionManager', () => {
+       it('selects things', () => {
+
+       });
+});
\ No newline at end of file
diff --git a/skyquake/plugins/composer/test/uploadServer/package.json b/skyquake/plugins/composer/test/uploadServer/package.json
new file mode 100644 (file)
index 0000000..c0789b6
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "name": "file_upload",
+  "version": "0.0.1",
+  "dependencies": {
+    "cors": "^2.7.1",
+    "express": "^4.10.2",
+    "multer": "^0.1.6"
+  }
+}
diff --git a/skyquake/plugins/composer/test/uploadServer/server.js b/skyquake/plugins/composer/test/uploadServer/server.js
new file mode 100644 (file)
index 0000000..9b7f40a
--- /dev/null
@@ -0,0 +1,225 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/*Define dependencies.*/
+
+var express = require('express');
+var multer = require('multer');
+var cors = require('cors');
+var launchpadServer = express();
+var apiServer = express();
+var done = false;
+var path = require('path');
+
+/*Configure the multer.*/
+
+//apiServer.use(function(req, res, next) {
+//     res.header('Access-Control-Allow-Origin', '*');
+//     res.header('Access-Control-Allow-Headers', '*');
+//     next();
+//});
+
+var uploadPayload = {
+       "events": [
+               {
+                       "timestamp": 1445452293.688965,
+                       "value": "onboard-started",
+                       "text": "onboarding process started"
+               },
+               {
+                       "timestamp": 1445452293.7836523,
+                       "value": "onboard-pkg-upload",
+                       "text": "uploading package"
+               },
+               {
+                       "timestamp": 1445452293.8315961,
+                       "value": "onboard-img-upload",
+                       "text": "uploading image"
+               },
+               {
+                       "timestamp": 1445452293.8316283,
+                       "value": "onboard-dsc-validation",
+                       "text": "descriptor validation"
+               },
+               {
+                       "timestamp": 1445452294.00448,
+                       "value": "onboard-success",
+                       "text": "onboarding process completed"
+               }
+       ],
+       "warnings": [],
+       "status": "success",
+       "errors": [
+               {
+                       "value": "onboard vnfd/ping_vnfd.xml",
+                       "timestamp": 1445452294.0032463
+               }
+       ]
+};
+
+var updatePayload = {
+       "events": [
+               {
+                       "timestamp": 1445452293.688965,
+                       "value": "update-started",
+                       "text": "updating process started"
+               },
+               {
+                       "timestamp": 1445452293.7836523,
+                       "value": "update-pkg-upload",
+                       "text": "uploading package"
+               },
+               {
+                       "timestamp": 1445452293.8315961,
+                       "value": "update-img-upload",
+                       "text": "uploading image"
+               },
+               {
+                       "timestamp": 1445452293.8316283,
+                       "value": "update-dsc-validation",
+                       "text": "descriptor validation"
+               },
+               {
+                       "timestamp": 1445452294.00448,
+                       "value": "update-success",
+                       "text": "updating process completed"
+               }
+       ],
+       "warnings": [],
+       "status": "success",
+       "errors": [
+               {
+                       "value": "update vnfd/ping_vnfd.xml",
+                       "timestamp": 1445452294.0032463
+               }
+       ]
+};
+
+var exportPayload = {
+       "events": [
+               {
+                       "timestamp": 1445452293.688965,
+                       "value": "update-started",
+                       "text": "download process started"
+               },
+               {
+                       "timestamp": 1445452293.7836523,
+                       "value": "update-pkg-upload",
+                       "text": "building package"
+               },
+               {
+                       "timestamp": 1445452293.8315961,
+                       "value": "update-img-upload",
+                       "text": "building image"
+               },
+               {
+                       "timestamp": 1445452293.8316283,
+                       "value": "update-dsc-validation",
+                       "text": "descriptor validation"
+               },
+               {
+                       "timestamp": 1445452294.00448,
+                       "value": "download-success",
+                       "text": "download process completed"
+               }
+       ],
+       "warnings": [],
+       "status": "success",
+       "errors": [
+               {
+                       "value": "download nsd/ping-pong-nsd.xml",
+                       "timestamp": 1445452294.0032463
+               }
+       ]
+};
+
+apiServer.use(cors());
+launchpadServer.use(cors());
+
+apiServer.use(multer({
+       dest: './uploads/',
+       rename: function (fieldname, filename) {
+               return filename + '-' + Date.now();
+       },
+       onFileUploadStart: function (file) {
+               console.log(file.originalname + ' is starting ...')
+       },
+       onFileUploadComplete: function (file) {
+               console.log(file.fieldname + ' uploaded to  ' + file.path)
+               done = true;
+       }
+}));
+
+/*Handling routes.*/
+
+launchpadServer.get('/launchpad/catalog', function (req, res) {
+       res.sendFile(path.join(__dirname, '../../src/assets/ping-pong-catalog.json'));
+});
+
+launchpadServer.delete('/launchpad/catalog/nsd/:id', function (req, res) {
+       res.end();
+});
+
+launchpadServer.put('/launchpad/catalog/nsd/:id', function (req, res) {
+       res.end();
+});
+
+apiServer.post('/api/upload', function (req, res) {
+       if (done == true) {
+               res.end('{"transaction_id": "' + Date.now() + '"}');
+       }
+});
+
+apiServer.get('/api/upload/:transaction_id/state', function (req, res) {
+       if (done == true) {
+               console.log('transaction id state request', req.params.transaction_id);
+               res.end(JSON.stringify(uploadPayload));
+       }
+});
+
+apiServer.post('/api/update', function (req, res) {
+       if (done == true) {
+               res.end('{"transaction_id": "' + Date.now() + '"}');
+       }
+});
+
+apiServer.get('/api/update/:transaction_id/state', function (req, res) {
+       if (done == true) {
+               console.log('transaction id state request', req.params.transaction_id);
+               res.end(JSON.stringify(updatePayload));
+       }
+});
+
+apiServer.get('/api/export', function (req, res) {
+       res.end('{"transaction_id": "' + Date.now() + '"}');
+});
+
+apiServer.get('/api/export/:transaction_id/state', function (req, res) {
+       console.log('transaction id state request', req.params.transaction_id);
+       res.end(JSON.stringify(exportPayload));
+});
+
+/*Run the servers.*/
+launchpadServer.listen(3000, function () {
+       console.log('LaunchPad Server listening on port 3000');
+});
+
+apiServer.listen(4567, function () {
+       console.log('API Server listening on port 4567');
+});
diff --git a/skyquake/plugins/composer/webpack.config.js b/skyquake/plugins/composer/webpack.config.js
new file mode 100644 (file)
index 0000000..b6ed534
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/*
+ * Webpack development server configuration
+ *
+ * This file is set up for serving the webpack-dev-server, which will watch for changes and recompile as required if
+ * the subfolder /webpack-dev-server/ is visited. Visiting the root will not automatically reload.
+ */
+'use strict';
+var path = require('path');
+var webpack = require('webpack');
+
+module.exports = {
+
+       output: {
+               filename: 'main.js',
+               publicPath: '/assets/'
+       },
+
+       cache: true,
+       debug: true,
+       devtool: 'sourcemap',
+       entry: [
+               'webpack/hot/only-dev-server',
+               './src/components/ComposerApp.js'
+       ],
+
+       stats: {
+               colors: true,
+               reasons: true
+       },
+
+       module: {
+               preLoaders: [
+                       {
+                               test: /\.(js|jsx)$/,
+                               exclude: /node_modules/,
+                               loader: 'eslint-loader'
+                       }
+               ],
+               loaders: [
+                       {
+                               test: /\.(js|jsx)$/,
+                               exclude: /node_modules/,
+                               loader: 'react-hot'
+                       }, {
+                               test: /\.(js|jsx)$/,
+                               exclude: /node_modules/,
+                               loader: 'babel-loader',
+                               query: {
+                                       presets: ['react', 'es2015']
+                               }
+                       }, {
+                               test: /\.scss/,
+                               loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded'
+                       }, {
+                               test: /\.css$/,
+                               loader: 'style-loader!css-loader'
+                       }, {
+                               test: /\.(jpg|woff|woff2|png)$/,
+                               loader: 'url-loader'
+                       }, {
+                               test: /\.(svg)(\?[a-z0-9]+)?$/i,
+                               loader: "file-loader"
+                       }
+               ]
+       },
+       resolve: {
+               alias: {
+                       'styles': path.join(process.cwd(), './src/styles/'),
+                       'libraries': path.join(process.cwd(), './src/libraries/'),
+                       'components': path.join(process.cwd(), './src/components/'),
+                       //'stores': '../../../src/stores/',
+                       //'actions': '../../../src/actions/',
+                       'helpers': path.join(process.cwd(), './test/helpers/')
+               }
+       },
+
+       plugins: [
+               new webpack.HotModuleReplacementPlugin()
+       ]
+
+};
diff --git a/skyquake/plugins/composer/webpack.production.config.js b/skyquake/plugins/composer/webpack.production.config.js
new file mode 100644 (file)
index 0000000..bf2747a
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+/*
+ * Webpack distribution configuration
+ *
+ * This file is set up for serving the distribution version. It will be compiled to dist/ by default
+ */
+
+'use strict';
+
+var webpack = require('webpack');
+var path = require('path');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+module.exports = {
+       devtool: 'source-map',
+       output: {
+               publicPath: 'assets/',
+               path: 'public/assets/',
+               filename: 'src/main.js'
+       },
+
+       debug: false,
+       entry: [path.resolve(__dirname) + '/src/index.js'],
+
+       stats: {
+               colors: true,
+               reasons: false
+       },
+       resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils',
+            'styles': path.join(process.cwd(), './src/styles/'),
+                       'libraries': path.join(process.cwd(), './src/libraries/'),
+                       'components': path.join(process.cwd(), './src/components/'),
+                       //'stores': '../../../src/stores/',
+                       //'actions': '../../../src/actions/',
+                       'helpers': path.join(process.cwd(), './test/helpers/')
+        }
+    },
+       plugins: [
+               // new webpack.optimize.DedupePlugin(),
+               // new webpack.optimize.UglifyJsPlugin(),
+               // new webpack.optimize.OccurenceOrderPlugin(),
+               // new webpack.optimize.AggressiveMergingPlugin(),
+               // new webpack.NoErrorsPlugin(),
+               new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="app"></div>'
+        })
+       ],
+
+       module: {
+               noParse: [/autoit.js/],
+               // preLoaders: [
+               //      {
+               //              test: /\.(js|jsx)$/,
+               //              exclude: /node_modules/,
+               //              loader: 'eslint-loader'
+               //      }
+               // ],
+               loaders: [
+                       {
+                               test: /\.(js|jsx)$/,
+                               exclude: /node_modules/,
+                               loader: 'babel-loader',
+                               query: {
+                                       presets: ['es2015', 'stage-0', 'react']
+                               }
+                       }, {
+                               test: /\.css$/,
+                               loader: 'style-loader!css-loader'
+                       }, {
+                               test: /\.scss/,
+                               loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded&includePaths[]='+ path.resolve(frameworkPath)
+                       },{
+                               test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                               loader: "file-loader"
+                       },
+                       { test: /\.json$/, loader: "json-loader" },
+               ]
+       }
+};
diff --git a/skyquake/plugins/debug/CMakeLists.txt b/skyquake/plugins/debug/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6d2e56d
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  debug
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/debug/debug-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/debug/debug-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/debug/api/debug.js b/skyquake/plugins/debug/api/debug.js
new file mode 100644 (file)
index 0000000..5d6e0ea
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+
+var Promise = require('bluebird');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var request = utils.request;
+var constants = require('../../../framework/core/api_utils/constants.js');
+var APIVersion = '/v1';
+var crashDetails = {};
+var debug = {};
+var _ = require('lodash');
+
+crashDetails.get = function(req) {
+  var api_server = req.query["api_server"];
+
+  return new Promise(function(resolve, reject) {
+    var requestHeaders = {};
+    _.extend(requestHeaders,
+      constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+      });
+    request({
+        url: utils.confdPort(api_server) + APIVersion +'/api/operational/crash?deep',
+        type: 'GET',
+        headers: requestHeaders,
+        forever: constants.FOREVER_ON,
+        rejectUnauthorized: false,
+      },
+      function(error, response, body) {
+        var data;
+        console.log(error);
+        if (utils.validateResponse('crashDetails.get', error, response, body, resolve, reject)) {
+          try {
+            data = JSON.parse(response.body)['rwshell-mgmt:crash'].list.vm;
+          } catch (e) {
+            return reject(e);
+          }
+
+          return resolve(data);
+        }
+      });
+  });
+}
+
+debug.crashDetails = crashDetails;
+
+module.exports = debug;
diff --git a/skyquake/plugins/debug/config.json b/skyquake/plugins/debug/config.json
new file mode 100644 (file)
index 0000000..6643aca
--- /dev/null
@@ -0,0 +1,14 @@
+{
+    "root": "public",
+    "name": "Debug",
+    "dashboard": "./crash.jsx",
+    "order": 100,
+    "priority":2,
+    "routes" : [{
+        "label": "Debug",
+        "route": "/",
+        "component": "./crash.jsx",
+        "path": "",
+        "type": "internal"
+    }]
+}
diff --git a/skyquake/plugins/debug/package.json b/skyquake/plugins/debug/package.json
new file mode 100644 (file)
index 0000000..fd2dea9
--- /dev/null
@@ -0,0 +1,51 @@
+{
+  "name": "debug",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "RIFT.io",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "alt": "^0.18.3",
+    "bluebird": "^3.4.1",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "jquery": "^2.2.1",
+    "json-loader": "^0.5.4",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.4.1",
+    "react": "^0.14.7",
+    "react-breadcrumbs": "^1.3.9",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.6",
+    "react-router": "^2.0.1",
+    "react-slick": "^0.11.1",
+    "react-tabs": "^0.5.3",
+    "react-treeview": "^0.4.2",
+    "request-promise": "^3.0.0",
+    "underscore": "^1.8.3"
+  },
+  "devDependencies": {
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "cors": "^2.7.1",
+    "css-loader": "^0.23.1",
+    "file-loader": "^0.8.5",
+    "html-webpack-plugin": "^2.9.0",
+    "http-proxy": "^1.12.0",
+    "loaders.css": "^0.1.2",
+    "node-sass": "^3.4.2",
+    "react-addons-css-transition-group": "^0.14.7",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "webpack": "^1.3.0",
+    "webpack-dev-server": "^1.10.1"
+  }
+}
diff --git a/skyquake/plugins/debug/routes.js b/skyquake/plugins/debug/routes.js
new file mode 100644 (file)
index 0000000..1c8be7b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var router = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js');
+var debug = require('./api/debug.js');
+
+router.get('/api/crash-details', function(req, res) {
+          debug.crashDetails.get(req).then(
+        function(data) {
+            res.send(data);
+        },
+        function (error) {
+            utils.sendErrorResponse(error, res);
+        }
+    );
+});
+
+module.exports = router;
diff --git a/skyquake/plugins/debug/scripts/build.sh b/skyquake/plugins/debug/scripts/build.sh
new file mode 100755 (executable)
index 0000000..49bc9f0
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=debug
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/debug/scripts/install.sh b/skyquake/plugins/debug/scripts/install.sh
new file mode 100755 (executable)
index 0000000..a14b9bd
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=debug
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
diff --git a/skyquake/plugins/debug/server.js b/skyquake/plugins/debug/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/debug/src/crash.jsx b/skyquake/plugins/debug/src/crash.jsx
new file mode 100644 (file)
index 0000000..6c659c3
--- /dev/null
@@ -0,0 +1,134 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './crash.scss';
+import TreeView from 'react-treeview';
+import '../node_modules/react-treeview/react-treeview.css';
+import AppHeader from 'widgets/header/header.jsx';
+var crashActions = require('./crashActions.js');
+var crashStore = require('./crashStore.js');
+// var MissionControlStore = require('../missioncontrol/missionControlStore.js');
+function openDashboard() {
+  window.location.hash = "#/";
+}
+class CrashDetails extends React.Component {
+  constructor(props) {
+    super(props)
+    var self = this;
+    this.state = crashStore.getState();
+    crashStore.listen(this.storeListener);
+  }
+  storeListener = (data) => {
+     this.setState({
+        list:data.crashList,
+        noDebug:!this.hasDebugData(data.crashList)
+      });
+  }
+  componentWillUnmount(){
+    crashStore.unlisten(this.storeListener);
+  }
+  componentWillMount() {
+    crashStore.get();
+  }
+  hasDebugData(list) {
+    console.log(list);
+    if (list && list.length > 0) {
+      for (let i = 0; i < list.length; i++) {
+        var trace = list[i].backtrace;
+        for (let j = 0; j < trace.length; j++) {
+          console.log(trace[j])
+          if (trace[j].detail) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+  downloadFile(fileName, urlData) {
+    var replacedNewLines = urlData.replace(/\\n/g, '\n');
+    var replacedTabs = replacedNewLines.replace(/\\t/g, '\t');
+    var replacedQuotes= replacedTabs.replace(/\\"/g, '"');
+    var textFileBlob = new Blob([replacedQuotes], {type: 'text/plain;charset=UTF-8'});
+    var aLink = document.createElement('a');
+    var evt = document.createEvent("HTMLEvents");
+    evt.initEvent("click");
+    aLink.download = fileName;
+    aLink.href = window.URL.createObjectURL(textFileBlob);
+    aLink.dispatchEvent(evt);
+  }
+  render() {
+    let html;
+    var list = null;
+    if (this.state != null) {
+      var tree = <div style={{'marginLeft':'auto', 'marginRight':'auto', 'width':'230px', 'padding':'90px'}}> No Debug Information Available </div>;
+      if (!this.state.noDebug)
+      {
+        var tree = this.state.list && this.state.list.map((node, i) => {
+                  var vm = node.name;
+                  var vm_label = <span>{vm}</span>;
+                  var backtrace = node.backtrace;
+                  return (
+                    <TreeView key={vm + '|' + i} nodeLabel={vm_label} defaultCollapsed={false}>
+                      {backtrace.map(details => {
+
+                        //Needed to decode HTML
+                        var text_temp = document.createElement("textarea")
+                        text_temp.innerHTML = details.detail;
+                        var text_temp = text_temp.value;
+                        var arr = text_temp.split(/\n/);
+                        var text = [];
+                        for (let i = 0; i < arr.length; i++) {
+                          text.push(arr[i]);
+                          text.push(<br/>)
+                        }
+
+                        return (
+                          <TreeView nodeLabel={<span>{details.id}</span>} key={vm + '||' + details.id} defaultCollapsed={false}>
+                            <p>{text}</p>
+                          </TreeView>
+                        );
+                      })}
+                    </TreeView>
+                  );
+                })}
+      html = (
+        <div className="crash-details-wrapper">
+              <div className="form-actions">
+                <button role="button" className="dark" onClick={this.state.noDebug ? false : this.downloadFile.bind(this, 'crash.txt', 'data:text;charset=UTF-8,' + decodeURIComponent(JSON.stringify(this.state.list, null, 2)))}> Download Crash Details</button>
+              </div>
+              <div className="crash-container">
+                <h2> Debug Information </h2>
+                <div className="tree">{tree}</div>
+              </div>
+        </div>
+              );
+    } else {
+      html = <div className="crash-container"></div>
+    };
+    let refPage = window.sessionStorage.getItem('refPage');
+    refPage = JSON.parse(refPage);
+    return (
+            <div className="crash-app">
+              {html}
+            </div>
+            );
+  }
+}
+export default CrashDetails;
diff --git a/skyquake/plugins/debug/src/crash.scss b/skyquake/plugins/debug/src/crash.scss
new file mode 100644 (file)
index 0000000..c1df6dd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.crash-app {
+    height: 100%;
+    display: flex;
+    flex-direction: row;
+    align-items: stretch;
+    align-content: stretch;
+    width: 100%;
+    flex: 1 1 100%;
+    overflow-y: auto;
+
+    .crash-details-wrapper {
+      flex: 1;
+
+      .form-actions {
+        display: flex;
+        justify-content: center;
+      }
+      .crash-container {
+        margin: 1rem 1.5rem;
+        background-color:#e5e5e5;
+        .primary {
+          background-color:#ffffff;
+        }
+        .tree {
+          padding:1.5rem;
+        }
+        h2 {
+          background-color: #ffffff;
+          margin-bottom: 0.125rem;
+          font-size: 0.9rem;
+          padding: 1.125rem;
+          font-weight: bold;
+          text-transform: uppercase;
+        }
+      }
+    }
+}
+
diff --git a/skyquake/plugins/debug/src/crashActions.js b/skyquake/plugins/debug/src/crashActions.js
new file mode 100644 (file)
index 0000000..968942b
--- /dev/null
@@ -0,0 +1,26 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+var crashDetailsActions = Alt.generateActions(
+                                                'getCrashDetailsSuccess',
+                                                'getCrashDetailsLoading',
+                                                'getCrashDetailsFail',
+                                                );
+
+module.exports = crashDetailsActions;
diff --git a/skyquake/plugins/debug/src/crashSource.js b/skyquake/plugins/debug/src/crashSource.js
new file mode 100644 (file)
index 0000000..af95b72
--- /dev/null
@@ -0,0 +1,55 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var crashActions = require('./crashActions.js');
+var Utils = require('utils/utils.js');
+import $ from 'jquery';
+var crashSource = {
+
+  get: function() {
+    return {
+      remote: function(state) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'api/crash-details?api_server=' + API_SERVER,
+            type:'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            contentType: "application/json",
+            success: function(data) {
+              resolve(data);
+            },
+            error: function(error) {
+              console.log("There was an error getting the crash details: ", error);
+              reject(error);
+            }
+          }).fail(function(xhr){
+            console.log('fail')
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });
+        }).catch(function(err){console.log(err)});
+      },
+      success: crashActions.getCrashDetailsSuccess,
+      loading: crashActions.getCrashDetailsLoading,
+      error: crashActions.getCrashDetailsFail
+    }
+  }
+}
+module.exports = crashSource;
diff --git a/skyquake/plugins/debug/src/crashStore.js b/skyquake/plugins/debug/src/crashStore.js
new file mode 100644 (file)
index 0000000..c5ded18
--- /dev/null
@@ -0,0 +1,39 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+function crashStore () {
+  this.exportAsync(require('./crashSource.js'));
+  this.bindActions(require('./crashActions.js'));
+}
+
+crashStore.prototype.getCrashDetailsSuccess = function(list) {
+  this.setState({
+    crashList:list
+  })
+  console.log('success', list)
+};
+crashStore.prototype.getCrashDetailsLoading = function(info) {
+  console.log('Loading crash details...', info)
+};
+crashStore.prototype.getCrashDetailsFailure = function(info) {
+  console.log('Failed to retrieve crash/debug details', info)
+};
+
+module.exports = Alt.createStore(crashStore);;
+
diff --git a/skyquake/plugins/debug/src/main.js b/skyquake/plugins/debug/src/main.js
new file mode 100644 (file)
index 0000000..b10dc1d
--- /dev/null
@@ -0,0 +1,11 @@
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/debug/webpack.production.config.js b/skyquake/plugins/debug/webpack.production.config.js
new file mode 100644 (file)
index 0000000..5be840c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass'
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="app"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/goodbyeworld/CMakeLists.txt b/skyquake/plugins/goodbyeworld/CMakeLists.txt
new file mode 100644 (file)
index 0000000..773e1bd
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  goodbyeworld
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/goodbyeworld/goodbyeworld-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/goodbyeworld/goodbyeworld-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/goodbyeworld/config.json b/skyquake/plugins/goodbyeworld/config.json
new file mode 100644 (file)
index 0000000..6f2d3cb
--- /dev/null
@@ -0,0 +1,18 @@
+{
+    "root": "public",
+    "name": "goodbye world test",
+    "routes": [
+    {
+        "label": "Goodbye World Component 1",
+        "route": "hello",
+        "component": "./goodbyeWorldOne.jsx",
+        "path": "",
+        "type": "internal"
+    },{
+        "label": "Goodbye World Component 2",
+        "route": "goodbye",
+        "component": "./goodbyeWorldTwo.jsx",
+        "path": "",
+        "type": "internal"
+    }]
+}
diff --git a/skyquake/plugins/goodbyeworld/package.json b/skyquake/plugins/goodbyeworld/package.json
new file mode 100644 (file)
index 0000000..ebb138c
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "name": "goodbyeworld",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "RIFT.io",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "alt": "^0.18.1",
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-preset-es2015": "^6.3.13",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "json-loader": "^0.5.4",
+    "react": "^0.14.6",
+    "react-dom": "^0.14.6",
+    "react-router": "^1.0.3",
+    "webpack": "^1.11.0",
+    "webpack-dev-server": "^1.10.1"
+  },
+  "devDependencies": {
+    "babel-preset-react": "^6.3.13",
+    "cors": "^2.7.1",
+    "html-webpack-plugin": "^2.7.2",
+    "http-proxy": "^1.12.0"
+  }
+}
diff --git a/skyquake/plugins/goodbyeworld/routes.js b/skyquake/plugins/goodbyeworld/routes.js
new file mode 100644 (file)
index 0000000..cc48f2f
--- /dev/null
@@ -0,0 +1,15 @@
+var router = require('express').Router();
+
+router.get('/api/', function(req, res) {
+       res.send({
+               'bar': 'foods'
+       });
+});
+
+router.get('/bar/', function(req, res) {
+       res.send({
+               'bar': 'foo'
+       });
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/skyquake/plugins/goodbyeworld/scripts/build.sh b/skyquake/plugins/goodbyeworld/scripts/build.sh
new file mode 100755 (executable)
index 0000000..6dc7f5c
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=goodbyeworld
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/goodbyeworld/scripts/install.sh b/skyquake/plugins/goodbyeworld/scripts/install.sh
new file mode 100755 (executable)
index 0000000..ab1dca1
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=goodbyeworld
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+#   cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+#   cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+
diff --git a/skyquake/plugins/goodbyeworld/server.js b/skyquake/plugins/goodbyeworld/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/goodbyeworld/server/bundle.js b/skyquake/plugins/goodbyeworld/server/bundle.js
new file mode 100644 (file)
index 0000000..6996392
--- /dev/null
@@ -0,0 +1,42 @@
+
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+var Webpack = require('webpack');
+var WebpackDevServer = require('webpack-dev-server');
+var webpackConfig = require('./../webpack.config.js');
+var path = require('path');
+var fs = require('fs');
+var mainPath = path.resolve(__dirname, '..', 'app', 'main.js');
+
+module.exports = function () {
+  var bundleStart = null;
+  var compiler = Webpack(webpackConfig);
+
+  compiler.plugin('compile', function() {
+    console.log('Bundling...');
+    bundleStart = Date.now();
+  });
+
+  compiler.plugin('done', function() {
+    console.log('Bundled in ' + (Date.now() - bundleStart) + 'ms!');
+  });
+
+  var bundler = new WebpackDevServer(compiler, {
+    contentBase: "http://localhost",
+    publicPath: '/build/',
+
+    hot: true,
+    progress: true,
+
+    quiet: true,
+    noInfo: false,
+    stats: {
+      colors: true
+    }
+  });
+  bundler.listen(8080, 'localhost', function () {
+    console.log('Bundling project, please wait...');
+  });
+
+};
diff --git a/skyquake/plugins/goodbyeworld/src/components/goodbyeWorldOne.jsx b/skyquake/plugins/goodbyeworld/src/components/goodbyeWorldOne.jsx
new file mode 100644 (file)
index 0000000..8725ef5
--- /dev/null
@@ -0,0 +1,27 @@
+import React from 'react';
+export default class GoodbyeWorldApp extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+            <GoodbyeWorldView />
+        );
+        return html;
+    }
+}
+
+class GoodbyeWorldView extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+           <div>GoodbyeWorld: Goodbye World One</div>
+        );
+        return html;
+    }
+}
+
diff --git a/skyquake/plugins/goodbyeworld/src/components/goodbyeWorldTwo.jsx b/skyquake/plugins/goodbyeworld/src/components/goodbyeWorldTwo.jsx
new file mode 100644 (file)
index 0000000..0c83ff2
--- /dev/null
@@ -0,0 +1,27 @@
+import React from 'react';
+
+export default class HelloWorldApp extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+            <HelloWorldView />
+        );
+        return html;
+    }
+}
+
+class HelloWorldView extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+           <div>GoodbyeWorld: Goodbye World Two</div>
+        );
+        return html;
+    }
+}
diff --git a/skyquake/plugins/goodbyeworld/src/index.html b/skyquake/plugins/goodbyeworld/src/index.html
new file mode 100644 (file)
index 0000000..a5e2309
--- /dev/null
@@ -0,0 +1,37 @@
+<!doctype html>
+<html lang="en" class="viewport">
+    <head>
+        <!-- TITLE Data -->
+        <title>RIFT.ware</title>
+        <!-- META Data -->
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="description" content="">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+        <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+        <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+        <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+        <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+        <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+        <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+        <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+        <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
+        <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
+        <link rel="icon" type="image/png" href="/favicon-194x194.png" sizes="194x194">
+        <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
+        <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
+        <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
+        <link rel="manifest" href="/manifest.json">
+        <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+        <meta name="msapplication-TileColor" content="#da532c">
+        <meta name="msapplication-TileImage" content="/mstile-144x144.png">
+        <meta name="theme-color" content="#ffffff">
+        <script src="./build/vendor.js"></script>
+    </head>
+    <body>
+        <div id="content">
+        </div>
+        <script src="./build/bundle.js"></script>
+    </body>
+</html>
diff --git a/skyquake/plugins/goodbyeworld/src/main.js b/skyquake/plugins/goodbyeworld/src/main.js
new file mode 100644 (file)
index 0000000..3c1f7b8
--- /dev/null
@@ -0,0 +1,11 @@
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./components', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#content');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/goodbyeworld/webpack.config.js b/skyquake/plugins/goodbyeworld/webpack.config.js
new file mode 100644 (file)
index 0000000..78b026b
--- /dev/null
@@ -0,0 +1,79 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var frameworkPath = '../../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+
+var config = {
+    devtool: 'eval',
+    entry:  [
+            'webpack/hot/dev-server',
+            'webpack-dev-server/client?http://localhost:8080',
+            mainPath
+        ]
+    ,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: 'http://localhost:8000/build/'
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: [nodeModulesPath],
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                },
+            },
+            {
+                test: /\.css$/,
+                loader: 'style!css?sourceMap'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css?sourceMap!sass'
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html',
+            templateContent: '<div id="content"></div>'
+        }),
+        new Webpack.HotModuleReplacementPlugin(),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/goodbyeworld/webpack.production.config.js b/skyquake/plugins/goodbyeworld/webpack.production.config.js
new file mode 100644 (file)
index 0000000..e013478
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass'
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html',
+            templateContent: '<div id="content"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/helloworld/CMakeLists.txt b/skyquake/plugins/helloworld/CMakeLists.txt
new file mode 100644 (file)
index 0000000..921c1aa
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  helloworld
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/helloworld/helloworld-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/helloworld/helloworld-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/helloworld/config.json b/skyquake/plugins/helloworld/config.json
new file mode 100644 (file)
index 0000000..90d2d10
--- /dev/null
@@ -0,0 +1,19 @@
+{
+    "root": "public",
+    "name": "Hello World Plugin",
+    "dashboard" : "./helloWorldDashboard.jsx",
+    "routes": [
+    {
+        "label": "Hello World Component 1",
+        "route": "hello",
+        "component": "./helloWorldOne.jsx",
+        "path": "",
+        "type": "internal"
+    },{
+        "label": "Hello World Component 2",
+        "route": "goodbye",
+        "component": "./helloWorldTwo.jsx",
+        "path": "",
+        "type": "internal"
+    }]
+}
diff --git a/skyquake/plugins/helloworld/package.json b/skyquake/plugins/helloworld/package.json
new file mode 100644 (file)
index 0000000..c874218
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "name": "helloworld",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "RIFT.io",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "alt": "^0.18.1",
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-preset-es2015": "^6.3.13",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "json-loader": "^0.5.4",
+    "react": "^0.14.6",
+    "react-dom": "^0.14.6",
+    "react-router": "^1.0.3",
+    "webpack": "^1.11.0",
+    "webpack-dev-server": "^1.10.1"
+  },
+  "devDependencies": {
+    "babel-preset-react": "^6.3.13",
+    "cors": "^2.7.1",
+    "html-webpack-plugin": "^2.9.0",
+    "http-proxy": "^1.12.0"
+  }
+}
diff --git a/skyquake/plugins/helloworld/routes.js b/skyquake/plugins/helloworld/routes.js
new file mode 100644 (file)
index 0000000..cc48f2f
--- /dev/null
@@ -0,0 +1,15 @@
+var router = require('express').Router();
+
+router.get('/api/', function(req, res) {
+       res.send({
+               'bar': 'foods'
+       });
+});
+
+router.get('/bar/', function(req, res) {
+       res.send({
+               'bar': 'foo'
+       });
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/skyquake/plugins/helloworld/scripts/build.sh b/skyquake/plugins/helloworld/scripts/build.sh
new file mode 100755 (executable)
index 0000000..39913a3
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=helloworld
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/helloworld/scripts/install.sh b/skyquake/plugins/helloworld/scripts/install.sh
new file mode 100755 (executable)
index 0000000..3d566a7
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=helloworld
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+#   cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+#   cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+
diff --git a/skyquake/plugins/helloworld/server.js b/skyquake/plugins/helloworld/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/helloworld/server/bundle.js b/skyquake/plugins/helloworld/server/bundle.js
new file mode 100644 (file)
index 0000000..6996392
--- /dev/null
@@ -0,0 +1,42 @@
+
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+var Webpack = require('webpack');
+var WebpackDevServer = require('webpack-dev-server');
+var webpackConfig = require('./../webpack.config.js');
+var path = require('path');
+var fs = require('fs');
+var mainPath = path.resolve(__dirname, '..', 'app', 'main.js');
+
+module.exports = function () {
+  var bundleStart = null;
+  var compiler = Webpack(webpackConfig);
+
+  compiler.plugin('compile', function() {
+    console.log('Bundling...');
+    bundleStart = Date.now();
+  });
+
+  compiler.plugin('done', function() {
+    console.log('Bundled in ' + (Date.now() - bundleStart) + 'ms!');
+  });
+
+  var bundler = new WebpackDevServer(compiler, {
+    contentBase: "http://localhost",
+    publicPath: '/build/',
+
+    hot: true,
+    progress: true,
+
+    quiet: true,
+    noInfo: false,
+    stats: {
+      colors: true
+    }
+  });
+  bundler.listen(8080, 'localhost', function () {
+    console.log('Bundling project, please wait...');
+  });
+
+};
diff --git a/skyquake/plugins/helloworld/src/helloWorldDashboard.jsx b/skyquake/plugins/helloworld/src/helloWorldDashboard.jsx
new file mode 100644 (file)
index 0000000..532813d
--- /dev/null
@@ -0,0 +1,27 @@
+import React from 'react';
+
+export default class HelloWorldDashboard extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+            <HelloWorldView />
+        );
+        return html;
+    }
+}
+
+class HelloWorldView extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+           <div>HelloWorld: HelloWorldDashboard</div>
+        );
+        return html;
+    }
+}
diff --git a/skyquake/plugins/helloworld/src/helloWorldOne.jsx b/skyquake/plugins/helloworld/src/helloWorldOne.jsx
new file mode 100644 (file)
index 0000000..8f06fd2
--- /dev/null
@@ -0,0 +1,27 @@
+import React from 'react';
+
+export default class HelloWorldApp extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+            <HelloWorldView />
+        );
+        return html;
+    }
+}
+
+class HelloWorldView extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+           <div>HelloWorld: Hello World One</div>
+        );
+        return html;
+    }
+}
diff --git a/skyquake/plugins/helloworld/src/helloWorldTwo.jsx b/skyquake/plugins/helloworld/src/helloWorldTwo.jsx
new file mode 100644 (file)
index 0000000..6b7ccdb
--- /dev/null
@@ -0,0 +1,28 @@
+import React from 'react';
+
+export default class HelloWorldTwo extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+            <HelloWorldTwoView />
+        );
+        return html;
+    }
+}
+
+class HelloWorldTwoView extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    render() {
+        let html;
+        html = (
+           <div>HelloWorld: Hello World Two</div>
+        );
+        return html;
+    }
+}
+
diff --git a/skyquake/plugins/helloworld/src/index.html b/skyquake/plugins/helloworld/src/index.html
new file mode 100644 (file)
index 0000000..a5e2309
--- /dev/null
@@ -0,0 +1,37 @@
+<!doctype html>
+<html lang="en" class="viewport">
+    <head>
+        <!-- TITLE Data -->
+        <title>RIFT.ware</title>
+        <!-- META Data -->
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="description" content="">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+        <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+        <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+        <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+        <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+        <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+        <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+        <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+        <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
+        <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
+        <link rel="icon" type="image/png" href="/favicon-194x194.png" sizes="194x194">
+        <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
+        <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
+        <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
+        <link rel="manifest" href="/manifest.json">
+        <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+        <meta name="msapplication-TileColor" content="#da532c">
+        <meta name="msapplication-TileImage" content="/mstile-144x144.png">
+        <meta name="theme-color" content="#ffffff">
+        <script src="./build/vendor.js"></script>
+    </head>
+    <body>
+        <div id="content">
+        </div>
+        <script src="./build/bundle.js"></script>
+    </body>
+</html>
diff --git a/skyquake/plugins/helloworld/src/main.js b/skyquake/plugins/helloworld/src/main.js
new file mode 100644 (file)
index 0000000..f69a91e
--- /dev/null
@@ -0,0 +1,11 @@
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#content');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/helloworld/webpack.config.js b/skyquake/plugins/helloworld/webpack.config.js
new file mode 100644 (file)
index 0000000..1e0f614
--- /dev/null
@@ -0,0 +1,78 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var frameworkPath = '../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+var config = {
+    devtool: 'eval',
+    entry:  [
+            'webpack/hot/dev-server',
+            'webpack-dev-server/client?http://localhost:8080',
+            mainPath
+        ]
+    ,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: 'http://localhost:8000/build/'
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: [nodeModulesPath],
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                },
+            },
+            {
+                test: /\.css$/,
+                loader: 'style!css?sourceMap'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css?sourceMap!sass'
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            // ,emplateContent: '<div id="content"></div>'
+        }),
+        new Webpack.HotModuleReplacementPlugin(),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/helloworld/webpack.production.config.js b/skyquake/plugins/helloworld/webpack.production.config.js
new file mode 100644 (file)
index 0000000..e5728d0
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass'
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="content"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/launchpad/CMakeLists.txt b/skyquake/plugins/launchpad/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2917c8d
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  launchpad
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/launchpad/launchpad-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/launchpad/launchpad-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/launchpad/api/epa_aggregator.js b/skyquake/plugins/launchpad/api/epa_aggregator.js
new file mode 100644 (file)
index 0000000..5577226
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var EpaSchema = {
+  "vswitch-epa": {
+    "objType": "container",
+    "ovs-offload": {
+      "objType": "leaf"
+    },
+    "ovs-acceleration": {
+      "objType": "leaf"
+    }
+  },
+  "hypervisor-epa": {
+    "objType": "container",
+    "type": {
+      "objType": "leaf"
+    },
+    "version": {
+      "objType": "leaf"
+    }
+  },
+  "host-epa": {
+    "objType": "container",
+    "cpu-model": {
+      "objType": "leaf"
+    },
+    "cpu-arch": {
+      "objType": "leaf"
+    },
+    "cpu-vendor": {
+      "objType": "leaf"
+    },
+    "cpu-socket-count": {
+      "objType": "leaf"
+    },
+    "cpu-core-count": {
+      "objType": "leaf"
+    },
+    "cpu-feature": {
+      "objType": "leaf-list"
+    }
+  },
+  "guest-epa": {
+    "objType": "container",
+    "mempage-size": {
+      "objType": "leaf"
+    },
+    "trusted-execution": {
+      "objType": "leaf"
+    },
+    "cpu-pinning-policy": {
+      "objType": "leaf"
+    },
+    "cpu-thread-pinning-policy": {
+      "objType": "leaf"
+    },
+    "pcie-device": {
+      "objType": "list"
+    },
+    "numa-node-policy": {
+      "objType": "container",
+      "node": {
+        "objType": "list"
+      }
+    }
+  }
+}
+
+module.exports = function aggregateEPA(vdur, data) {
+  var data = data || {};
+  var schema = EpaSchema;
+  var findLeaf = function(obj, schema, data) {
+    for (k in obj) {
+      var epaSchema = schema[k];
+      //if key exists in schema
+      if (epaSchema) {
+        if (!data[k]) {
+          data[k] = {};
+        }
+        switch (epaSchema.objType) {
+          case 'container':
+            findLeaf(obj[k], epaSchema, data[k]);
+            break;
+          case 'leaf':
+            aggregateValue(obj[k].toString(), data[k]);
+            break;
+          case 'leaf-list':
+            aggregateLeafListValue(obj[k], data[k]);
+            break;
+          case 'list':
+            aggregateListValue(k, obj[k], data[k]);
+            break;
+          case 'choice':
+            aggregateChoiceValue(obj[k], data[k]);
+            break;
+        }
+      }
+    }
+    return data;
+  }
+  try {
+    vdur.map(function(vm) {
+      findLeaf(vm, schema, data)
+    })
+  }
+  catch(e) {
+
+  }
+
+  return data;
+
+  function aggregateChoiceValue(obj, data) {
+    for (k in obj) {
+      aggregateValue(k, data)
+    }
+  }
+
+  function aggregateValue(value, data) {
+    value = value.toString();
+    if (!data[value]) data[value] = {};
+    var total = data[value];
+    total.total = (!total.total) ? 1 : total.total + 1;
+  }
+
+  function aggregateListValue(k, value, data) {
+    if (value.length > 0) {
+      aggregateValue(k, data);
+    }
+  }
+
+  function aggregateLeafListValue(obj, data) {
+    if (obj.constructor.name == "Array") {
+      obj.map(function(p) {
+        aggregateValue(p, data);
+      })
+    } else {
+      console.log("Oops, something went wrong here. An object was passed that wasn't an Array. Are you sure it was leaf-list?")
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/api/launchpad.js b/skyquake/plugins/launchpad/api/launchpad.js
new file mode 100644 (file)
index 0000000..02c28eb
--- /dev/null
@@ -0,0 +1,2026 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var request = require('request');
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var constants = require('../../../framework/core/api_utils/constants.js');
+var APIVersion = '/v1';
+var _ = require('underscore');
+var epa_aggregator = require('./epa_aggregator.js');
+var transforms = require('./transforms.js');
+var uuid = require('node-uuid');
+
+// Revealing module pattern objects
+var Catalog = {};
+var Config = {};
+var NSR = {};
+var VNFR = {};
+var VLR = {};
+var RIFT = {};
+var ComputeTopology = {};
+var NetworkTopology = {};
+var VDUR = {};
+var CloudAccount = {};
+var ConfigAgentAccount = {};
+var RPC = {};
+var SSHkey = {};
+// API Configuration Info
+var APIConfig = {}
+APIConfig.NfviMetrics = ['vcpu', 'memory'];
+
+RPC.executeNSServicePrimitive = function(req) {
+    var api_server = req.query['api_server'];
+    return new Promise(function(resolve, reject) {
+        var jsonData = {
+            "input": req.body
+        };
+
+        var headers = _.extend({},
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            }
+        );
+        request({
+            url: utils.confdPort(api_server) + APIVersion + '/api/operations/exec-ns-service-primitive',
+            method: 'POST',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('RPC.executeNSServicePrimitive', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            }
+        })
+    });
+};
+
+RPC.getNSServicePrimitiveValues = function(req) {
+    var api_server = req.query['api_server'];
+    // var nsr_id = req.body['nsr_id_ref'];
+    // var nsConfigPrimitiveName = req.body['name'];
+    return new Promise(function(resolve, reject) {
+        var jsonData = {
+            "input": req.body
+        };
+
+        var headers = _.extend({},
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            }
+        );
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/operations/get-ns-service-primitive-values',
+            method: 'POST',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('RPC.getNSServicePrimitiveValues', error, response, body, resolve, reject)) {
+
+                resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.parse(body)
+                });
+            }
+        });
+    }).catch(function(error) {
+        console.log('error getting primitive values');
+    });
+};
+RPC.refreshAccountConnectionStatus = function(req) {
+    var api_server = req.query['api_server'];
+    var Name = req.params.name;
+    var Type = req.params.type;
+    var jsonData = {
+        input: {}
+    };
+    var rpcInfo = {
+        sdn: {
+            label: 'sdn-account',
+            rpc: 'update-sdn-status'
+        },
+        config: {
+            label: 'cfg-agent-account',
+            rpc: 'update-cfg-agent-status'
+        },
+        cloud: {
+            label: 'cloud-account',
+            rpc: 'update-cloud-status'
+        }
+    }
+    jsonData.input[rpcInfo[Type].label] = Name;
+    var headers = _.extend({},
+        constants.HTTP_HEADERS.accept.data,
+        constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        }
+    );
+    return new Promise(function(resolve, reject) {
+
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/operations/' + rpcInfo[Type].rpc,
+            method: 'POST',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('RPC.refreshAccountConnectionStatus', error, response, body, resolve, reject)) {
+
+                resolve({
+                    statusCode: response.statusCode,
+                    data: body
+                });
+            }
+        });
+    }).catch(function(error) {
+        console.log('Error refreshing account info');
+    });
+};
+
+
+var DataCenters = {};
+// Catalog module methods
+Catalog.get = function(req) {
+    var api_server = req.query['api_server'];
+    var results = {}
+    return new Promise(function(resolve, reject) {
+        Promise.all([
+            rp({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            }),
+            rp({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd?deep',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            }),
+            rp({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata?deep',
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                    'Authorization': req.get('Authorization')
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+                resolveWithFullResponse: true
+            })
+            // Not enabled for now
+            // rp({
+            //   uri: utils.confdPort(api_server) + APIVersion + '/api/config/pnfd-catalog/pnfd?deep',
+            //   method: 'GET',
+            //   headers: _.extend({},
+            //     constants.HTTP_HEADERS.accept.collection,
+            //     {
+            //       'Authorization': req.get('Authorization')
+            //     }),
+            //   forever: constants.FOREVER_ON,
+            // rejectUnauthorized: false,
+            //   resolveWithFullResponse: true
+            // })
+        ]).then(function(result) {
+            console.log('Resolved all request promises (NSD, VNFD) successfully');
+            var response = [{
+                "id": "GUID-1",
+                "name": "RIFT.ware™ NS Descriptors Catalog",
+                "short-name": "rift.ware-nsd-cat",
+                "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+                "vendor": "RIFT.io",
+                "version": "",
+                "created-on": "",
+                "type": "nsd",
+                "meta": {
+                    "icon-svg": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22iso-8859-1%22%3F%3E%0A%3C!--%20Generator%3A%20Adobe%20Illustrator%2018.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200)%20%20--%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22connection-icon-1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2050%2050%22%20style%3D%22enable-background%3Anew%200%200%2050%2050%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%09%3Cpath%20d%3D%22M15%2030c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2020c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2040c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M19.007%2025.885l12.88%206.44-.895%201.788-12.88-6.44z%22%2F%3E%3Cpath%20d%3D%22M30.993%2015.885l.894%201.79-12.88%206.438-.894-1.79z%22%2F%3E%3C%2Fsvg%3E"
+                },
+                "descriptors": []
+            }, {
+                "id": "GUID-2",
+                "name": "RIFT.ware™ VNF Descriptors Catalog",
+                "short-name": "rift.ware-vnfd-cat",
+                "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+                "vendor": "RIFT.io",
+                "version": "",
+                "created-on": "",
+                "type": "vnfd",
+                "meta": {
+                    "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_3\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <g> <path d=\"M58.852,62.447l-4.662-1.033c-0.047-3.138-0.719-6.168-1.996-9.007l3.606-2.92c0.858-0.695,0.99-1.954,0.296-2.813 l-4.521-5.584c-0.334-0.413-0.818-0.675-1.346-0.731c-0.525-0.057-1.056,0.102-1.468,0.435L45.25,43.64v0 c-2.486-1.907-5.277-3.259-8.297-4.019v-4.458c0-1.104-0.896-2-2-2H27.77c-1.104,0-2,0.896-2,2v4.461 c-3.08,0.777-5.922,2.171-8.447,4.144l-3.545-2.82c-0.415-0.33-0.94-0.479-1.472-0.422c-0.527,0.06-1.009,0.327-1.339,0.743 l-4.472,5.623c-0.688,0.864-0.544,2.123,0.32,2.81l3.642,2.896v0c-1.25,2.848-1.895,5.88-1.916,9.011l-4.666,1.078 c-1.076,0.249-1.747,1.322-1.499,2.398l1.616,7.001c0.249,1.077,1.325,1.747,2.399,1.499l4.813-1.111v0 c1.429,2.681,3.344,5.017,5.691,6.943l-2.17,4.55c-0.476,0.997-0.054,2.19,0.943,2.666l6.484,3.094 c0.271,0.129,0.566,0.195,0.861,0.195c0.226,0,0.451-0.038,0.668-0.115c0.5-0.177,0.909-0.545,1.138-1.024l2.198-4.611 c2.923,0.563,5.966,0.554,8.879-0.033l2.236,4.585c0.484,0.994,1.685,1.403,2.675,0.921l6.456-3.148 c0.992-0.484,1.405-1.682,0.921-2.674l-2.206-4.524c2.335-1.946,4.231-4.301,5.639-6.999l4.812,1.067 c1.076,0.237,2.146-0.441,2.385-1.52l1.556-7.014c0.115-0.518,0.02-1.06-0.266-1.508C59.82,62.878,59.369,62.562,58.852,62.447z M40.18,61.761c0,4.859-3.953,8.812-8.813,8.812c-4.858,0-8.811-3.953-8.811-8.812s3.952-8.812,8.811-8.812 C36.227,52.949,40.18,56.902,40.18,61.761z\"/> <path d=\"M64.268,45.324c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.826,0.353,3.736,0.345,5.551-0.021l1.07,2.195 c0.484,0.992,1.682,1.405,2.675,0.921l2.691-1.313c0.477-0.233,0.842-0.646,1.015-1.147c0.172-0.501,0.139-1.051-0.095-1.528 l-1.052-2.155c1.458-1.214,2.645-2.686,3.527-4.377l2.278,0.504c1.075,0.238,2.146-0.442,2.386-1.52l0.647-2.923 c0.238-1.078-0.442-2.146-1.521-2.385l-2.184-0.484c-0.028-1.962-0.449-3.857-1.248-5.632l1.673-1.355 c0.412-0.334,0.675-0.818,0.73-1.345s-0.102-1.056-0.436-1.468l-1.884-2.327c-0.697-0.859-1.957-0.99-2.813-0.295l-1.614,1.307 c-1.554-1.193-3.299-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.04 c-1.927,0.486-3.703,1.358-5.28,2.592l-1.634-1.298c-0.862-0.687-2.12-0.543-2.81,0.32l-1.864,2.344 c-0.33,0.416-0.481,0.945-0.422,1.472c0.061,0.527,0.327,1.009,0.743,1.339l1.69,1.345c-0.78,1.779-1.184,3.676-1.197,5.636 l-2.189,0.505c-0.517,0.119-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51l0.675,2.918 c0.249,1.076,1.323,1.747,2.398,1.498l2.28-0.527c0.892,1.676,2.089,3.137,3.559,4.343l-1.035,2.17 c-0.228,0.479-0.257,1.028-0.08,1.528c0.178,0.5,0.546,0.91,1.024,1.138l2.703,1.289C63.686,45.261,63.979,45.324,64.268,45.324z M64.334,27.961c0-3.039,2.473-5.51,5.512-5.51c3.038,0,5.51,2.472,5.51,5.51c0,3.039-2.472,5.511-5.51,5.511 C66.807,33.472,64.334,31,64.334,27.961z\"/> <path d=\"M96.107,66.441l-2.182-0.484c-0.028-1.961-0.449-3.856-1.25-5.632l1.675-1.355c0.412-0.334,0.675-0.818,0.73-1.346 c0.056-0.527-0.102-1.056-0.436-1.468l-1.885-2.327c-0.695-0.859-1.956-0.99-2.813-0.295l-1.614,1.307 c-1.555-1.193-3.3-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.041 c-1.929,0.486-3.706,1.358-5.282,2.592l-0.001,0l-1.631-1.298c-0.415-0.331-0.938-0.482-1.472-0.422 c-0.527,0.06-1.009,0.327-1.339,0.742l-1.863,2.343c-0.688,0.865-0.544,2.123,0.32,2.811l1.691,1.345 c-0.782,1.784-1.186,3.68-1.199,5.636l-2.188,0.505c-0.517,0.12-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51 l0.675,2.918c0.249,1.076,1.327,1.744,2.397,1.498l2.281-0.526c0.893,1.677,2.09,3.138,3.558,4.343h0.001l-1.035,2.168 c-0.229,0.479-0.258,1.029-0.081,1.529c0.178,0.5,0.546,0.909,1.024,1.138l2.702,1.289c0.278,0.132,0.571,0.195,0.86,0.195 c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.828,0.353,3.739,0.347,5.552-0.021l1.071,2.194 c0.484,0.992,1.682,1.405,2.675,0.921l2.69-1.312c0.477-0.233,0.842-0.645,1.014-1.147c0.173-0.501,0.14-1.051-0.093-1.528 l-1.052-2.155c1.459-1.215,2.645-2.688,3.525-4.377l2.278,0.505c0.52,0.116,1.061,0.02,1.508-0.266 c0.447-0.285,0.763-0.736,0.878-1.254l0.647-2.923C97.866,67.748,97.186,66.681,96.107,66.441z M85.162,66.174 c0,3.039-2.471,5.511-5.508,5.511c-3.039,0-5.512-2.472-5.512-5.511c0-3.039,2.473-5.511,5.512-5.511 C82.691,60.664,85.162,63.136,85.162,66.174z\"/> </g> </svg> "
+                },
+                "descriptors": []
+            }, {
+                "id": "GUID-3",
+                "name": "RIFT.ware™ PNF Descriptors Catalog",
+                "short-name": "rift.ware-pnfd-cat",
+                "description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
+                "vendor": "RIFT.io",
+                "version": "",
+                "created-on": "",
+                "type": "pnfd",
+                "meta": {
+                    "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_4\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <path d=\"M86.334,47.444V35.759H13.666v11.686h3.561v5.111h-3.561v11.686h72.668V52.556h-4.108v-5.111H86.334z M26.628,59.454h-5.051 v-4.941h5.051V59.454z M26.628,52.404h-5.051v-4.941h5.051V52.404z M26.628,45.486h-5.051v-4.941h5.051V45.486z M34.094,59.454 h-5.051v-4.941h5.051V59.454z M34.094,52.404h-5.051v-4.941h5.051V52.404z M34.094,45.486h-5.051v-4.941h5.051V45.486z M41.452,59.454h-5.051v-4.941h5.051V59.454z M41.452,52.404h-5.051v-4.941h5.051V52.404z M41.452,45.486h-5.051v-4.941h5.051 V45.486z M48.733,59.454h-5.051v-4.941h5.051V59.454z M48.733,52.404h-5.051v-4.941h5.051V52.404z M48.733,45.486h-5.051v-4.941 h5.051V45.486z M56.2,59.454h-5.051v-4.941H56.2V59.454z M56.2,52.404h-5.051v-4.941H56.2V52.404z M56.2,45.486h-5.051v-4.941H56.2 V45.486z M63.558,59.454h-5.05v-4.941h5.05V59.454z M63.558,52.404h-5.05v-4.941h5.05V52.404z M63.558,45.486h-5.05v-4.941h5.05 V45.486z M74.858,59.312h-6.521v-3.013h6.521V59.312z M71.572,50.854c-2.875,0-5.204-2.33-5.204-5.203s2.329-5.203,5.204-5.203 s5.204,2.33,5.204,5.203S74.446,50.854,71.572,50.854z M74.858,45.618c0,1.801-1.46,3.261-3.261,3.261 c-1.8,0-3.261-1.46-3.261-3.261s1.46-3.26,3.261-3.26C73.398,42.358,74.858,43.817,74.858,45.618z\"/> </svg>"
+                },
+                "descriptors": []
+            }];
+            var vnfdCatalog = null;
+            var vnfdDict = {};
+            if (result[1].body) {
+                vnfdCatalog = JSON.parse(result[1].body).collection['vnfd:vnfd'].map(function(v, i) {
+                    vnfdDict[v.id] = v['short-name'] || v.name;
+                })
+            }
+            if (result[0].body) {
+                response[0].descriptors = JSON.parse(result[0].body).collection['nsd:nsd'];
+                if (result[2].body) {
+                    var data = JSON.parse(result[2].body);
+                    if (data && data["nsr:ns-instance-opdata"] && data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"]) {
+                        var nsdRefCountCollection = data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"];
+                        response[0].descriptors.map(function(nsd) {
+                            if (!nsd["meta"]) {
+                                nsd["meta"] = {};
+                            }
+                            if (typeof nsd['meta'] == 'string') {
+                                nsd['meta'] = JSON.parse(nsd['meta']);
+                            }
+                            nsd["meta"]["instance-ref-count"] = _.findWhere(nsdRefCountCollection, {
+                                "nsd-id-ref": nsd.id
+                            })["instance-ref-count"];
+                            nsd["constituent-vnfd"] && nsd["constituent-vnfd"].map(function(v) {
+                                v.name = vnfdDict[v["vnfd-id-ref"]];
+                            })
+                        });
+                    }
+                }
+            };
+            if (result[1].body) {
+                response[1].descriptors = JSON.parse(result[1].body).collection['vnfd:vnfd'];
+            };
+            // if (result[2].body) {
+            //   response[2].descriptors = JSON.parse(result[2].body).collection['pnfd:pnfd'];
+            // };
+            resolve({
+                statusCode: response.statusCode || 200,
+                data: JSON.stringify(response)
+            });
+        }).catch(function(error) {
+            // Todo: Need better logic than all or nothing.
+            // Right now even if one of the southbound APIs fails - all fail
+            var res = {};
+            console.log('Problem with Catalog.get', error);
+            res.statusCode = error.statusCode || 500;
+            res.errorMessage = {
+                error: 'Failed to get catalogs' + error
+            };
+            reject(res);
+        });
+    });
+};
+Catalog.delete = function(req) {
+    var api_server = req.query['api_server'];
+    var catalogType = req.params.catalogType;
+    var id = req.params.id;
+    console.log('Deleting', catalogType, id, 'from', api_server);
+    return new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog/' + catalogType + '/' + id,
+            method: 'DELETE',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('Catalog.delete', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+Catalog.getVNFD = function(req) {
+    var api_server = req.query['api_server'];
+    var vnfdID = req.body.data;
+    var authorization = req.get('Authorization');
+    var VNFDs = [];
+    if (typeof(vnfdID) == "object" && vnfdID.constructor.name == "Array") {
+        vnfdID.map(function(id) {
+            VNFDs.push(requestVNFD(id));
+        });
+    } else {
+        VNFDs.push(requestVNFD(vnfdID));
+    }
+    return new Promise(function(resolve, reject) {
+        Promise.all(VNFDs).then(function(data) {
+            resolve(data)
+        }).catch(function(error) {
+            // Todo: Need better logic than all or nothing.
+            // Right now even if one of the southbound APIs fails - all fail
+            var res = {};
+            console.log('Problem with Catalog.getVNFD', error);
+            res.statusCode = 404;
+            res.errorMessage = {
+                error: 'Failed to get VNFDs' + error
+            };
+            reject(res);
+        });
+    });
+
+    function requestVNFD(id) {
+        return new Promise(function(resolve, reject) {
+            var url = utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd' + (id ? '/' + id : '') + '?deep';
+            request({
+                uri: url,
+                method: 'GET',
+                headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                    'Authorization': authorization
+                }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+            }, function(error, response, body) {
+                if (utils.validateResponse('Catalog.getVNFD', error, response, body, resolve, reject)) {
+                    var data;
+                    //Is this still needed?
+                    try {
+                        data = JSON.parse(response.body)
+                    } catch (e) {
+                        reject({
+                            statusCode: response ? response.statusCode : 400,
+                            errorMessage: 'Issue parsing VNFD ' + id + 'from ' + utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd/' + id + '?deep'
+                        });
+                    }
+                    resolve(data);
+                }
+            });
+        });
+    }
+};
+Catalog.create = function(req) {
+    var api_server = req.query['api_server'];
+    var catalogType = req.params.catalogType;
+    var data = req.body;
+    console.log('Creating', catalogType, 'on', api_server);
+    var jsonData = {};
+    jsonData[catalogType] = [];
+    jsonData[catalogType].push(data);
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog',
+            method: 'POST',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('Catalog.create', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+Catalog.update = function(req) {
+    var api_server = req.query['api_server'];
+    var catalogType = req.params.catalogType;
+    var id = req.params.id;
+    var data = req.body;
+    console.log('Updating', catalogType, 'id', id, 'on', api_server);
+    var jsonData = {};
+    jsonData[catalogType] = {};
+    jsonData[catalogType] = data;
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog' + '/' + catalogType + '/' + id,
+            method: 'PUT',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('Catalog.update', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+
+Catalog.decorateNsdCatalogWithPlacementGroups = function decorateNsdCatalogWithPlacementGroups(catalog) {
+    var newData = catalog;
+    var parsedCatalog = JSON.parse(catalog.data);
+    var nsds = parsedCatalog[0].descriptors;
+    var vnfds = parsedCatalog[1].descriptors;
+    var vnfdDict = (function(){
+        var dict = {};
+        vnfds.map(function(v, i) {
+            dict[v.id] = v;
+        })
+        return dict;
+    })(vnfds);
+
+    nsds.map(function(c, i) {
+        //Rename and decorate NSD placement groups
+        c['ns-placement-groups'] = c['placement-groups'] && c['placement-groups'].map(function(p, i) {
+            //Adds vnfd name to member-vnfd entry
+            p['member-vnfd'] = p['member-vnfd'].map(function(v) {
+                v.name = vnfdDict[v['vnfd-id-ref']].name;
+                return v;
+            });
+            p['host-aggregate'] = [];
+            return p;
+        });
+
+        //Adds vnf placement groups to nsd object for UI
+        c['vnf-placement-groups'] = [];
+        c['constituent-vnfd'] && c['constituent-vnfd'].map(function(v) {
+            var vnf = vnfdDict[v['vnfd-id-ref']];
+            // var vnfPg = {
+            //     name: vnf.name,
+            //     'placement-groups': vnf['placement-groups'].map(function(vp){
+            //         vp['host-aggregate'] = [{}];
+            //         return vp;
+            //     })
+            // };
+            v['vnf-name'] = vnf.name;
+            vnf['placement-groups'] && vnf['placement-groups'].map(function(vp) {
+                vp['host-aggregate'] = [];
+                vp['vnf-name'] = vnf.name;
+                vp['vnfd-id-ref'] = v['vnfd-id-ref'];
+                vp['member-vnf-index'] = v['member-vnf-index'];
+                c['vnf-placement-groups'].push(vp);
+            })
+        })
+        return c;
+    })
+    // parsedCatalog[0].descriptors = nsds;
+    newData.data = JSON.stringify(parsedCatalog);
+    return newData;
+}
+
+// NSR module methods
+// Spend some time refactoring this
+// refactor to accept only request object
+NSR.get = function(req) {
+    var self = this;
+    var nsrPromises = [];
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+    var nsdInfo = new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep',
+            method: 'GET',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.get nsd-catalog', error, response, body, resolve, reject)) {
+                var data;
+                var isString = typeof(response.body) == "string";
+                if (isString && response.body == '') return resolve('empty');
+                data = isString ? JSON.parse(response.body) : response.body;
+                var nsdData = data.collection["nsd:nsd"];
+                if (nsdData.constructor.name == "Object") {
+                    nsdData = [nsdData];
+                }
+                resolve(nsdData);
+            };
+        })
+    })
+    var config = new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-config/nsr' + (id ? '/' + id : '') + '?deep',
+            method: 'GET',
+            headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.get ns-instance-config', error, response, body, resolve, reject)) {
+                var data;
+                var isString = typeof(response.body) == "string";
+                if (isString && response.body == '') return resolve();
+                data = isString ? JSON.parse(response.body) : response.body;
+                data = id ? data : data.collection;
+                var nsrData = data["nsr:nsr"];
+                if (nsrData.constructor.name == "Object") {
+                    nsrData = [nsrData];
+                }
+                resolve(nsrData);
+            };
+        });
+    });
+    var opData = new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr' + (id ? '/' + id : '') + '?deep',
+            method: 'GET',
+            headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.get ns-instance-opdata', error, response, body, resolve, reject)) {
+                var data;
+                var isString = typeof(response.body) == "string";
+                if (isString && response.body == '') return resolve();
+                data = isString ? JSON.parse(response.body) : response.body;
+                data = id ? data : data.collection;
+                var nsrData = data["nsr:nsr"];
+                if (nsrData.constructor.name == "Object") {
+                    nsrData = [nsrData];
+                }
+                nsrData.forEach(self.decorateWithScalingGroupDict);
+                nsrData.forEach(self.decorateAndTransformNFVI);
+                nsrData.forEach(self.decorateAndTransformWithControls);
+                Promise.all(self.addVnfrDataPromise(req, nsrData)).then(function() {
+                    Promise.all(self.addVlrDataPromise(req, nsrData)).then(function() {
+                        resolve(nsrData);
+                    });
+                });
+            };
+        });
+    }).catch(function(error) {
+        console.log('error getting aggregated NS opdata', error)
+        //note this will actually trigger the success callback
+    });
+    return new Promise(function(resolve, reject) {
+        //Need smarter error handling here
+        Promise.all([config, opData]).then(function(resolves) {
+            var aggregate = {};
+            // resolves[0] ==> ns-instance-config
+            // resolves[1] ==> ns-instance-opdata
+
+            var nsInstanceConfig = resolves[0] && resolves[0];
+            var nsInstanceOpdata = resolves[1] && resolves[1];
+
+            if (!nsInstanceConfig && !nsInstanceOpdata) {
+                return resolve({
+                    nsrs: []
+                });
+            }
+
+            nsInstanceConfig.forEach(function(v, k) {
+                v.nsd_name = v['nsd'] && v['nsd']['name'];
+                var scaling_group_descriptor = null;
+
+                scaling_group_descriptor = v['nsd'] && v['nsd']['scaling-group-descriptor'];
+
+                if (scaling_group_descriptor) {
+                    scaling_group_descriptor.map(function(sgd, sgdi) {
+                        sgd['vnfd-member'] && sgd['vnfd-member'].map(function(vnfd, vnfdi) {
+                            var vnfrObj = _.findWhere(_.findWhere(nsInstanceOpdata, {
+                                    'ns-instance-config-ref': v.id
+                                }).vnfrs, {
+                                'member-vnf-index-ref': vnfd['member-vnf-index-ref']
+                            });
+                            if (vnfrObj) {
+                                vnfd['short-name'] = vnfrObj['short-name'];
+                            }
+                        })
+                    })
+                    v['scaling-group-descriptor'] = scaling_group_descriptor;
+                }
+
+                if (nsInstanceOpdata && nsInstanceOpdata.constructor.name == "Array") {
+                    nsInstanceOpdata.forEach(function(w, l) {
+                        if (v.id == w["ns-instance-config-ref"]) {
+                            for (prop in w) {
+                                if (prop != "ns-instance-config-ref" && !v.hasOwnProperty(prop)) {
+                                    v[prop] = w[prop];
+                                }
+                            }
+                        }
+                    });
+                }
+
+                v['scaling-group-record'] && v['scaling-group-record'].map(function(sgr) {
+                    var scalingGroupName = sgr['scaling-group-name-ref'];
+                    sgr['instance'] && sgr['instance'].map(function(instance) {
+                        var scalingGroupInstanceId = instance['instance-id'];
+                        instance['vnfrs'] && instance['vnfrs'].map(function(vnfr) {
+                            var vnfrObj = _.findWhere(v['vnfrs'], {id: vnfr});
+                            if (vnfrObj) {
+                                vnfrObj['scaling-group-name'] = scalingGroupName;
+                                vnfrObj['scaling-group-instance-id'] = scalingGroupInstanceId;
+                            }
+                        });
+                    });
+                })
+            });
+            var nsrsData = nsInstanceConfig;
+            nsrsData.sort(function(a, b) {
+                return a["create-time"] - b["create-time"];
+            });
+            resolve({
+                nsrs: nsrsData
+            });
+        }).catch(function(error) {
+            reject({
+                statusCode: 404,
+                errorMessage: error
+            })
+        })
+    });
+};
+// Static VNFR Cache bu VNFR ID
+var staticVNFRCache = {};
+
+/**
+ * [decorateWithScalingGroupDict description]
+ * @param  {[type]} nsr [description]
+ * @return {[type]}
+{vnfr-id} : {
+    "scaling-group-name-ref": "sg1",
+    "instance-id": 0,
+    "op-status": "running",
+    "is-default": "true",
+    "create-time": 1463593760,
+    "config-status": "configuring",
+    "vnfrs": [
+        "432154e3-164e-4c05-83ee-3b56e4c898e7"
+    ]
+}
+ */
+NSR.decorateWithScalingGroupDict = function(nsr) {
+    var sg = nsr["scaling-group-record"];
+    var dict = {};
+    if(sg) {
+        sg.map(function(s) {
+            var sgRef = s['scaling-group-name-ref'];
+            s.instance && s.instance.map(function(si) {
+                si.vnfrs && si.vnfrs.map(function(v) {
+                    dict[v] = si;
+                    dict[v]["scaling-group-name-ref"] = sgRef;
+                })
+            })
+        })
+    }
+    return nsr['vnfr-scaling-groups'] = dict;
+}
+
+
+NSR.addVlrDataPromise = function(req, nsrs) {
+    var api_server = req.query['api_server'];
+    var promises = [];
+    nsrs.map(function(nsr) {
+        var vlrPromises = [];
+        var vlr = nsr['vlr'];
+        nsr['decorated-vlrs'] = [];
+        if (!vlr) {
+            console.log('No VL\'s found in NS');
+        }
+        vlr && vlr.map(function(vlrObject) {
+            req.params.id = vlrObject['vlr-ref'];
+            var vlrPromise = VLR.get(req).then(function(vlr) {
+                try {
+                    var vlrItem = vlr['data'][0];
+                    decorateNSRWithVLR(nsr, vlrObject, vlrItem);
+                } catch (e) {
+                    console.log('Expection caught getting VLRs and adding to NSR:', e);
+                }
+            })
+            vlrPromises.push(vlrPromise);
+        });
+        var NSR_Promise = new Promise(function(resolve, reject) {
+            Promise.all(vlrPromises).then(function() {
+                resolve();
+            })
+        });
+        promises.push(NSR_Promise);
+    });
+    return promises;
+
+    function decorateNSRWithVLR(nsr, nsrVLRObject, vlr) {
+        var vlrObject = _.extend(nsrVLRObject, vlr);
+        vlrObject['vnfr-connection-point-ref'] && vlrObject['vnfr-connection-point-ref'].map(function(vnfrCP) {
+            var vnfrName = nsr['vnfrs'] && _.find(nsr['vnfrs'], {id: vnfrCP['vnfr-id']})['name'];
+            vnfrName && (vnfrCP['vnfr-name'] = vnfrName);
+        });
+        nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'name'), 0, vlrObject);
+        // nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'create-time'), 0, vlrObject);
+    }
+}
+
+
+NSR.addVnfrDataPromise = function(req, nsrs) {
+    var api_server = req.query['api_server'];
+    var promises = [];
+    nsrs.map(function(nsr) {
+        var epa_params = {};
+        var constituent_vnfr_ref = nsr["constituent-vnfr-ref"];
+        var vnfrPromises = [];
+        nsr["vnfrs"] = [];
+        nsr["dashboard-urls"] = [];
+        nsr['nfvi-metrics'] = [];
+        if (!constituent_vnfr_ref) {
+            console.log('Something is wrong, there are no constituent-vnfr-refs');
+            constituent_vnfr_ref = [];
+        }
+        //Get VNFR Static Data
+        constituent_vnfr_ref && constituent_vnfr_ref.map(function(constituentVnfrObj) {
+            req.params.id = constituentVnfrObj['vnfr-id'];
+            var vnfrPromise;
+            vnfrPromise = VNFR.get(req).then(function(vnfr) {
+                try {
+                    var vnfrItem = vnfr[0];
+                    decorateNSRWithVNFR(nsr, vnfrItem)
+                    staticVNFRCache[vnfrItem.id] = vnfrItem;
+                } catch (e) {
+                    console.log('Exception caught:', e);
+                }
+            });
+            vnfrPromises.push(vnfrPromise);
+        });
+        var NSR_Promise = new Promise(function(resolve, reject) {
+            Promise.all(vnfrPromises).then(function() {
+                var vnfrs = staticVNFRCache;
+                //Aggregate EPA Params
+                constituent_vnfr_ref && constituent_vnfr_ref.map(function(k) {
+                        if (vnfrs[k['vnfr-id']]) {
+                            epa_params = epa_aggregator(vnfrs[k['vnfr-id']].vdur, epa_params);
+                        }
+                    })
+                //Add VNFR Name to monitoring params
+                try {
+                    if (nsr["monitoring-param"]) {
+                        nsr["monitoring-param"].map(function(m) {
+                            var vnfr = vnfrs[m["vnfr-id"]] || {};
+                            m["vnfr-name"] = vnfr['name'] ? vnfr['name'] : (vnfr['short-name'] ? vnfr['short-name'] : 'VNFR');
+                        });
+                    }
+                } catch (e) {
+                    console.log('Exception caught:', e);
+                }
+                resolve();
+            })
+        })
+        nsr["epa-params"] = epa_params;
+        promises.push(NSR_Promise);
+    })
+    return promises;
+
+    function decorateNSRWithVDURConsoleUrls(nsr, vnfr) {
+        nsr['console-urls'] = nsr['console-urls'] ? nsr['console-urls'] : [];
+
+        vnfr && vnfr['vdur'] && vnfr['vdur'].map(function(vdur) {
+            vdur['console-url'] && nsr['console-urls'].push({
+                id: vdur.id,
+                name: vdur.name,
+                'console-url': vdur['console-url']
+            });
+        });
+    }
+
+    function decorateNSRWithVNFR(nsr, vnfr) {
+        var vnfrObj = {
+            id: vnfr.id,
+            "member-vnf-index-ref": vnfr["member-vnf-index-ref"],
+            "short-name": vnfr["short-name"],
+            "vnf-configuration": vnfr["vnf-configuration"],
+            "nsr-id": nsr['ns-instance-config-ref'],
+            "name": vnfr['name'],
+            "vdur": vnfr["vdur"],
+            "cloud-account": vnfr["cloud-account"]
+        };
+        var vnfrSg = nsr['vnfr-scaling-groups'];
+        var vnfrName = vnfr["name"];
+        if(vnfrSg) {
+            if(vnfrSg[vnfr.id]) {
+                vnfrName = vnfrSg[vnfr.id]["scaling-group-name-ref"] + ':' + vnfrSg[vnfr.id][ "instance-id"] + ':' + vnfrName;
+            }
+        }
+        var vnfrNfviMetrics = buildNfviGraphs(vnfr.vdur, vnfrName);
+        if (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) {
+            vnfrObj['service-primitives-present'] = true;
+        } else {
+            vnfrObj['service-primitives-present'] = false;
+        }
+               transforms.mergeVnfrNfviMetrics(vnfrNfviMetrics, nsr["nfvi-metrics"]);
+        //TODO: Should be sorted by create-time when it becomes available instead of id
+        // nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'create-time'), 0, vnfrObj);
+        nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'id'), 0, vnfrObj);
+        vnfrObj["dashboard-url"] = vnfr["dashboard-url"];
+        nsr["dashboard-urls"].push(vnfrObj);
+
+        decorateNSRWithVDURConsoleUrls(nsr, vnfr);
+    }
+}
+NSR.create = function(req) {
+    var api_server = req.query['api_server'];
+    var data = req.body.data;
+    console.log('Instantiating NSR on ', api_server);
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config',
+            method: 'POST',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: data
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.create', error, response, body, resolve, reject)) {
+                var nsr_id = null;
+                try {
+                    nsr_id = data.nsr[0].id;
+                } catch (e) {
+                    console.log("NSR.create unable to get nsr_id. Error: %s",
+                    e.toString());
+                }
+                resolve({
+                    statusCode: response.statusCode,
+                    data: { nsr_id: nsr_id }
+                 });
+            };
+        });
+    });
+};
+NSR.delete = function(req) {
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+    if (!id || !api_server) {
+        return new Promise(function(resolve, reject) {
+            console.log('Must specifiy api_server and id to delete NSR');
+            return reject({
+                statusCode: 500,
+                errorMessage: {
+                    error: 'Must specifiy api_server and id to delete NSR'
+                }
+            });
+        });
+    };
+    console.log('Deleting NSR with id: ' + id + 'on server: ' + api_server);
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id,
+            method: 'DELETE',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.delete', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    });
+};
+NSR.decorateAndTransformNFVI = function(nsr) {
+        var toDecorate = [];
+        // var metricsToUse = ["vcpu", "memory", "storage", "network"];
+        var metricsToUse = ["vcpu", "memory"];
+        try {
+            var nfviMetrics = nsr["rw-nsr:nfvi-metrics"];
+            if (nfviMetrics) {
+                metricsToUse.map(function(name) {
+                    toDecorate.push(nfviMetrics[name])
+                });
+            }
+            nsr["nfvi-metrics"] = toDecorate;
+            delete nsr["rw-nsr:nfvi-metrics"];
+        } catch (e) {}
+        return nsr;
+    }
+    //Not a great pattern, Need a better way of handling logging;
+    //Refactor and move to the logging/logging.js
+var logCache = {
+    decorateAndTransformWithControls: {}
+}
+NSR.decorateAndTransformWithControls = function(nsr) {
+    var controlTypes = ["action-param", "control-param"];
+    var nsControls = [];
+    var Groups = {};
+    controlTypes.map(function(control) {
+        try {
+            var controls = nsr["rw-nsr:" + control];
+            // nsControls.push(controls);
+            controls.map(function(item) {
+                if (!Groups[item["group-tag"]]) {
+                    Groups[item["group-tag"]] = {};
+                    Groups[item["group-tag"]]["action-param"] = []
+                    Groups[item["group-tag"]]["control-param"] = []
+                }
+                Groups[item["group-tag"]][control].push(item);
+            });
+            delete nsr["rw-nsr:" + control];
+        } catch (e) {
+            var id = nsr["ns-instance-config-ref"];
+            if (!logCache.decorateAndTransformWithControls[id]) {
+                logCache.decorateAndTransformWithControls[id] = {};
+            }
+            var log = logCache.decorateAndTransformWithControls[id];
+            if (!log[control]) {
+                log[control] = true;
+                console.log('No controls exist for ' + control + ' at ' + nsr["ns-instance-config-ref"]);
+            }
+        }
+    });
+    for (k in Groups) {
+        var obj = {}
+        obj[k] = Groups[k];
+        nsControls.push(obj)
+    }
+    nsr.nsControls = nsControls;
+    return nsr;
+};
+NSR.setStatus = function(req) {
+    var api_server = req.query['api_server'];
+    var id = req.params.id;
+    var status = req.body.status;
+    console.log('Setting NSR (id: ' + id + ') status, on ' + api_server + ', to be: ' + status);
+    return new Promise(function(resolve, reject) {
+        var command;
+        if (typeof(status) != "string") {
+            reject({
+                'ERROR': 'NSR.setStatus Error: status is not a string type'
+            });
+        }
+        command = status.toUpperCase();
+        if (command != "ENABLED" && command != "DISABLED") {
+            reject({
+                'ERROR': 'NSR.setStatus Error: status is: ' + command + '. It should be ENABLED or DISABLED'
+            });
+        }
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/admin-status/',
+            method: 'PUT',
+            headers: requestHeaders,
+            json: {
+                "nsr:admin-status": command
+            },
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.setStatus', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            };
+        });
+    });
+};
+
+NSR.createScalingGroupInstance = function(req) {
+    var api_server = req.query['api_server'];
+    var id = req.params.id;
+    var scaling_group_id = req.params.scaling_group_id;
+    if (!api_server || !id || !scaling_group_id) {
+        return new Promise(function(resolve, reject) {
+            return reject({
+                statusCode: 500,
+                errorMessage: {
+                    error: 'API server/NSR id/Scaling group not provided'
+                }
+            });
+        });
+    }
+
+    var instance_id = Math.floor(Math.random() * 65535);
+
+    var jsonData = {
+        instance: [{
+            // id: uuid.v1()
+            id: instance_id
+        }]
+    };
+
+    console.log('Creating scaling group instance for NSR ', id, ', scaling group ', scaling_group_id, ' with instance id ', instance_id);
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data,
+            {
+                'Authorization': req.get('Authorization')
+            }
+        );
+
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/scaling-group/' + scaling_group_id + '/instance',
+            method: 'POST',
+            headers: requestHeaders,
+            json: jsonData,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false
+        }, function (error, response, body) {
+            if (utils.validateResponse('NSR.createScalingGroupInstance', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode,
+                    data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
+                })
+            }
+        });
+    });
+};
+
+NSR.deleteScalingGroupInstance = function(req) {
+    var api_server=req.query['api_server'];
+    var id = req.params.id;
+    var scaling_group_id = req.params.scaling_group_id;
+    var scaling_instance_id = req.params.scaling_instance_id;
+
+    if (!api_server || !id || !scaling_group_id || !scaling_instance_id) {
+        return new Promise(function(resolve, reject) {
+            return reject({
+                statusCode: 500,
+                errorMessage: {
+                    error: 'API server/NSR id/Scaling group/Scaling instance id not provided'
+                }
+            });
+        });
+    }
+
+    console.log('Deleting scaling group instance id ', scaling_instance_id,
+        ' for scaling group ', scaling_group_id,
+        ', under NSR ', id);
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data,
+            {
+                'Authorization': req.get('Authorization')
+            }
+        );
+
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/scaling-group/' + scaling_group_id + '/instance/' + scaling_instance_id,
+            method: 'DELETE',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false
+        }, function (error, response, body) {
+            if (utils.validateResponse('NSR.deleteScalingGroupInstance', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode,
+                    data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
+                })
+            }
+        });
+    });
+};
+
+NSR.nsd = {};
+NSR.nsd.vld = {};
+
+NSR.nsd.vld.get = function(req) {
+    var api_server = req.query['api_server'];
+    var nsr_id = req.params.nsr_id;
+    var vld_id = req.params.vld_id;
+
+    if (!api_server || !nsr_id) {
+        return new Promise(function(resolve, reject) {
+            return reject({
+                statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
+                errorMessage: 'API server/NSR id not provided'
+            });
+        })
+    }
+    console.log('Getting VLD', vld_id ? (' ' + vld_id) : ('\'s'), ' for NSR id', nsr_id);
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            vld_id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection,
+            {
+                'Authorization': req.get('Authorization')
+            }
+        );
+
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld' + (vld_id ? '/' + vld_id : '')  +'?deep',
+            method: 'GET',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false
+        }, function (error, response, body) {
+            if (utils.validateResponse('NSR.nsd.vld.get', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode,
+                    data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
+                });
+            }
+        });
+    });
+};
+
+NSR.nsd.vld.create = function(req) {
+    var api_server = req.query['api_server'];
+    var nsr_id = req.params.nsr_id;
+    var vld_id = req.params.vld_id;
+    var data = req.body;
+
+    if (!api_server || !nsr_id) {
+        return new Promise(function(resolve, reject) {
+            return reject({
+                statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
+                errorMessage: 'API server/NSR id not provided'
+            });
+        });
+    }
+
+    console.log((vld_id ? 'Updating VLD ' + vld_id : 'Creating VLD') + ' under NSR', nsr_id);
+
+    var jsonData = {
+        vld: typeof(data) == 'string' ? JSON.parse(data) : data
+    };
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
+            'Authorization': req.get('Authorization')
+        });
+        request({
+            uri: utils.confdPort(api_server) + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld' + (vld_id ? '/' + vld_id : ''),
+            method: vld_id ? 'PUT' : 'POST',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData
+        }, function(error, response, body) {
+            if (utils.validateResponse('NSR.nsd.vld.create/update', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode,
+                    data: (typeof(response.body) == 'string') ? JSON.parse(response.body) : response.body
+                });
+            }
+        });
+    });
+};
+
+NSR.nsd.vld.update = NSR.nsd.vld.create;
+
+NSR.nsd.vld.delete = function(req) {
+    var api_server = req.query['api_server'];
+    var nsr_id = req.params.nsr_id;
+    var vld_id = req.params.vld_id;
+
+    if (!api_server || !nsr_id || !vld_id) {
+        return new Promise(function(resolve, reject) {
+            return reject({
+                statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
+                errorMessage: 'API server/NSR id/VLD id not provided'
+            });
+        })
+    }
+    console.log('Deleting VLD', vld_id, 'for NSR id', nsr_id);
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            {
+                'Authorization': req.get('Authorization')
+            }
+        );
+
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld/' + vld_id,
+            method: 'DELETE',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false
+        }, function (error, response, body) {
+            if (utils.validateResponse('NSR.nsd.vld.delete', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode,
+                    data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
+                });
+            }
+        });
+    });
+}
+
+VNFR.get = function(req) {
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+    var uri = utils.confdPort(api_server);
+    uri += APIVersion + '/api/operational/vnfr-catalog/vnfr' + (id ? '/' + id : '') + '?deep';
+    var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+        'Authorization': req.get('Authorization')
+    });
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri,
+            method: 'GET',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('VNFR.get', error, response, body, resolve, reject)) {
+                var data = JSON.parse(response.body);
+                var returnData = id ? [data["vnfr:vnfr"]] : data.collection["vnfr:vnfr"];
+                returnData.forEach(function(vnfr) {
+                    vnfr['nfvi-metrics'] = buildNfviGraphs(vnfr.vdur);
+                    vnfr['epa-params'] = epa_aggregator(vnfr.vdur);
+                    vnfr['service-primitives-present'] = (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) ? true : false;
+                })
+                return resolve(returnData);
+            };
+        });
+    });
+}
+
+function buildNfviGraphs(VDURs, vnfrName){
+        var temp = {};
+        var toReturn = [];
+        APIConfig.NfviMetrics.map(function(k) {
+
+            VDURs && VDURs.map(function(v,i) {
+                //Check for RIFT-12699: VDUR NFVI Metrics not fully populated
+                if (v["rw-vnfr:nfvi-metrics"] && v["rw-vnfr:nfvi-metrics"][k] && v["rw-vnfr:nfvi-metrics"][k].hasOwnProperty('utilization')) {
+                    if(!temp[k]) {
+                        temp[k] = {
+                            title: '',
+                            data: []
+                        };
+                    };
+                    try {
+                        var data = v["rw-vnfr:nfvi-metrics"][k];
+                        var newData = {};
+                        newData.name = v.name ? v.name : v.id.substring(0,6);
+                        newData.name = vnfrName ? vnfrName + ': ' + newData.name : newData.name;
+                        newData.id = v.id;
+                        //converts to perentage
+                        newData.utilization = data.utilization * 0.01;
+                        temp[k].data.push(newData);
+                        temp[k].title = v["rw-vnfr:nfvi-metrics"][k].label;
+                    } catch (e) {
+                        console.log('Something went wrong with the VNFR NFVI Metrics. Check that the data is being properly returned. ERROR: ', e);
+                    }
+                }
+            });
+            if(temp[k]) {
+                toReturn.push(temp[k]);
+            }
+        });
+        return toReturn;
+    }
+
+
+//Cache NSR reference for VNFR
+VNFR.cachedNSR = {};
+VNFR.getByNSR = function(req) {
+    var api_server = req.query["api_server"];
+    var id = req.params.nsr_id;
+    var uri = utils.confdPort(api_server);
+    var reqClone = _.clone(req);
+    delete reqClone.params.id;
+    uri += APIVersion + '/api/operational/ns-instance-opdata/nsr/' + id + '?deep';
+    var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+        'Authorization': req.get('Authorization')
+    });
+    return new Promise(function(resolve, reject) {
+        if (VNFR.cachedNSR[id]) {
+            var data = VNFR.cachedNSR[id];
+            var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
+            VNFR.get(reqClone).then(function(vnfrData) {
+                resolve(filterVnfrByList(vnfrList, vnfrData));
+            });
+        } else {
+            request({
+                url: uri,
+                method: 'GET',
+                headers: headers,
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+            }, function(error, response, body) {
+                if (utils.validateResponse('VNFR.getByNSR', error, response, body, resolve, reject)) {
+                    var data = JSON.parse(response.body);
+                    data = data["nsr:nsr"];
+                    //Cache NSR data with NSR-ID as
+                    VNFR.cachedNSR[id] = data;
+                    var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
+                    var returnData = [];
+                    VNFR.get(reqClone).then(function(vnfrData) {
+                        resolve(filterVnfrByList(vnfrList, vnfrData));
+                    });
+                };
+            });
+        }
+    });
+};
+
+function filterVnfrByList(vnfrList, vnfrData) {
+    return vnfrData.map(function(vnfr) {
+        if (vnfrList.indexOf(vnfr.id) > -1) {
+            return vnfr;
+        }
+    })
+};
+
+VLR.get = function(req) {
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+    var uri = utils.confdPort(api_server);
+    uri += APIVersion + '/api/operational/vlr-catalog/vlr' + (id ? '/' + id : '') + '?deep';
+    var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+        'Authorization': req.get('Authorization')
+    });
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri,
+            method: 'GET',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('VLR.get', error, response, body, resolve, reject)) {
+                var data = JSON.parse(response.body);
+                var returnData = id ? [data["vlr:vlr"]] : data.collection["vlr:vlr"];
+                return resolve({
+                    data: returnData,
+                    statusCode: response.statusCode
+                });
+            };
+        });
+    });
+}
+
+RIFT.api = function(req) {
+    var api_server = req.query["api_server"];
+    var uri = utils.confdPort(api_server);
+    var url = req.path;
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri + url + '?deep',
+            method: 'GET',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('RIFT.api', error, response, body, resolve, reject)) {
+                resolve(JSON.parse(response.body))
+            };
+        })
+    })
+};
+
+ComputeTopology.get = function(req) {
+    var api_server = req.query['api_server'];
+    var nsr_id = req.params.id;
+    var result = {
+        id: nsr_id, // node id
+        name: nsr_id, // node name to display
+        parameters: {}, // the parameters that can be used to determine size/color, etc. for the node
+        type: 'nsr',
+        children: [] // children for the node
+    };
+    return new Promise(function(resolve, reject) {
+        var nsrPromise = new Promise(function(success, failure) {
+            request({
+                uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr/' + nsr_id + '?deep',
+                method: 'GET',
+                headers: _.extend({},
+                    constants.HTTP_HEADERS.accept.data, {
+                        'Authorization': req.get('Authorization')
+                    }),
+                forever: constants.FOREVER_ON,
+                rejectUnauthorized: false,
+            }, function(error, response, body) {
+                if (utils.validateResponse('ComputeTopology.get ns-instance-opdata/nsr/:id', error, response, body, success, failure)) {
+                    var data;
+                    var isString = typeof(response.body) == "string";
+                    if (isString && response.body == '') {
+                        return success({});
+                    }
+                    try {
+                        data = isString ? JSON.parse(response.body) : response.body;
+
+                        var nsrNFVIMetricData = data["nsr:nsr"]["rw-nsr:nfvi-metrics"];
+                        result.parameters = nsrNFVIMetricData;
+
+                        result.name = data["nsr:nsr"]["name-ref"];
+
+                        var nsrData = data["nsr:nsr"]["constituent-vnfr-ref"];
+                        success(nsrData);
+                    } catch (e) {
+                        console.log('Error parsing ns-instance-opdata for NSR ID', nsr_id, 'Exception:', e);
+                        return failure()
+                    }
+                };
+            });
+        }).then(function(data) {
+
+            try {
+                // got NSR data
+                // now get VNFR data and populate the structure
+                var vnfrPromises = [];
+
+                // Run separately to confirm that primary structure is populated before promise resolution takes over
+                // and starts modifying the data
+                data.forEach(function(vnfrObj) {
+
+                   var vnfrId = vnfrObj['vnfr-id'];
+
+                    // If anything needs to be added to result for each vnfrId, do it here
+
+                    vnfrPromises.push(
+                        new Promise(function(success, failure) {
+                            rp({
+                                uri: utils.confdPort(api_server) + APIVersion + '/api/operational/vnfr-catalog/vnfr/' + vnfrId + '?deep',
+                                method: 'GET',
+                                headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                                    'Authorization': req.get('Authorization')
+                                }),
+                                forever: constants.FOREVER_ON,
+                                rejectUnauthorized: false,
+                                resolveWithFullResponse: true
+                            }, function(error, response, body) {
+                                if (utils.validateResponse('ComputeTopology.get vnfr-catalaog/vnfr/:id', error, response, body, success, failure)) {
+                                    try {
+                                        var data = JSON.parse(response.body);
+                                        var returnData = data["vnfr:vnfr"];
+
+                                        // Push VNFRs in result
+                                        result.children.push({
+                                            id: vnfrId,
+                                            name: returnData.name,
+                                            parameters: {}, // nfvi metrics here
+                                            children: [],
+                                            type: 'vnfr'
+                                        });
+
+                                        // Push VDURs in result
+                                        returnData.vdur.forEach(function(vdur) {
+                                            result.children[result.children.length - 1].children.push({
+                                                id: vdur.id,
+                                                name: vdur.id,
+                                                parameters: {},
+                                                type: 'vdur'
+                                                    // children: []
+                                            });
+                                        });
+
+                                        return success(returnData.vdur);
+                                    } catch (e) {
+                                        console.log('Error parsing vnfr-catalog for VNFR ID', vnfrId, 'Exception:', e);
+                                        return failure();
+                                    }
+                                };
+                            });
+                        })
+                    );
+                });
+
+                Promise.all(vnfrPromises).then(function(output) {
+                    console.log('Resolved all VNFR requests successfully');
+                    // By now result must be completely populated. output is moot
+
+                    // Sort the results as there's no order to them from RIFT-REST
+                    result.children.sort(sortByName);
+
+                    result.children.forEach(function(vnfr) {
+                        vnfr.children.sort(sortByName);
+                    });
+
+                    resolve({
+                        statusCode: 200,
+                        data: result
+                    });
+                }).catch(function(error) {
+                    // Todo: Can this be made better?
+                    // Right now if one of the southbound APIs fails - we just return what's populated so far in result
+                    console.log('Problem with ComputeTopology.get vnfr-catalog/vnfr/:id', error, 'Resolving with partial data', result);
+                    resolve({
+                        statusCode: 200,
+                        data: result
+                    });
+                });
+            } catch (e) {
+                // API came back with empty ns-instance-opdata response for NSR ID
+                // bail
+                console.log('Error iterating through ns-instance-opdata response for NSR ID', nsr_id, 'Exception:', e);
+                resolve({
+                    statusCode: 200,
+                    data: result
+                })
+            }
+        }, function(error) {
+            // failed to get NSR data.
+            // bail
+            resolve({
+                statusCode: 200,
+                data: result
+            });
+        });
+    });
+};
+
+NetworkTopology.get = function(req) {
+    var api_server = req.query["api_server"];
+    var uri = utils.confdPort(api_server);
+    uri += APIVersion + '/api/operational/network?deep';
+    var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+    });
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri,
+            method: 'GET',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false
+        }, function(error, response, body) {
+            if (utils.validateResponse('NetworkTopology.get', error, response, body, resolve, reject)) {
+                var data = JSON.parse(response.body);
+                var returnData = transforms.transformNetworkTopology(
+                    data["ietf-network:network"]
+                );
+                resolve({
+                    statusCode: 200,
+                    data: returnData
+                });
+            };
+        });
+    })
+}
+
+VDUR.get = function(req) {
+    var api_server = req.query["api_server"];
+    var vnfrID = req.params.vnfr_id;
+    var vdurID = req.params.vdur_id;
+    var uri = utils.confdPort(api_server);
+    uri += APIVersion + '/api/operational/vnfr-catalog/vnfr/' + vnfrID + '/vdur/' + vdurID + '?deep';
+    var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
+        'Authorization': req.get('Authorization')
+    });
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri,
+            method: 'GET',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('VDUR.get', error, response, body, resolve, reject)) {
+                var data = JSON.parse(response.body);
+                var returnData = data["vdur:vdur"];
+                return resolve(returnData);
+            };
+        });
+    })
+}
+
+CloudAccount.get = function(req) {
+    var api_server = req.query["api_server"];
+    var uri = utils.confdPort(api_server);
+    uri += APIVersion + '/api/config/cloud/account?deep';
+    var headers = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+        'Authorization': req.get('Authorization')
+    });
+    return new Promise(function(resolve, reject) {
+        request({
+            url: uri,
+            method: 'GET',
+            headers: headers,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('CloudAccount.get', error, response, body, resolve, reject)) {
+                var data = JSON.parse(response.body);
+                var returnData = data["collection"]["rw-cloud:account"];
+                resolve({
+                    statusCode: 200,
+                    data: returnData
+                });
+            };
+        });
+    });
+}
+
+
+// Config-Agent Account APIs
+ConfigAgentAccount.get = function(req) {
+    var self = this;
+
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+
+    if (!id) {
+        // Get all config accounts
+        return new Promise(function(resolve, reject) {
+
+            var requestHeaders = {};
+            _.extend(requestHeaders,
+                constants.HTTP_HEADERS.accept.collection, {
+                    'Authorization': req.get('Authorization')
+                });
+
+            request({
+                    url: utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account',
+                    type: 'GET',
+                    headers: requestHeaders,
+                    forever: constants.FOREVER_ON,
+                    rejectUnauthorized: false,
+                },
+                function(error, response, body) {
+                    var data;
+                    var statusCode;
+                    if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
+                        try {
+                            data = JSON.parse(response.body).collection['rw-config-agent:account'];
+                            statusCode = response.statusCode;
+                        } catch (e) {
+                            console.log('Problem with "ConfigAgentAccount.get"', e);
+                            var err = {};
+                            err.statusCode = 500;
+                            err.errorMessage = {
+                                error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
+                            }
+                            return reject(err);
+                        }
+
+                        return resolve({
+                            statusCode: statusCode,
+                            data: data
+                        });
+                    };
+                });
+        });
+    } else {
+        //Get a specific config account
+        return new Promise(function(resolve, reject) {
+            var requestHeaders = {};
+            _.extend(requestHeaders,
+                constants.HTTP_HEADERS.accept.data, {
+                    'Authorization': req.get('Authorization')
+                });
+
+            request({
+                    url: utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account/' + id,
+                    type: 'GET',
+                    headers: requestHeaders,
+                    forever: constants.FOREVER_ON,
+                    rejectUnauthorized: false,
+                },
+                function(error, response, body) {
+                    var data;
+                    var statusCode;
+                    if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
+                        try {
+                            data = JSON.parse(response.body)['rw-config-agent:account'];
+                            statusCode = response.statusCode;
+                        } catch (e) {
+                            console.log('Problem with "ConfigAgentAccount.get"', e);
+                            var err = {};
+                            err.statusCode = 500;
+                            err.errorMessage = {
+                                error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
+                            }
+                            return reject(err);
+                        }
+
+                        return resolve({
+                            statusCode: statusCode,
+                            data: data
+                        });
+                    }
+                });
+        });
+    }
+};
+
+ConfigAgentAccount.create = function(req) {
+
+    var api_server = req.query["api_server"];
+    var data = req.body;
+
+    return new Promise(function(resolve, reject) {
+        var jsonData = {
+            "account": Array.isArray(data) ? data : [data]
+        };
+
+        console.log('Creating with', JSON.stringify(jsonData));
+
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            });
+
+        request({
+            url: utils.confdPort(api_server) + APIVersion + '/api/config/config-agent',
+            method: 'POST',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData,
+        }, function(error, response, body) {
+            if (utils.validateResponse('ConfigAgentAccount.create', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body),
+                    body:response.body.body
+                });
+            };
+        });
+    });
+};
+
+ConfigAgentAccount.update = function(req) {
+
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+    var data = req.body;
+
+    return new Promise(function(resolve, reject) {
+        var jsonData = {
+            "rw-config-agent:account": data
+        };
+
+        console.log('Updating config-agent', id, ' with', JSON.stringify(jsonData));
+
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data,
+            constants.HTTP_HEADERS.content_type.data, {
+                'Authorization': req.get('Authorization')
+            });
+
+        request({
+            url: utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + id,
+            method: 'PUT',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+            json: jsonData,
+        }, function(error, response, body) {
+            if (utils.validateResponse('ConfigAgentAccount.update', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    });
+};
+
+ConfigAgentAccount.delete = function(req) {
+
+    var api_server = req.query["api_server"];
+    var id = req.params.id;
+
+    if (!id || !api_server) {
+        return new Promise(function(resolve, reject) {
+            console.log('Must specifiy api_server and id to delete config-agent account');
+            return reject({
+                statusCode: 500,
+                errorMessage: {
+                    error: 'Must specifiy api_server and id to delete config agent account'
+                }
+            });
+        });
+    };
+
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            });
+        request({
+            url: utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + id,
+            method: 'DELETE',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('ConfigAgentAccount.delete', error, response, body, resolve, reject)) {
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: JSON.stringify(response.body)
+                });
+            };
+        });
+    });
+};
+
+
+DataCenters.get = function(req) {
+    var api_server = req.query["api_server"];
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            });
+        request({
+            url: utils.confdPort(api_server) + APIVersion + '/api/operational/datacenters/cloud-accounts?deep',
+            method: 'GET',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('DataCenters.get', error, response, body, resolve, reject)) {
+                var returnData = {};
+                try {
+                    data = JSON.parse(response.body)['rw-launchpad:cloud-accounts'];
+                    data.map(function(c) {
+                        returnData[c.name] = c.datacenters;
+                    })
+                    statusCode = response.statusCode;
+                } catch (e) {
+                    console.log('Problem with "DataCenters.get"', e);
+                    var err = {};
+                    err.statusCode = 500;
+                    err.errorMessage = {
+                        error: 'Problem with "DataCenters.get": ' + e.toString()
+                    }
+                    return reject(err);
+                }
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: returnData
+                });
+            };
+        });
+    });
+}
+
+SSHkey.get  = function(req) {
+    var api_server = req.query["api_server"];
+    return new Promise(function(resolve, reject) {
+        var requestHeaders = {};
+        _.extend(requestHeaders,
+            constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            });
+        request({
+            url: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair?deep',
+            method: 'GET',
+            headers: requestHeaders,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('SSHkey.get', error, response, body, resolve, reject)) {
+                var returnData = {};
+                try {
+                    returnData = JSON.parse(response.body)['nsr:key-pair'];
+                    statusCode = response.statusCode;
+                } catch (e) {
+                    console.log('Problem with "SSHkey.get"', e);
+                    var err = {};
+                    err.statusCode = 500;
+                    err.errorMessage = {
+                        error: 'Problem with "SSHkey.get": ' + e.toString()
+                    }
+                    return reject(err);
+                }
+                return resolve({
+                    statusCode: response.statusCode,
+                    data: returnData
+                });
+            };
+        });
+    });
+}
+SSHkey.delete = function(req) {
+    var api_server = req.query['api_server'];
+    var id = decodeURI(req.params.name);
+    console.log('Deleting ssk-key', id);
+    return new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/' + id,
+            method: 'DELETE',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('SSHkey.delete', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+SSHkey.post = function(req) {
+    var api_server = req.query['api_server'];
+    var data = req.body;
+    return new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/',
+            method: 'POST',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            json: data,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('SSHkey.post', error, response, body, resolve, reject)) {
+                resolve({
+                    data: 'success',
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+SSHkey.put = function(req) {
+    var api_server = req.query['api_server'];
+    var data = req.body;
+    return new Promise(function(resolve, reject) {
+        request({
+            uri: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/',
+            method: 'PUT',
+            headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+                'Authorization': req.get('Authorization')
+            }),
+            json: data,
+            forever: constants.FOREVER_ON,
+            rejectUnauthorized: false,
+        }, function(error, response, body) {
+            if (utils.validateResponse('SSHkey.put', error, response, body, resolve, reject)) {
+                resolve({
+                    statusCode: response.statusCode
+                });
+            }
+        });
+    });
+};
+
+function sortByName(a, b) {
+    return a.name > b.name;
+}
+
+module.exports.catalog = Catalog;
+module.exports.nsr = NSR;
+module.exports.vnfr = VNFR;
+module.exports.vlr = VLR;
+module.exports.rift = RIFT;
+module.exports.computeTopology = ComputeTopology;
+module.exports.networkTopology = NetworkTopology;
+module.exports.config = Config;
+module.exports.cloud_account = CloudAccount;
+module.exports['config-agent-account'] = ConfigAgentAccount;
+module.exports.rpc = RPC;
+module.exports.data_centers = DataCenters;
+module.exports.SSHkey = SSHkey;
diff --git a/skyquake/plugins/launchpad/api/launchpad_.js b/skyquake/plugins/launchpad/api/launchpad_.js
new file mode 100644 (file)
index 0000000..fcc1a53
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var request = require('request');
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var constants = require('../../../framework/core/api_utils/constants.js');
+var APIVersion = '/v1';
+
+var Launchpad = {};
diff --git a/skyquake/plugins/launchpad/api/transforms.js b/skyquake/plugins/launchpad/api/transforms.js
new file mode 100644 (file)
index 0000000..d3044b8
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var _ = require('lodash');
+
+/**
+ * Merges vnfr["nfvi-metrics"] with nsr["nfvi-metrics"] into a format consumable by the UI LP and Record Cards
+ * @param  {Array} vnfr vnfr nfvi metrics
+ * @param  {Array} nsr  nsr nfvi metrics
+ * @return {Array}      Merged NSR nfvi metrics
+ */
+function mergeVnfrNfviMetrics(vnfr, nsr) {
+    for (var i = 0; i < vnfr.length; i ++) {
+        var title = vnfr[i].title;
+        var matched = false;
+        for (var j = 0; j < nsr.length; j++) {
+            if (nsr[j] && nsr[j].title == title) {
+                matched = true;
+                nsr[j].data = nsr[j].data.concat(vnfr[i].data).sort(function(a,b) {
+                    return (a.name > b.name) ? 1 : -1;
+                });
+                break;
+            }
+        }
+        if (!matched) {
+            nsr.push({
+                title: title,
+                data: vnfr[i].data
+            });
+        }
+    }
+}
+
+function terminationPointValues (node) {
+    var tpids = [];
+    var attrs = { 'tp-id': [] };
+    var TERM_PT_KEY = 'ietf-network-topology:termination-point';
+    var TERM_PT_ATTR_KEY = 'ietf-l2-topology:l2-termination-point-attributes';
+
+    var node_id = node['node-id'];
+    node[TERM_PT_KEY].forEach(
+        function(elem, index, array) {
+            if ('tp-id' in elem) {
+                attrs['tp-id'].push(elem['tp-id'])
+            }
+            if (TERM_PT_ATTR_KEY in elem) {
+                for (var key in elem[TERM_PT_ATTR_KEY]) {
+                    if (!(key in attrs)) {
+                        attrs[key] = _.cloneDeep(elem[TERM_PT_ATTR_KEY][key]);
+                    }
+                }
+            }
+        });
+    return {
+        'node-id': node_id,
+        attrs: attrs
+    }
+}
+
+// Transforms one or more topologies into a collection of nodes, links
+// usable by D3.js
+function transformNetworkTopology(raw) {
+    var nodes = [];
+    var links = [];
+
+    var y = 0;
+    var id = 1;
+
+    var node_mapper = {};
+    var network_ids = [];
+
+    var networks = raw;
+    if ('collection' in raw) {
+        networks = raw.collection;
+    }
+    if ('ietf-network:network' in networks) {
+        networks = networks['ietf-network:network'];
+    }
+
+    // for each network in the array of networks
+    for (var net_index=0, tot_networks=networks.length; net_index < tot_networks; net_index++) {
+        var network = networks[net_index];
+        var network_id = networks[net_index]['network-id'];
+        if (network_ids.indexOf(network_id) == -1) {
+            network_ids.push(network_id);
+        }
+        var raw_nodes = network['node'] || [];
+        var x = 0;
+        for (var index=0, tot=raw_nodes.length; index < tot; index++) {
+            var termination_point = [];
+            var new_node = {
+                id: id,
+                // TODO: make short name,
+                name: raw_nodes[index]['node-id'],
+                full_name: raw_nodes[index]['node-id'],
+                network: network_id,
+                x: x,
+                y: y,
+                attr: terminationPointValues(raw_nodes[index]).attrs
+            };
+            nodes.push(new_node);
+            // What do wse do if the name is already collected
+            node_mapper[new_node.name] = nodes.length-1;
+            x += 20;
+            id++;
+        }
+
+        var raw_links = network['ietf-network-topology:link'];
+        if (raw_links) {
+            for (var index=0, tot=raw_links.length; index < tot; index++) {
+                var source_name = raw_links[index]['source']['source-node'];
+                var dest_name = raw_links[index]['destination']['dest-node'];
+                var new_link = {
+                    source: node_mapper[source_name],
+                    target: node_mapper[dest_name]
+                };
+                links.push(new_link);
+            }
+        }
+        // prep for next network
+        y += 20;
+    }
+
+    // D3 is expecting array indexes of the nodes for the links
+    // Now for the links to find the nodes
+
+    return {
+        nodes: nodes,
+        links: links,
+        network_ids: network_ids
+    };
+}
+
+
+module.exports = {
+    transformNetworkTopology: transformNetworkTopology,
+    mergeVnfrNfviMetrics: mergeVnfrNfviMetrics
+}
diff --git a/skyquake/plugins/launchpad/config.json b/skyquake/plugins/launchpad/config.json
new file mode 100644 (file)
index 0000000..851239f
--- /dev/null
@@ -0,0 +1,61 @@
+{
+    "root": "public",
+    "name": "Launchpad",
+    "dashboard": "./launchpad.jsx",
+    "order": 1,
+    "priority":1,
+    "routes": [
+    {
+        "label": "Dashboard",
+        "route": "/",
+        "component": "./launchpad.jsx",
+        "path": "",
+        "query":"name",
+        "type": "external"
+    },{
+        "label": "Instantiate",
+        "route": "/instantiate",
+        "component": "./instantiate/instantiateDashboard.jsx",
+        "path": "",
+        "type": "external",
+        "routes": [
+            {
+                "label": "Instantiate",
+                "route": ":nsd",
+                "component": "./instantiate/instantiateParameters.jsx",
+                "path": ":nsd",
+                "type": "internal"
+            }
+        ]
+    },{
+        "label": "SSH Keys",
+        "route": "/ssh-keys",
+        "component": "./ssh_keys/sshKeys.jsx",
+        "path": "",
+        "type": "external"
+    },
+    {
+        "label": "Viewport",
+        "route": "/viewport",
+        "query": "id",
+        "component": "./recordViewer/recordView.jsx",
+        "type": "internal",
+        "routes": [
+
+        ]
+    },{
+        "label": "Compute Topology",
+        "route": "/compute-topology",
+        "query": "id",
+        "component": "./topologyView/topologyView.jsx",
+        "path": "",
+        "type": "internal"
+    },{
+        "label": "Network Topology",
+        "route": "/network-topology",
+        "query": "id",
+        "component": "./topologyL2View/topologyL2View.jsx",
+        "path": "",
+        "type": "internal"
+    }]
+}
diff --git a/skyquake/plugins/launchpad/package.json b/skyquake/plugins/launchpad/package.json
new file mode 100644 (file)
index 0000000..b953b71
--- /dev/null
@@ -0,0 +1,56 @@
+{
+  "name": "launchpad",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "RIFT.io",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "alt": "^0.18.3",
+    "bluebird": "^3.4.1",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "jquery": "^2.2.1",
+    "json-loader": "^0.5.4",
+    "lodash": "^4.10.0",
+    "node-uuid": "^1.4.7",
+    "normalizr": "^2.1.0",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.4.1",
+    "react": "^0.14.8",
+    "react-awesome-modal": "^0.3.3",
+    "react-breadcrumbs": "^1.3.9",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.6",
+    "react-router": "^2.0.1",
+    "react-slick": "^0.11.1",
+    "react-tabs": "^0.5.3",
+    "react-treeview": "^0.4.2",
+    "request-promise": "^3.0.0",
+    "underscore": "^1.8.3"
+  },
+  "devDependencies": {
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-polyfill": "^6.9.1",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "cors": "^2.7.1",
+    "css-loader": "^0.23.1",
+    "file-loader": "^0.8.5",
+    "html-webpack-plugin": "^2.9.0",
+    "http-proxy": "^1.12.0",
+    "loaders.css": "^0.1.2",
+    "node-sass": "^3.4.2",
+    "react-addons-css-transition-group": "^0.14.7",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "webpack": "^1.3.0",
+    "webpack-dev-server": "^1.10.1"
+  }
+}
diff --git a/skyquake/plugins/launchpad/routes.js b/skyquake/plugins/launchpad/routes.js
new file mode 100644 (file)
index 0000000..d8f6493
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var app = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js');
+var launchpadAPI = require('./api/launchpad.js');
+
+app.get('/api/nsr', cors(), function(req, res) {
+        launchpadAPI['nsr'].get(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.get('/api/nsr/:id', cors(), function(req, res) {
+        launchpadAPI['nsr'].get(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.delete('/api/nsr/:id', cors(), function(req, res) {
+        launchpadAPI['nsr'].delete(req).then(function(response) {
+            utils.sendSuccessResponse(response, res);
+        }, function(error) {
+            sendErrorResponse(error, res);
+        });
+    });
+    app.post('/api/nsr', cors(), function(req, res) {
+        launchpadAPI['nsr'].create(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            console.log(error)
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.get('/api/nsr/:nsr_id/vnfr', cors(), function(req, res) {
+        launchpadAPI['vnfr'].get(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        }).catch(function(error) {
+            console.log(error)
+        });
+    });
+    app.get('/api/nsr/:nsr_id/vld', cors(), function(req, res) {
+        launchpadAPI['nsr'].nsd.vld.get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/api/nsr/:nsr_id/vld/:vld_id', cors(), function(req, res) {
+        launchpadAPI['nsr'].nsd.vld.get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.delete('/api/nsr/:nsr_id/vld/:vld_id', function(req, res) {
+        launchpadAPI['nsr'].nsd.vld.delete(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.post('/api/nsr/:nsr_id/vld', cors(), function(req, res) {
+        launchpadAPI['nsr'].nsd.vld.create(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.put('/api/nsr/:nsr_id/vld/:vld_id', cors(), function(req, res) {
+        launchpadAPI['nsr'].nsd.vld.update(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/api/vlr', cors(), function(req, res) {
+        launchpadAPI['vlr'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/api/vlr/:id', cors(), function(req, res) {
+        launchpadAPI['vlr'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+
+    app.put('/api/nsr/:id/admin-status', cors(), function(req, res) {
+        launchpadAPI['nsr'].setStatus(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.post('/api/nsr/:id/:scaling_group_id/instance', cors(), function(req, res) {
+        launchpadAPI['nsr'].createScalingGroupInstance(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            console.log(error)
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.delete('/api/nsr/:id/:scaling_group_id/instance/:scaling_instance_id', cors(), function(req, res) {
+        launchpadAPI['nsr'].deleteScalingGroupInstance(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            console.log(error)
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/api/vnfr', cors(), function(req, res) {
+        launchpadAPI['vnfr'].get(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.get('/api/vnfr/:id', cors(), function(req, res) {
+        launchpadAPI['vnfr'].get(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.get('/api/vnfr/:vnfr_id/:vdur_id', cors(), function(req, res) {
+        launchpadAPI['vdur'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        })
+    });
+    app.get('/api/catalog', cors(), function(req, res) {
+        launchpadAPI['catalog'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            if(!error || !error.statusCode) {
+                error = {
+                    statusCode: 500,
+                    message: 'unknown error with Catalog.get'
+                }
+            }
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    //TODO refactor this query
+    app.get('/api/decorated-catalog', cors(), function(req, res) {
+        launchpadAPI['catalog'].get(req).then(function(data) {
+            var returnData = launchpadAPI['catalog'].decorateNsdCatalogWithPlacementGroups(data)
+            utils.sendSuccessResponse(returnData, res);
+        }, function(error) {
+            if(!error || !error.statusCode) {
+                error = {
+                    statusCode: 500,
+                    message: 'unknown error with Catalog.get'
+                }
+            }
+            utils.sendErrorResponse(error, res);
+        });
+    });
+
+    //TODO refactor this query
+    app.post('/api/vnfd', cors(), function(req, res) {
+        launchpadAPI['catalog'].getVNFD(req).then(function(data) {
+            res.send(data);
+        }).catch(function(error) {
+            console.log(error)
+        });
+    });
+    app.get('/api/nsd/:nsd_id/input-param', cors(), function(req, res) {
+        launchpadAPI['nsd'].getInputParams(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.post('/api/exec-ns-service-primitive', cors(), function(req, res) {
+        launchpadAPI['rpc'].executeNSServicePrimitive(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/api/get-ns-service-primitives', cors(), function(req, res) {
+        launchpadAPI['rpc'].getNSServicePrimitiveValues(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.delete('/api/catalog/:catalogType/:id', cors(), function(req, res) {
+        launchpadAPI['catalog'].delete(req).then(function(response) {
+            res.status(response.statusCode);
+            res.send({});
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.post('/api/catalog/:catalogType', cors(), function(req, res) {
+        launchpadAPI['catalog'].create(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.put('/api/catalog/:catalogType/:id', cors(), function(req, res) {
+        launchpadAPI['catalog'].update(req).then(function(data) {
+            res.send(data);
+        }, function(error) {
+            res.status(error.statusCode);
+            res.send(error.errorMessage);
+        });
+    });
+    app.get('/api/nsr/:id/compute-topology', cors(), function(req, res) {
+        launchpadAPI['computeTopology'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        })
+    });
+    app.get('/api/network-topology', cors(), function(req, res) {
+        launchpadAPI['networkTopology'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        })
+    });
+    app.get('/api/cloud-account', cors(), function(req, res) {
+        launchpadAPI['cloud_account'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        })
+    });
+    app.get('/api/config', cors(), function(req, res) {
+        launchpadAPI['config'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        })
+    });
+    app.get('/api/config-agent-account', cors(), function(req, res) {
+        launchpadAPI['config-agent-account'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.get('/api/config-agent-account/:id', cors(), function(req, res) {
+        launchpadAPI['config-agent-account'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.post('/api/config-agent-account', cors(), function(req, res) {
+        launchpadAPI['config-agent-account'].create(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.put('/api/config-agent-account/:id', cors(), function(req, res) {
+        launchpadAPI['config-agent-account'].update(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.delete('/api/config-agent-account/:id', cors(), function(req, res) {
+        launchpadAPI['config-agent-account'].delete(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    //DataCenters
+    app.get('/api/data-centers', cors(), function(req, res) {
+        launchpadAPI['data_centers'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });//DataCenters
+    app.get('/api/ssh-key', cors(), function(req, res) {
+        launchpadAPI['SSHkey'].get(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.put('/api/ssh-key', cors(), function(req, res) {
+        launchpadAPI['SSHkey'].put(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.post('/api/ssh-key', cors(), function(req, res) {
+        launchpadAPI['SSHkey'].post(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+    app.delete('/api/ssh-key/:name', cors(), function(req, res) {
+        launchpadAPI['SSHkey'].delete(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    });
+
+    utils.passThroughConstructor(app);
+
+module.exports = app;
diff --git a/skyquake/plugins/launchpad/scripts/build.sh b/skyquake/plugins/launchpad/scripts/build.sh
new file mode 100755 (executable)
index 0000000..611fcc8
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=launchpad
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/launchpad/scripts/install.sh b/skyquake/plugins/launchpad/scripts/install.sh
new file mode 100755 (executable)
index 0000000..79fb26b
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=launchpad
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
diff --git a/skyquake/plugins/launchpad/server.js b/skyquake/plugins/launchpad/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/launchpad/src/alt.js b/skyquake/plugins/launchpad/src/alt.js
new file mode 100644 (file)
index 0000000..4c3b0da
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+//Reference to skyquake alt context.
+//Local can be replaced with a separate alt context local to the plugin only.
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance.js';
+export default Alt;
diff --git a/skyquake/plugins/launchpad/src/assets/images/default-catalog-icon.svg b/skyquake/plugins/launchpad/src/assets/images/default-catalog-icon.svg
new file mode 100644 (file)
index 0000000..80fb5ef
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+       Copyright 2016 RIFT.IO Inc
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90.8 78.5"><path class="st0" d="M70.8 58.2c-0.7 0-1.4 0.1-2 0.3L51.5 42.7c0.7-1.1 1.2-2.4 1.2-3.8 0-1.4-0.4-2.7-1.2-3.8l15.1-13.9c1.1 0.9 2.6 1.5 4.2 1.5 3.7 0 6.7-3 6.7-6.6 0-3.7-3-6.6-6.7-6.6 -3.7 0-6.7 3-6.7 6.6 0 1.4 0.4 2.7 1.2 3.8L50.2 33.8c-1.1-0.9-2.6-1.5-4.2-1.5 -1.6 0-3.1 0.6-4.2 1.5L26.7 19.9c0.7-1.1 1.2-2.4 1.2-3.8 0-3.7-3-6.6-6.7-6.6 -3.7 0-6.7 3-6.7 6.6 0 3.3 2.5 6.1 5.7 6.6v35.6c-3.2 0.5-5.7 3.2-5.7 6.6 0 3.7 3 6.6 6.7 6.6 3.1 0 5.8-2.2 6.5-5.1h36.7c0.7 2.9 3.3 5.1 6.5 5.1 3.7 0 6.7-3 6.7-6.6C77.5 61.2 74.5 58.2 70.8 58.2zM64.2 64.5H27.8c-0.1-2.1-1.2-4-2.8-5.1l16.7-15.4c1.1 0.9 2.6 1.5 4.2 1.5 1.6 0 3.1-0.6 4.2-1.5L67 59.4C65.3 60.6 64.3 62.4 64.2 64.5zM25.4 21.3l15.1 13.9c-0.7 1.1-1.2 2.4-1.2 3.8 0 1.4 0.4 2.7 1.2 3.8L23.2 58.5c-0.3-0.1-0.7-0.2-1.1-0.2V22.7C23.4 22.5 24.5 22 25.4 21.3z"/></svg>
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/assets/images/default-icon-white.svg b/skyquake/plugins/launchpad/src/assets/images/default-icon-white.svg
new file mode 100644 (file)
index 0000000..c8b5bca
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+       Copyright 2016 RIFT.IO Inc
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="378" height="412" viewBox="0 0 378 412"><title>  default</title><desc>  default</desc><g id="Page-1" style="fill:none;stroke-width:1;stroke:none"><path stroke="white" d="M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z" id="default" fill="white"/></g></svg>
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/assets/images/default-icon.svg b/skyquake/plugins/launchpad/src/assets/images/default-icon.svg
new file mode 100644 (file)
index 0000000..1b28cd6
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+       Copyright 2016 RIFT.IO Inc
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="378" height="412" viewBox="0 0 378 412"><title>  default</title><desc>  default</desc><g id="Page-1" style="fill:none;stroke-width:1;stroke:none"><path d="M188.8 0L0 103 0 311.2 188.8 412 377.7 311.2 377.7 104.1 188.8 0 188.8 0ZM324.6 114.1L188.9 186.5 53.8 112.8 188.8 39.2 324.6 114.1 324.6 114.1ZM34.3 141.3L171.7 216.2 171.7 363.9 34.3 290.7 34.3 141.3 34.3 141.3ZM206 363.9L206 216.3 343.3 143 343.3 290.7 206 363.9 206 363.9ZM274.1 243.9C268.4 244 263.9 248.7 264 254.4 264.1 260.1 268.8 264.6 274.5 264.5 280.2 264.4 284.7 259.7 284.6 254 284.5 248.3 279.8 243.8 274.1 243.9L274.1 243.9ZM93.1 255C93 260.7 97.5 265.4 103.2 265.5 108.9 265.6 113.5 261.1 113.6 255.4 113.8 249.7 109.3 245 103.6 244.9 97.9 244.8 93.2 249.3 93.1 255L93.1 255ZM188.8 98.3C183.2 98.3 178.5 102.9 178.5 108.6 178.5 114.3 183.2 118.9 188.8 118.9 194.5 118.9 199.1 114.3 199.1 108.6 199.1 102.9 194.5 98.3 188.8 98.3L188.8 98.3Z" id="default" fill="#000"/></g></svg>
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/assets/images/header-logo.png b/skyquake/plugins/launchpad/src/assets/images/header-logo.png
new file mode 100644 (file)
index 0000000..09b47c7
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/header-logo.png differ
diff --git a/skyquake/plugins/launchpad/src/assets/images/logos/riftio.png b/skyquake/plugins/launchpad/src/assets/images/logos/riftio.png
new file mode 100644 (file)
index 0000000..2361de6
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/logos/riftio.png differ
diff --git a/skyquake/plugins/launchpad/src/assets/images/osm_header_253x50.png b/skyquake/plugins/launchpad/src/assets/images/osm_header_253x50.png
new file mode 100644 (file)
index 0000000..1005431
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/osm_header_253x50.png differ
diff --git a/skyquake/plugins/launchpad/src/assets/images/osm_header_506x100.png b/skyquake/plugins/launchpad/src/assets/images/osm_header_506x100.png
new file mode 100644 (file)
index 0000000..7ece845
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/osm_header_506x100.png differ
diff --git a/skyquake/plugins/launchpad/src/assets/images/riftio_website_logo_002_03.png b/skyquake/plugins/launchpad/src/assets/images/riftio_website_logo_002_03.png
new file mode 100644 (file)
index 0000000..f187fb6
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/riftio_website_logo_002_03.png differ
diff --git a/skyquake/plugins/launchpad/src/assets/images/sample-catalog.png b/skyquake/plugins/launchpad/src/assets/images/sample-catalog.png
new file mode 100644 (file)
index 0000000..caf4251
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/sample-catalog.png differ
diff --git a/skyquake/plugins/launchpad/src/assets/images/vendor-riftio.png b/skyquake/plugins/launchpad/src/assets/images/vendor-riftio.png
new file mode 100644 (file)
index 0000000..70d23dd
Binary files /dev/null and b/skyquake/plugins/launchpad/src/assets/images/vendor-riftio.png differ
diff --git a/skyquake/plugins/launchpad/src/carousel/ButtonEventListener.js b/skyquake/plugins/launchpad/src/carousel/ButtonEventListener.js
new file mode 100644 (file)
index 0000000..9b6fc13
--- /dev/null
@@ -0,0 +1,207 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+
+
+/**
+ * Event listener Mixins. A vast majority of components are going to expose these events to the user so we're making
+ * a central location to house all of them.
+ */
+var MIXINS = {
+  propTypes: {
+    onClick:       React.PropTypes.func,
+    onMouseUp:     React.PropTypes.func,
+    onMouseDown:   React.PropTypes.func,
+    onMouseOver:   React.PropTypes.func,
+    onMouseEnter:  React.PropTypes.func,
+    onMouseLeave:  React.PropTypes.func,
+    onMouseOut:    React.PropTypes.func,
+
+    onTouchCancel: React.PropTypes.func,
+    onTouchEnd:    React.PropTypes.func,
+    onTouchMove:   React.PropTypes.func,
+    onTouchStart:  React.PropTypes.func,
+
+    onKeyDown:     React.PropTypes.func,
+    onKeyPress:    React.PropTypes.func,
+    onKeyUp:       React.PropTypes.func,
+
+    onFocus:       React.PropTypes.func,
+    onBlur:        React.PropTypes.func
+  },
+
+  /**
+   * A vast majority of these functions just check to see if the event function is defined and then passes the function
+   * both the event and the local props.
+   * @param e
+   */
+  onClick: function(e) {
+    if (Boolean(this.props.onClick) && !this.state.isDisabled && !this.state.isReadOnly) {
+      //this.props.isActive = true;
+      this.props.onClick(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseUp: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive:false});
+      if (Boolean(this.props.onMouseUp)) {
+        this.props.onMouseUp(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseDown: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive:true});
+      if (Boolean(this.props.onMouseDown)) {
+        this.props.onMouseDown(e, this);
+      }
+    }
+  },
+  onMouseOver: function(e) {
+    if (Boolean(this.props.onMouseOver) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onMouseOver(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseEnter: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isHovered:true});
+      if (this.props.onMouseEnter) {
+        this.props.onMouseEnter(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onMouseLeave: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isHovered:false, isActive:false});
+      if (Boolean(this.props.onMouseLeave)) {
+        this.props.onMouseLeave(e, this);
+      }
+    }
+  },
+  onMouseOut: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      if (Boolean(this.props.onMouseOut)) {
+        this.props.onMouseOut(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchCancel: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive: false});
+      if (Boolean(this.props.onTouchCancel)) {
+        this.props.onTouchCancel(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchEnd: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive: false});
+      if (Boolean(this.props.onTouchEnd)) {
+        this.props.onTouchEnd(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchMove: function(e) {
+    if (Boolean(this.props.onTouchMove) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onTouchMove(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onTouchStart: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isActive: true});
+      if (Boolean(this.props.onTouchStart)) {
+        this.props.onTouchStart(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onKeyDown: function(e) {
+    if (Boolean(this.props.onKeyDown) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onKeyDown(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onKeyPress: function(e) {
+    if (Boolean(this.props.onKeyPress) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onKeyPress(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onKeyUp: function(e) {
+    if (Boolean(this.props.onKeyUp) && !this.state.isDisabled && !this.state.isReadOnly) {
+      this.props.onKeyUp(e, this);
+    } else {
+      e.preventDefault();
+    }
+  },
+  onFocus: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isFocused: true});
+      if (Boolean(this.props.onFocus)) {
+        this.props.onFocus(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+  onBlur: function(e) {
+    if (!this.state.isDisabled && !this.state.isReadOnly) {
+      this.setState({isFocused: false});
+      if (Boolean(this.props.onBlur)) {
+        this.props.onBlur(e, this);
+      }
+    } else {
+      e.preventDefault();
+    }
+  },
+
+  /**
+   * Generic clone function that takes an object and returns an independent clone of it.
+   * Needed to give the user a clone of the props instead of the props themselves to prevent direct access to the props.
+   * @param obj
+   * @returns {*}
+   **/
+  clone: function(obj) {
+    if (null == obj || "object" != typeof obj) return obj;
+    var copy = obj.constructor();
+    for (var attr in obj) {
+      if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
+    }
+    return copy;
+  }
+};
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/carousel/carousel-react.js b/skyquake/plugins/launchpad/src/carousel/carousel-react.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/skyquake/plugins/launchpad/src/carousel/carousel-react.jsx b/skyquake/plugins/launchpad/src/carousel/carousel-react.jsx
new file mode 100644 (file)
index 0000000..e3fd003
--- /dev/null
@@ -0,0 +1,141 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+var Slider = require('react-slick');
+//import SkyquakeCarousel from './skyquakeCarousel.jsx';
+//This componenet should not be coupled with launchpad
+
+import button from 'widgets/button/rw.button.js'
+var LaunchpadFleetStore = require('../launchpadFleetStore.js');
+var LaunchpadFleetActions = require('../launchpadFleetActions.js');
+
+require('./carousel.css');
+var SimpleSlider = React.createClass({
+  propTypes: {
+    component_list:           React.PropTypes.array.isRequired,
+    slideno:                  React.PropTypes.number,
+    externalChangeSlide:      React.PropTypes.bool
+  },
+  handleClick: function() {
+    this.setState({});
+  },
+  getDefaultProps: function() {
+    this.externalChangeSlide = false;
+    return {
+      externalChangeSlide: false
+    }
+  },
+  getInitialState: function() {
+    return {
+      }
+
+  },
+  changeSlide: function(data) {
+    if (data.slideChange > 0) {
+      var setSlide = -1;
+      for (var i = 0; i < this.props.component_list.length; i++) {
+        var component = this.props.component_list[i].component;
+        if (Object.prototype.toString.call(component) === "[object Array]") {
+          for (var j = 0; j < component.length; j++) {
+            var subcomponent = component[j];
+            if (subcomponent.props.mp === data.dropdownSlide[0]) {
+              setSlide = i;
+            }
+          }
+        } else {
+            if (component.props.mp === data.dropdownSlide[0]) {
+              setSlide = i;
+            }
+          }
+      }
+      if (setSlide < 0) {
+        return;
+      }
+      this.externalChangeSlide = true;
+      this.setState({slideno: parseFloat(setSlide)});
+    }
+  },
+  componentDidMount: function() {
+    // LaunchpadFleetStore.listen(this.changeSlide);
+  },
+  componentWillUnmount: function() {
+  },
+  shouldComponentUpdate: function(nextProps) {
+
+    return true;
+    // This prevents things in the carousel from updating which makes no sense because we're displaying metrics that need to update
+    // if (nextProps.slideno != this.props.slideno) {
+    //   return true;
+    // }
+    // return false;
+  },
+  componentDidUpdate: function(prevProps, prevState) {
+    if (this.externalChangeSlide > 0) {
+      this.externalChangeSlide = false;
+      // LaunchpadFleetActions.slideNoStateChangeSuccess();
+    }
+  },
+  handleResize: function(e) {
+
+  },
+  render: function () {
+    // var settings = {
+    //   dots: true,
+    //   infinite: false,
+    //   speed: 500,
+    //   slidesToShow: 1,
+    //   slidesToScroll: 1,
+    //   centerMode: true,
+    //   initialSlide: this.props.slideno || 2
+    // };
+    var settings = {
+        dots: true,
+        infinite: false,
+        speed: 500,
+        slidesToShow: 1,
+        slidesToScroll: 1,
+        centerMode: true,
+        changeSlide: this.externalChangeSlide,
+        initialSlide: this.state.slideno || 0
+    }
+    if (this.externalChangeSlide) {
+      settings.initialSlide = this.state.slideno;
+    }
+    setTimeout(function() {
+      window.dispatchEvent(new Event('resize'));
+    }, 0)
+    var list = [];
+    if (this.props.component_list !== undefined) {
+      for (var i = 0; i < this.props.component_list.length; i++) {
+        let title = this.props.component_list[i].title;
+        let displayTitle = title ? 'inherit' : 'none';
+        list.push(<div key={i}  className={"component"}><h2 style={{flex: '0 1 auto', justifyContent: 'center', alignSelf: 'center', display: displayTitle, padding: '0.5rem'}}>{title}</h2><div className="componentWrapper">{this.props.component_list[i].component}</div></div>);
+      }
+    }
+
+    return (
+      <div className={list.length > 1 ? '' : 'hideButtons'}>
+        <Slider {...settings}>
+          {list}
+        </Slider>
+      </div>
+    );
+  }
+});
+module.exports = SimpleSlider;
diff --git a/skyquake/plugins/launchpad/src/carousel/carousel.css b/skyquake/plugins/launchpad/src/carousel/carousel.css
new file mode 100644 (file)
index 0000000..4ab94ae
--- /dev/null
@@ -0,0 +1,90 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@charset "UTF-8";
+/* Slider */
+
+.hideButtons .slick-slider>button {
+  display:none !important;
+}
+.slick-slider { position: relative; padding:0px 0px; display: block; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -ms-touch-action: pan-y; touch-action: pan-y; -webkit-tap-highlight-color: transparent;     margin-right: 10px;}
+
+.slick-list { position: relative; overflow: hidden; display: block; margin: 0; padding: 0; }
+.slick-list:focus { outline: none; }
+.slick-loading .slick-list { background: #000 }
+.slick-list.dragging { cursor: pointer; cursor: hand; }
+
+.slick-slider .slick-track { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); }
+
+.slick-track { position: relative; left: 0; top: 0; display: block; }
+.slick-track:before, .slick-track:after { content: ""; display: table; }
+.slick-track:after { clear: both; }
+.slick-loading .slick-track { visibility: hidden; }
+
+.slick-slide { float: left; height: 100%; min-height: 1px; display: none; }
+[dir="rtl"] .slick-slide { float: right; }
+.slick-slide.slick-active.component{
+      display: flex;
+    justify-content: space-around;
+    align-items: center;
+    /*padding: 0 2.5rem;*/
+
+}
+.slick-slide img { display: block; }
+.slick-slide.slick-loading img { display: none; }
+.slick-slide.dragging img { pointer-events: none; }
+.slick-initialized .slick-slide { display: block; }
+.slick-loading .slick-slide { visibility: hidden; }
+.slick-vertical .slick-slide { display: block; height: auto; border: 1px solid transparent; }
+
+/* Icons */
+/* Arrows */
+.slick-prev, .slick-next { position: absolute; display: block; height: 20px; width: 50px; line-height: 0; font-size: 0; cursor: pointer; background: transparent; color: transparent; top: 50%; margin-top: -30px; padding: 0; border: none; outline: none; box-shadow: none; }
+.slick-prev:hover, .slick-prev:focus, .slick-next:hover, .slick-next:focus { outline: none; background: transparent; color: transparent; }
+.slick-prev:hover:before, .slick-prev:focus:before, .slick-next:hover:before, .slick-next:focus:before { opacity: 1; }
+.slick-prev.slick-disabled:before, .slick-next.slick-disabled:before { opacity: 0.25; }
+
+.slick-prev:before, .slick-next:before { font-family: "slick"; font-size: 70px; font-weight:bold; line-height: 1; color: white; opacity: 0.75; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
+
+.slick-prev { left: 0px; }
+[dir="rtl"] .slick-prev { left: auto; right: 0px; }
+.slick-prev:before { content: "❮"; }
+[dir="rtl"] .slick-prev:before { content: "❯"; }
+
+.slick-next { right: -30px; }
+[dir="rtl"] .slick-next { left: 0px; right: auto; }
+.slick-next:before { content: "❯"; }
+[dir="rtl"] .slick-next:before { content: "❮"; }
+
+/* Dots */
+.slick-slider { margin-bottom: 30px; }
+
+.slick-dots { position: absolute; bottom: -45px; list-style: none; display: block; text-align: center; padding: 0; width: 100%; }
+.slick-dots li { position: relative; display: inline-block; height: 20px; width: 20px; margin: 0 5px; padding: 0; cursor: pointer; }
+.slick-dots li button { border: 0; background: transparent; display: block; height: 20px; width: 20px; outline: none; line-height: 0; font-size: 0; color: transparent; padding: 5px; cursor: pointer; }
+.slick-dots li button:hover, .slick-dots li button:focus { outline: none; }
+.slick-dots li button:hover:before, .slick-dots li button:focus:before { opacity: 1; }
+.slick-dots li button:before { position: absolute; top: 0; left: 0; content: "•"; width: 20px; height: 20px; font-family: "slick"; font-size: 6px; line-height: 20px; text-align: center; color: black; opacity: 0.25; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
+.slick-dots li.slick-active button:before { color: black; opacity: 0.75; }
+
+.slick-slider button {
+      box-shadow: none;
+}
+
+
+/*# sourceMappingURL=slick.css.map */
diff --git a/skyquake/plugins/launchpad/src/carousel/components.js b/skyquake/plugins/launchpad/src/carousel/components.js
new file mode 100644 (file)
index 0000000..6908ac7
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var React = require('react');
+
+
+var exports = {
+  carousel: require('./carousel.js'),
+  React: React
+};
+if (typeof module == 'object') {
+  module.exports = exports;
+}
+if (typeof window.$test == 'object' && typeof window == 'object') {
+  $rw.component = exports;
+} else {
+  window.$test = {
+    component: exports
+  };
+}
diff --git a/skyquake/plugins/launchpad/src/carousel/multicomponent.js b/skyquake/plugins/launchpad/src/carousel/multicomponent.js
new file mode 100644 (file)
index 0000000..788a06f
--- /dev/null
@@ -0,0 +1,61 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var React = require('react');
+var mixin = require('./ButtonEventListener.js')
+/**
+ *  Contains a set of components.  Takes a list of components and renders them in lists.
+ *  It's props values and a brief description below
+ *  component_list: Takes a list of React components.
+ */
+module.exports = React.createClass({
+  displayName: 'Multicomponent',
+  mixins:mixin.MIXINS,
+  propTypes: {
+    component_list:           React.PropTypes.array.isRequired
+  },
+
+  /**
+   * Defines default state.
+   *  component_list: Takes a list of React components.
+   */
+  getInitialState: function() {
+    return {
+      component_list: this.props.component_list
+
+    }
+  },
+
+
+  /**
+   * Renders the multicomponent Component
+   * Returns a list React components
+   * @returns {*}
+   */
+  render: function() {
+    var components = [];
+    for (var i = 0; i < this.props.component_list.length; i++) {
+      components.push(this.props.component_list[i].component);
+    }
+
+    var componentDOM = React.createElement("div", {className:this.props.className}, 
+      components
+    )
+    return componentDOM;
+  }
+});
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/carousel/skyquakeCarousel.jsx b/skyquake/plugins/launchpad/src/carousel/skyquakeCarousel.jsx
new file mode 100644 (file)
index 0000000..14bd5e3
--- /dev/null
@@ -0,0 +1,151 @@
+
+var defaultSlideData = [{"id":1,"group-tag":"Group1-0","units":"packets","name":"ping-request-rx-count","value-type":"INT","http-endpoint-ref":"api/v1/pong/stats","widget-type":"COUNTER","description":"no of ping requests","value-integer":2538459,"json-query-method":"NAMEKEY","vnfr-id":"39b56173-be82-4f87-872a-eaa761b36281","mp-id":"1-39b56173-be82-4f87-872a-eaa761b36281","vnfr-name":"pong_vnfd"},{"id":2,"group-tag":"Group1-0","units":"packets","name":"ping-response-tx-count","value-type":"INT","http-endpoint-ref":"api/v1/pong/stats","widget-type":"COUNTER","description":"no of ping responses","value-integer":2538459,"json-query-method":"NAMEKEY","vnfr-id":"39b56173-be82-4f87-872a-eaa761b36281","mp-id":"2-39b56173-be82-4f87-872a-eaa761b36281","vnfr-name":"pong_vnfd"},{"id":1,"group-tag":"Group1-1","units":"packets","name":"ping-request-tx-count","value-type":"INT","http-endpoint-ref":"api/v1/ping/stats","widget-type":"COUNTER","description":"no of ping requests","value-integer":2538460,"json-query-method":"NAMEKEY","vnfr-id":"9f0c4f07-f5e2-4189-aa25-acee550eb02b","mp-id":"1-9f0c4f07-f5e2-4189-aa25-acee550eb02b","vnfr-name":"ping_vnfd"},{"id":2,"group-tag":"Group1-1","units":"packets","name":"ping-response-rx-count","value-type":"INT","http-endpoint-ref":"api/v1/ping/stats","widget-type":"COUNTER","description":"no of ping responses","value-integer":2538455,"json-query-method":"NAMEKEY","vnfr-id":"9f0c4f07-f5e2-4189-aa25-acee550eb02b","mp-id":"2-9f0c4f07-f5e2-4189-aa25-acee550eb02b","vnfr-name":"ping_vnfd"}];
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+require('./skyquakeCarousel.scss');
+
+export default class SkyquakeCarousel extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.slides = this.constructSlides(props.slides);
+        //current slide number. can eventually be used with initial construct slides function to specify initial slide. construct slides currently defaults to slide 1 as initial.
+        this.state.currentSlide = props.currentSlide;
+        //Ref handles. Index coresponds to slide position. Last slide is overflowed left in dom with an order of 1;
+        this.state.refsArray = this.state.slides.map(function(v, i) {
+            return v.ref
+        });
+    }
+    componentWillReceiveProps(props) {
+        console.log(props);
+        let slides = this.constructSlides(props.slides);
+        console.log('refs', this.refs);
+        this.setState({
+            slides: slides
+        });
+
+    }
+    constructSlides(data){
+        let slides = [];
+        let len = data.length;
+        let classItems = 'slide';
+        return data.map(function(v, i) {
+            let slideOrder = i + 2;
+            let isRef = '';
+            let ref;
+            if (slideOrder > len) {
+                isRef = ' is-ref';
+                slideOrder = 1;
+            }
+            ref = 'slide-' + (i+1);
+            // return (<div key={i} ref={ref} className={classItems + isRef} style={{order: slideOrder}}>{v}</div>);
+            return (<div key={i} className={classItems + isRef} style={{order: slideOrder}}>{v}</div>);
+        });
+    }
+    reorderSlides(activeSlideNo) {
+        let self = this;
+        let newSlideRefs = [];
+        let newSlideRefsLen;
+        let containerNode = ReactDOM.findDOMNode(self.refs['container']);
+        newSlideRefs = reorder(this.state.refsArray, activeSlideNo - 1);
+        newSlideRefsLen = newSlideRefs.length;
+        //updates Dom via ref hanldes to the individual slides.
+        newSlideRefs.map(function(v, i) {
+            let element = ReactDOM.findDOMNode(containerNode.refs[v]);
+            if (newSlideRefsLen > (i + 1)) {
+                element.style.order = i + 2;
+                //class handles. currently no purpose
+                element.classList.remove('is-ref');
+            } else {
+                element.style.order = 1;
+                //class handles. currently no purpose
+                element.classList.add('is-ref');
+            }
+        })
+
+        function reorder(data, index) {
+          return data.slice(index).concat(data.slice(0, index))
+        };
+    }
+    changeSlide(dir, e) {
+        let self = this;
+        let containerNode = ReactDOM.findDOMNode(self.refs['container']);
+        let total_len = this.props.slides.length;
+        switch(dir) {
+            case 'previous': prev.call(this); break;
+            case 'next': next.call(this); break;
+        }
+         containerNode.classList.remove('is-set');
+            setTimeout(function() {
+                containerNode.classList.add('is-set');
+        }, 100)
+        function prev() {
+            let nextSlide;
+            let currentSlide = self.state.currentSlide;
+            containerNode.classList.add('is-reversing');
+            if(currentSlide == 1) {
+               nextSlide = total_len
+            } else {
+                nextSlide = currentSlide - 1;
+            }
+            updateSlide(nextSlide);
+        }
+        function next() {
+            let nextSlide;
+            let currentSlide = self.state.currentSlide;
+            containerNode.classList.remove('is-reversing');
+            if(currentSlide == total_len) {
+               nextSlide = 1
+            } else {
+                nextSlide = currentSlide + 1;
+            }
+            updateSlide(nextSlide);
+
+        }
+        function updateSlide(slide) {
+            self.reorderSlides(slide)
+            self.setState({
+                    currentSlide: slide
+            });
+        }
+    }
+  render() {
+    // console.log('this', this);
+    // console.log('refs', this.refs);
+    // console.log('props',this.props);
+    // console.log('state',this.state);
+    return (
+      <div className="carousel-component">
+        <div>{this.state.currentSlide}</div>
+        <button onClick={this.changeSlide.bind(this, 'previous')}>Prev</button>
+        <button onClick={this.changeSlide.bind(this, 'next')}>Next</button>
+        <div className="carousel-container is-set">
+            {this.state.slides}
+        </div>
+      </div>
+    );
+  }
+}
+
+SkyquakeCarousel.defaultProps = {
+    slides: [],
+    // slides: [(<div className="slide">slide 1</div>),(<div className="slide">slide 2</div>),(<div className="slide">slide 3</div>),(<div className="slide is-ref" ref="last">slide 4</div>)],
+    currentSlide: 1
+}
+
+SkyquakeCarousel.displayName = 'SkyquakeCarousel';
+
+/*
+
+<div className="carousel-container is-set" ref="container">
+            {this.state.slides}
+        </div>
+
+ */
+
+// Uncomment properties you need
+// CarouselComponent.propTypes = {};
+// CarouselComponent.defaultProps = {};
+
diff --git a/skyquake/plugins/launchpad/src/carousel/skyquakeCarousel.scss b/skyquake/plugins/launchpad/src/carousel/skyquakeCarousel.scss
new file mode 100644 (file)
index 0000000..c41d933
--- /dev/null
@@ -0,0 +1,28 @@
+.carousel-component {
+  border: 1px dashed #f00;
+  height:400px;
+  overflow:hidden;
+    .carousel-container {
+        display:flex;
+        position: relative;
+        left: -100%;
+        transform: translateX(100%);
+        &.is-reversing {
+            transform: translateX(-100%);
+        }
+        &.is-set {
+            transform: none;
+            transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
+        }
+        .slide {
+            flex:1 0 100%;
+            order:2;
+            border:1px solid white;
+            width: 100px;
+            height: 100px;
+            &.is-ref {
+                order:1;
+            }
+        }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/carousel/test.html b/skyquake/plugins/launchpad/src/carousel/test.html
new file mode 100644 (file)
index 0000000..1a0c882
--- /dev/null
@@ -0,0 +1,53 @@
+<!-- A test for the button component -->
+<!doctype html>
+<html lang="en" class="viewport">
+<head>
+  <!-- -->
+  <title>RIFT.ware</title>
+  <!-- -->
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="description" content="">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <!-- -->
+<!--   <link href="../../build/core.css" rel="stylesheet" type="text/css"  />
+ -->  <!-- -->
+<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
+  <script src="components.js"></script>
+</head>
+<body class="viewport" style="margin:100px;">
+<h2>Button States</h2>
+    <br/>
+  <!-- Create A Button -->
+  <div id="carousel"></div>
+  <br>
+<!-- -->
+
+  <script>
+    $(document).ready(function() {
+      var React = $rw.component.React;
+
+      /*
+       * Each button this onClick is passed to will run this function when clicked.
+       */
+      var onClick = function (e, comp) {
+        console.log('click');
+      };
+
+      // Renders the normal button.
+      $rw.ui({
+        button: {
+          label: "button",
+          onClick: onClick
+        }
+      }, document.getElementById('carousel'));
+
+    });
+
+
+
+
+          </script>
+</body>
+</html>
diff --git a/skyquake/plugins/launchpad/src/cloud-account.js b/skyquake/plugins/launchpad/src/cloud-account.js
new file mode 100644 (file)
index 0000000..e868573
--- /dev/null
@@ -0,0 +1,315 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var CloudAccountCreateController = function($timeout, $state, $stateParams) {
+  var self = this;
+  var CloudAccountStore = require('../missioncontrol/cloud_account/cloudAccountStore')
+  var CloudAccountActions = require('../missioncontrol/cloud_account/cloudAccountActions')
+  self.CloudAccountStore = CloudAccountStore;
+  self.accountType = [
+    // {
+    //   "name":"AWS",
+    //   "account-type":"aws",
+    // },
+    {
+      "name":"OpenStack",
+      "account-type":"openstack",
+    },{
+      "name":"Cloudsim",
+      "account-type":"cloudsim"
+    },{
+      "name":"OpenMano",
+      "account-type":"openmano"
+    }
+  ];
+  self.params = {
+    "aws": [
+        {
+          label: "Key",
+          ref: 'key'
+        },
+        {
+          label: "Secret",
+          ref: 'secret'
+        },
+        {
+          label: "Availability Zone",
+          ref: 'availability-zone'
+        },
+        {
+          label: "Default Subnet ID",
+          ref: 'default-subnet-id'
+        },
+        {
+          label: "Region",
+          ref: 'region'
+        },
+        {
+          label: "VPC ID",
+          ref: 'vpcid'
+        },
+        {
+          label: "SSH Key",
+          ref: 'ssh-key'
+        }
+      ],
+    "openstack": [
+        {
+          label: "Key",
+          ref: 'key'
+        },
+        {
+          label: "Secret",
+          ref: 'secret'
+        },
+        {
+          label: "Authentication URL",
+          ref: 'auth_url'
+        },
+        {
+          label: "Tenant",
+          ref: 'tenant'
+        },
+        {
+          label: 'Management Network',
+          ref: 'mgmt-network'
+        }
+      ],
+    "openmano": [
+        {
+          label: "Host",
+          ref: 'host'
+        },
+        {
+          label: "Port",
+          ref: 'port'
+        },
+        {
+          label: "Tenant ID",
+          ref: 'tenant-id'
+        }
+      ]
+  }
+  self.cloud = {
+    name: '',
+    'account-type': 'openstack'
+  };
+  self.loadDashboard = function() {
+     $state.go('/launchpad', {management_domain: $stateParams.management_domain});
+  }
+  self.openAbout = function() {
+      $state.go('lp-about', {management_domain: $stateParams.management_domain});
+  }
+  self.openDebug = function() {
+      $state.go('lp-debug', {management_domain: $stateParams.management_domain});
+  }
+  self.create = function() {
+    if (self.cloud.name == "") {
+      CloudAccountActions.validateError("Please give the cloud account a name");
+      return;
+    } else {
+      var type = self.cloud['account-type'];
+      if (typeof(self.params[type]) != 'undefined') {
+        var params = self.params[type];
+        for (var i = 0; i < params.length; i++) {
+          var param = params[i].ref;
+          if (typeof(self.cloud[type]) == 'undefined' || typeof(self.cloud[type][param]) == 'undefined' || self.cloud[type][param] == "") {
+
+            CloudAccountActions.validateError("Please fill all account details");
+            return;
+          }
+        }
+      }
+    }
+    CloudAccountActions.validateReset();
+     CloudAccountStore.create(self.cloud).then(function() {
+      $state.go('/launchpad',{management_domain: $stateParams.management_domain});
+     });
+  }
+  self.cancel = function() {
+    $state.go('/launchpad',{management_domain: $stateParams.management_domain});
+  }
+  self.store = CloudAccountStore;
+  require('../utils/utils.js').isNotAuthenticated(window.location, function() {
+      $state.go('login');
+    });
+};
+
+var CloudAccountEditController = function($timeout, $state, $stateParams) {
+  var self = this;
+  var CloudAccountStore = require('../missioncontrol/cloud_account/cloudAccountStore');
+  self.CloudAccountStore = CloudAccountStore;
+  var cloud_account_name = $stateParams.cloud_account;
+
+  // Mark this is edit
+  self.edit = true;
+
+  self.accountType = [
+    // {
+    //   "name":"AWS",
+    //   "account-type":"aws",
+    // },
+    {
+      "name":"OpenStack",
+      "account-type":"openstack",
+    },{
+      "name":"Cloudsim",
+      "account-type":"cloudsim"
+    },{
+      "name":"OpenMano",
+      "account-type":"openmano"
+    }
+  ];
+  self.params = {
+    "aws": [
+        {
+          label: "Key",
+          ref: 'key'
+        },
+        {
+          label: "Secret",
+          ref: 'secret'
+        },
+        {
+          label: "Availability Zone",
+          ref: 'availability-zone'
+        },
+        {
+          label: "Default Subnet ID",
+          ref: 'default-subnet-id'
+        },
+        {
+          label: "Region",
+          ref: 'region'
+        },
+        {
+          label: "VPC ID",
+          ref: 'vpcid'
+        },
+        {
+          label: "SSH Key",
+          ref: 'ssh-key'
+        }
+      ],
+    "openstack": [
+        {
+          label: "Key",
+          ref: 'key'
+        },
+        {
+          label: "Secret",
+          ref: 'secret'
+        },
+        {
+          label: "Authentication URL",
+          ref: 'auth_url'
+        },
+        {
+          label: "Tenant",
+          ref: 'tenant'
+        },
+        {
+          label: 'Management Network',
+          ref: 'mgmt-network'
+        }
+      ],
+    "openmano": [
+        {
+          label: "Host",
+          ref: 'host'
+        },
+        {
+          label: "Port",
+          ref: 'port'
+        },
+        {
+          label: "Tenant ID",
+          ref: 'tenant'
+        },
+        {
+          label: "Data Center ID",
+          ref: 'datacenter'
+        }
+      ]
+  };
+  self.cloud = {
+    name: ''
+  };
+
+  // Setup listener
+  var listener = function(data) {
+    $timeout(function() {
+      console.log('updating', data);
+      self.cloud.name = data.cloudAccount.name;
+      var accountType = self.cloud['account-type'] = data.cloudAccount['account-type'];
+      if (data.cloudAccount[accountType]) {
+        // There are extra params.
+        // Initialize object
+        self.cloud[accountType] = {};
+        // Iterate over them and assign to proper keys
+        for (var k in data.cloudAccount[accountType]) {
+          self.cloud[accountType][k] = data.cloudAccount[accountType][k];
+        }
+      }
+    });
+  };
+
+  CloudAccountStore.listen(listener);
+  require('../utils/utils.js').isNotAuthenticated(window.location, function() {
+      CloudAccountStore.unlisten(listener);
+      $state.go('login')
+    });
+  // Get the cloud account
+  CloudAccountStore.getCloudAccount($stateParams.cloud_account);
+  self.store = CloudAccountStore;
+  self.update = function() {
+    if (self.cloud.name == "") {
+      console.log('pop')
+      return;
+    }
+     CloudAccountStore.update(self.cloud).then(function() {
+      CloudAccountStore.unlisten(listener);
+      $state.go('/launchpad',{management_domain: $stateParams.management_domain});
+     });
+  };
+  self.loadDashboard = function() {
+     $state.go('/launchpad', {management_domain: $stateParams.management_domain});
+  }
+  self.openAbout = function() {
+      $state.go('lp-about', {management_domain: $stateParams.management_domain});
+  }
+  self.openDebug = function() {
+      $state.go('lp-debug', {management_domain: $stateParams.management_domain});
+  }
+  self.delete = function() {
+    console.log('Deleting cloud account', cloud_account_name);
+    CloudAccountStore.delete(cloud_account_name).then(function() {
+      CloudAccountStore.unlisten(listener);
+      $state.go('/launchpad',{management_domain: $stateParams.management_domain});
+    });
+  };
+  self.cancel = function() {
+    CloudAccountStore.unlisten(listener);
+   $state.go('/launchpad',{management_domain: $stateParams.management_domain});
+  }
+};
+
+module.exports = {
+  CloudAccountCreateController: CloudAccountCreateController,
+  CloudAccountEditController: CloudAccountEditController
+};
diff --git a/skyquake/plugins/launchpad/src/createActions.js b/skyquake/plugins/launchpad/src/createActions.js
new file mode 100644 (file)
index 0000000..dc46745
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var alt = require('../core/alt');
+module.exports = alt.generateActions(
+                                       'getNetworkServicesSuccess',
+                                       'getNetworkServicesError',
+                                       'createEnvironmentSuccess',
+                                       'createEnvironmentError',
+                                       'getPoolsSuccess',
+                                       'getPoolsError',
+                                       'getSlaParamsSuccess',
+                                       'getSlaParamsError',
+                                       'validateError',
+                                       'validateReset'
+                                       );
diff --git a/skyquake/plugins/launchpad/src/createSource.js b/skyquake/plugins/launchpad/src/createSource.js
new file mode 100644 (file)
index 0000000..d9271d6
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var alt = require('./alt');
+var Utils = require('utils/utils.js');
+var API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+var NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+var createActions = require('./createActions.js');
+import $ from 'jquery';
+
+module.exports = {
+  getNetworkServices: function() {
+    return {
+      remote: function() {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: '//' + window.location.hostname + ':' + NODE_PORT + '/api/launchpad/network-service?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          })
+        })
+      },
+      success: createActions.getNetworkServicesSuccess,
+      error: createActions.getNetworkServicesError
+    }
+  },
+  createEnvironment: function() {
+    return {
+      remote: function(state, environment) {
+        return $.ajax({
+          url: '//' + window.location.hostname + ':' + NODE_PORT + '/api/launchpad/environment?api_server=' + API_SERVER,
+          type: 'POST',
+          beforeSend: Utils.addAuthorizationStub,
+          dataType: 'json',
+          data: JSON.stringify(environment),
+          contentType: 'application/json',
+          accept: 'application/json'
+        })
+
+      },
+      success: createActions.createEnvironmentSuccess,
+      error: createActions.createEnvironmentsError
+    }
+  },
+  getPools: function() {
+    return {
+      remote: function() {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: '//' + window.location.hostname + ':' + NODE_PORT + '/api/launchpad/pools?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          })
+        })
+      },
+      success: createActions.getPoolsSuccess,
+      error: createActions.getPoolsError
+    }
+  },
+  getSlaParams: function() {
+    return {
+      remote: function() {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: '//' + window.location.hostname + ':' + NODE_PORT + '/api/launchpad/sla-params?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          })
+        })
+      },
+      success: createActions.getSlaParamsSuccess,
+      error: createActions.getSlaParamsError
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/createStore.js b/skyquake/plugins/launchpad/src/createStore.js
new file mode 100644 (file)
index 0000000..517c70c
--- /dev/null
@@ -0,0 +1,58 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var alt = require('../core/alt');
+function CreateFleet () {
+  this.exportAsync(require('./createSource.js'));
+  this.bindActions(require('./createActions.js'));
+  this.nsd = [];
+  this.vnfd = [];
+  this.pnfd = [];
+  validateErrorEvent = false;
+  validateErrorMsg = "";
+};
+
+CreateFleet.prototype.getNetworkServicesSuccess = function(data) {
+  this.setState({
+    networkServices: data
+  })
+};
+CreateFleet.prototype.getSlaParamsSuccess = function(data) {
+  this.setState({
+    slaParams: data
+  })
+};
+CreateFleet.prototype.getPoolsSuccess = function(data) {
+  this.setState({
+    pools: data
+  })
+};
+CreateFleet.prototype.validateError = function(msg) {
+  this.setState({
+    validateErrorEvent: true,
+    validateErrorMsg: msg
+  });
+};
+CreateFleet.prototype.validateReset = function() {
+  this.setState({
+    validateErrorEvent: false
+  });
+};
+
+module.exports = alt.createStore(CreateFleet);
+
diff --git a/skyquake/plugins/launchpad/src/instantiate/catalogBrowser.jsx b/skyquake/plugins/launchpad/src/instantiate/catalogBrowser.jsx
new file mode 100644 (file)
index 0000000..cd3af17
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React, {Component} from 'react';
+class CatalogBrowser extends Component {
+    render() {
+        return <div />
+    }
+}
+
+export default CatalogBrowser
diff --git a/skyquake/plugins/launchpad/src/instantiate/catalogCard.jsx b/skyquake/plugins/launchpad/src/instantiate/catalogCard.jsx
new file mode 100644 (file)
index 0000000..d44bd2e
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import './catalogCard.scss';
+import 'style/common.scss';
+import React, {Component} from 'react';
+export default class CatalogCard extends Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.isExpanded = false;
+    }
+    hideIt = (e) => {
+        document.querySelector('body').removeEventListener('click', this.hideIt);
+        if(e.target.parentElement.classList.contains('CatalogCard-info--expanded') || e.target.classList.contains('CatalogCard-info--expanded')) {
+            e.stopPropagation();
+        }
+        this.setState({
+            isExpanded: false
+        });
+    }
+    handleImageError = (e) => {
+        console.log('Bad logo path, using default');
+        e.target.src = require('style/img/catalog-default.svg');
+    }
+    toggleDetailsDisplay = (e) => {
+        let self = this;
+        let isExpanded = this.state.isExpanded;
+        e.stopPropagation();
+        if(!isExpanded) {
+            document.querySelector('body').addEventListener('click', this.hideIt);
+             self.setState({
+                isExpanded: true
+            });
+        }
+    }
+    detailsHTML = (descriptor) => {
+        let self = this;
+        return (
+            <dd className="details">
+                <div className="details-section">
+                    <div className="details-section-title">
+                        VNFDs
+                    </div>
+                    {
+                        (
+                         descriptor['constituent-vnfd'] &&
+                         (descriptor['constituent-vnfd'].length > 0)
+                         ) ?
+                            descriptor['constituent-vnfd'] && descriptor['constituent-vnfd'].map(function(v,i) {
+                                return (
+                                    <div key={i} className="details-section-item">
+                                        <img
+                                            onError={self.handleImageError}
+                                            src={cleanDataURI(descriptor.logo, 'vnfd', descriptor.id)}
+                                        />
+                                        {v['name']}
+                                    </div>
+                                    )
+                            })
+                            : 'None'
+                    }
+                </div>
+                <div className="details-section">
+                    <div className="details-section-title">
+                        VLDs
+                    </div>
+                    {
+                        (
+                         descriptor['vld'] &&
+                         (descriptor['vld'].length > 0)
+                         ) ?
+                            descriptor['vld'] && descriptor['vld'].map(function(v,i) {
+                                return (
+                                    <div key={i} className="details-section-item">
+                                        {v['short-name']}
+                                    </div>
+                                    )
+                            })
+                            : 'None'
+                    }
+                </div>
+                <div className="details-section">
+                    <div className="details-section-title">
+                        VNFFGDs
+                    </div>
+                    {
+                        (
+                         descriptor['vnffgd'] &&
+                         (descriptor['vnffgd'].length > 0)
+                         ) ?
+                            descriptor['vnffgd'] && descriptor['vnffgd'].map(function(v,i) {
+                                return (
+                                    <div key={i} className="details-section-item">
+                                        {v['short-name']}
+                                    </div>
+                                    )
+                            })
+                            : 'None'
+                    }
+                </div>
+            </dd>
+        );
+    }
+    componentWillUnmount() {
+        document.querySelector('body').removeEventListener('click', this.hideIt);
+    }
+    render() {
+        let {className, descriptor, isActive, isOpen, onCloseCard,...props} = this.props;
+        let openTool = isOpen ? null : <span className="oi CatalogCard-button" data-glyph={isActive ? "circle-x" : "arrow-circle-right"} onClick={isActive ?  onCloseCard : props.onPreviewDescriptor(descriptor)}></span>
+        className = "CatalogCard " + buildClass(this.props);
+        return (
+            <div className={className} onClick={props.onClick} onDoubleClick={props.onDoubleClick}>
+                <img className="CatalogCard-thumbnail"  onError={this.handleImageError} src={cleanDataURI(descriptor.logo, 'nsd', descriptor.id)} />
+                <div className="CatalogCard-body">
+                    <div className="CatalogCard-header">
+                        <div className="CatalogCard-name">
+                            {descriptor.name}
+                        </div>
+                        <div className="CatalogCard-subtitle">
+                            {descriptor['short-name']}
+                        </div>
+                        <div className="CatalogCard-subtitle">
+                            {descriptor['vendor']} / {descriptor['version']}
+                        </div>
+                    </div>
+                    <div className="CatalogCard-description">
+                        {descriptor['description']}
+                    </div>
+                    <dl className={"CatalogCard-info " + (this.state.isExpanded ? "CatalogCard-info--expanded" : "")} onClick={this.toggleDetailsDisplay}>
+                        <dt>VNFDs:</dt>
+                        <dd>{descriptor['constituent-vnfd'] && descriptor['constituent-vnfd'].length || 0}</dd>
+                        <dt>VLDs:</dt>
+                        <dd>{descriptor['vld'] && descriptor['vld'].length || 0}</dd>
+                        <dt>VNFFGDs:</dt>
+                        <dd>{descriptor['vnffgd'] && descriptor['vnffgd'].length || 0}</dd>
+                        <dd className="arrow-black--down"></dd>
+                        {this.detailsHTML(descriptor)}
+                    </dl>
+                </div>
+                {openTool}
+            </div>
+        )
+    }
+}
+CatalogCard.defaultProps = {
+    className: null,
+    descriptor: {}
+}
+
+function buildClass(props) {
+    let className = '';
+    if(props.isSelected) {
+        className += ' CatalogCard-is-selected';
+    }
+    if(props.isActive) {
+        className += ' CatalogCard-is-active';
+    }
+    return className;
+}
+
+function cardHandler(element) {
+    this.handleEvent = function(e) {
+        ''
+    }
+}
+
+function cleanDataURI(imageString, type, id) {
+        if (/\bbase64\b/g.test(imageString)) {
+            return imageString;
+        } else if (/<\?xml\b/g.test(imageString)) {
+            const imgStr = imageString.substring(imageString.indexOf('<?xml'));
+            return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr);
+        } else if (/\.(svg|png|gif|jpeg|jpg)$/.test(imageString)) {
+            return '/composer/assets/logos/' + type + '/' + id + '/' + imageString;
+            // return require('../images/logos/' + imageString);
+        }
+        if(type == 'nsd' || type == 'vnfd') {
+            return require('style/img/catalog-'+type+'-default.svg');
+        }
+        return require('style/img/catalog-default.svg');
+    }
diff --git a/skyquake/plugins/launchpad/src/instantiate/catalogCard.scss b/skyquake/plugins/launchpad/src/instantiate/catalogCard.scss
new file mode 100644 (file)
index 0000000..688be81
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+
+.CatalogCard {
+    position:relative;
+    display:-ms-flexbox;
+    display:flex;
+    -ms-flex-align: start;
+        align-items: flex-start;
+    background-color: #fff;
+    margin: 0rem 1rem;
+    margin-bottom: 1rem;
+    min-width: 350px;
+    max-width: 350px;
+    height:125px;
+    border-radius: 8px;
+    padding:0.5rem;
+    cursor:pointer;
+    &-thumbnail {
+        margin-right: 0.5rem;
+            max-width: 2rem;
+    max-height: 2rem;
+    }
+    &-button {
+        font-size:1.25rem;
+        cursor:pointer;
+    }
+    &-body {
+        -ms-flex:1;
+            flex:1;
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-direction:column;
+            flex-direction:column;
+        -ms-flex-pack:justify;
+            justify-content:space-between;
+        height: 100%;
+        font-size:0.75rem;
+    }
+    &-name {
+        font-size:1rem;
+    }
+    &-info{
+        position:relative;
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-align: center;
+            align-items: center;
+        border-bottom: 1px solid $dark-gray;
+        width:-webkit-fit-content;
+        width:-moz-fit-content;
+        width:fit-content;
+        cursor:pointer;
+        dd {
+            margin:0 1rem 0 0.5rem;
+            &:nth-last-child(2) {
+                margin-right:0;
+            }
+        }
+        .details {
+            display:none;
+            top: 1.125rem;
+            left: 0;
+            width:100%;
+            z-index:2;
+            background:white;
+            border:1px solid $dark-gray;
+            padding:0.5rem;
+            padding-top: 1rem;
+            &-section {
+                margin-bottom:0.75rem;
+                color:black;
+
+                &-title{
+                    margin-bottom:0.5rem;
+                    font-weight:bold;
+                    color:black;
+                }
+                &-item{
+                    display:-ms-flexbox;
+                    display:flex;
+                    -ms-flex-align: center;
+                    align-items: center;
+                    margin:0.25rem 0rem;
+                    color:black;
+
+                    img {
+                        width:1.5rem;
+                        height:1.5rem;
+                        margin-right:0.25rem;
+                    }
+                }
+            }
+        }
+        &.CatalogCard-info--expanded {
+            .details{
+                position:absolute;
+                display:-ms-flexbox;
+                display:flex;
+                -ms-flex-direction:column;
+                    flex-direction:column;
+            }
+        }
+    }
+    &-is-selected {
+        outline: 2px dashed $brand-blue;
+        outline-offset: 2px;
+        cursor: pointer;
+    }
+    &:hover {
+        background-color: #7e9bc1;
+        /* background-color: $brand-blue-dark;*/
+        color:white;
+
+        .CatalogCard-info {
+            border-bottom: 1px solid white;
+        }
+
+    }
+    &-is-active {
+        /* &:before {*/
+        /*     content: '';*/
+        /*     position:absolute;*/
+        /*     height:125px;*/
+        /*     width:10px;*/
+        /*     left:-10px;*/
+        /*     background-color:#7e9bc1;*/
+        /*     /* background-color:$brand-blue-dark;*/
+        /* }*/
+    }
+    &-name {
+        font-weight:bold;
+    }
+    &-subtitle {
+        margin-top:0.25rem;
+    }
+    &-description {
+        margin:0.5rem 0;
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/catalogDescriptorRaw.jsx b/skyquake/plugins/launchpad/src/instantiate/catalogDescriptorRaw.jsx
new file mode 100644 (file)
index 0000000..afce7e4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import './catalogCard.scss';
+import 'style/common.scss';
+import JSONViewer from 'widgets/JSONViewer/JSONViewer'
+import React, {Component} from 'react';
+export default class CatalogDescriptorRaw extends Component {
+    constructor(props) {
+        super(props)
+    }
+    render() {
+        return <JSONViewer json={this.props.descriptor} />
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateActions.js b/skyquake/plugins/launchpad/src/instantiate/instantiateActions.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateDashboard.jsx b/skyquake/plugins/launchpad/src/instantiate/instantiateDashboard.jsx
new file mode 100644 (file)
index 0000000..607576b
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import AppHeader from 'widgets/header/header.jsx';
+import InstantiateStore from './instantiateStore.js';
+import NetworkServiceActions from './launchNetworkServiceActions.js';
+import InstantiateSelectDescriptorPanel from './instantiateSelectDescriptorPanel.jsx';
+import CatalogDescriptorRaw from './catalogDescriptorRaw.jsx'
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import {Panel, PanelWrapper} from 'widgets/panel/panel';
+import Button from 'widgets/button/rw.button.js'
+import 'style/layout.scss';
+import './instantiateDashboard.scss';
+
+class InstantiateDashboard extends React.Component {
+    constructor(props) {
+        super(props);
+        this.Store = this.props.flux.stores.hasOwnProperty('InstantiateStore') ? this.props.flux.stores.InstantiateStore : this.props.flux.createStore(InstantiateStore                );
+        this.state = this.Store.getState();
+    }
+    componentDidMount() {
+        let self = this;
+        let asyncOperations = []
+        asyncOperations.push(this.Store.getCatalog());
+        asyncOperations.push(this.Store.getCloudAccount(function() {
+          asyncOperations.push(self.Store.getDataCenters());
+          asyncOperations.push(self.Store.getSshKey());
+          asyncOperations.push(self.Store.getConfigAgent());
+        }));
+        Promise.all(asyncOperations).then(function(resolve, reject) {
+            if(self.props.params.nsd) {
+                self.Store.descriptorSelected(self.state.nsdDict[self.props.params.nsd]);
+            }
+        })
+
+    }
+    componentWillMount() {
+        this.Store.listen(this.updateState);
+    }
+    componentWillUnmount() {
+        this.Store.unlisten(this.updateState);
+    }
+    handleCancel = (e) => {
+        e.preventDefault();
+        this.props.router.push({pathname:''});
+    }
+    handleBack = (e) => {
+        e.preventDefault();
+        this.props.router.goBack();
+    }
+    handleSave = (launch, e) => {
+        let self = this;
+        e.preventDefault();
+        if (this.state.name == "") {
+            self.props.actions.showNotification('Please name the network service');
+          return;
+        }
+        if (!this.state.name.match(/^[a-zA-Z0-9_]*$/g)) {
+          self.props.actions.showNotification('Spaces and special characters except underscores are not supported in the network service name at this time');
+          return;
+        }
+        if (this.isOpenMano() && (this.state.dataCenterID == "" || !this.state.dataCenterID)) {
+             self.props.actions.showNotification("Please enter the Data Center ID");
+          return;
+        }
+        // LaunchNetworkServiceStore.resetView();
+        this.Store.saveNetworkServiceRecord(this.state.name, launch);
+    }
+    isSelectPage = () => {
+        //If an NSD id is present in the route then this evalauates to false;
+        return !this.props.location.pathname.split('/')[2];
+    }
+    isOpenMano = () => {
+        return this.state.selectedCloudAccount['account-type'] == 'openmano';
+    }
+    openDescriptor = (descriptor) => {
+        let NSD = descriptor;
+        if(descriptor.hasOwnProperty('target')) {
+            NSD = this.state.selectedNSD;
+        }
+        this.Store.descriptorSelected(NSD);
+        this.props.router.push({pathname:'/instantiate/' + NSD.id});
+    }
+    updateState = (state) => {
+        this.setState(state);
+    }
+    render() {
+        let self = this;
+        let html;
+        let selectedNSDid = self.state.selectedNSDid;
+        let isPreviewing = self.state.isPreviewing;
+        let descriptorPreview = (
+            <Panel title={(self.state.selectedNSD['short-name'] || self.state.selectedNSD.name ) + ' Descriptor Preview'} className="CatalogDescriptorPreview">
+            <span className="oi CatalogDescriptorPreview-button" data-glyph={"circle-x"} onClick={self.Store.deselectDescriptor}></span>
+                <CatalogDescriptorRaw descriptor={self.state.selectedNSD} />
+            </Panel>);
+        html = this.props.children ?
+                React.cloneElement(this.props.children, {store: self.Store, nsd: self.state.nsd[0], ...self.Store, ...self.state})
+                : (
+                    <PanelWrapper>
+                        <InstantiateSelectDescriptorPanel
+                            catalog={self.state.nsd[0]}
+                            onSelectDescriptor={self.Store.descriptorSelected}
+                            onPreviewDescriptor={self.Store.previewDescriptor}
+                            selectedDescriptorID={selectedNSDid}
+                            isPreviewing={isPreviewing}
+                            closeCard={self.Store.deselectDescriptor}
+                            openDescriptor={this.openDescriptor}
+                        />
+                        {isPreviewing ? descriptorPreview : null}
+                    </PanelWrapper>
+                )
+
+        return (
+            <div className="InstantiateDashboard">
+                {html}
+                <div className="ButtonGroup">
+
+                    <Button label="Cancel" onClick={this.handleCancel}/>
+                    {this.isSelectPage() ?
+                        <Button label="Next" isLoading={this.state.isSaving} onClick={this.state.selectedNSD && self.openDescriptor} className="dark"  type="submit"/>
+                        : <div>
+                            <Button label="Back" onClick={this.handleBack}/>
+                            <Button label="Launch" isLoading={this.state.isSaving} onClick={self.handleSave.bind(self, true)} className="dark"  type="submit"/>
+                        </div>
+                    }
+                </div>
+            </div>
+        );
+    }
+}
+InstantiateDashboard.contextTypes = {
+    router: React.PropTypes.object
+};
+export default SkyquakeComponent(InstantiateDashboard);
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateDashboard.scss b/skyquake/plugins/launchpad/src/instantiate/instantiateDashboard.scss
new file mode 100644 (file)
index 0000000..b9ce7fb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.application.instantiate {
+    /* overflow:visible !important;*/
+    height:100%;
+}
+.CatalogDescriptorPreview {
+       -ms-flex:0 1 40%;
+           flex:0 1 40%;
+           &-button {
+            position:absolute;
+            top:0;
+            right:0;
+            color:black;
+            margin: 1rem;
+            cursor:pointer;
+           }
+}
+.InstantiateDashboard {
+    display:-ms-flexbox;
+    display:flex;
+    -ms-flex-direction:column;
+        flex-direction:column;
+    -ms-flex-align:center;
+        align-items:center;
+
+    .ButtonGroup {
+        display:-ms-flexbox;
+        display:flex;
+        margin:1rem;
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateDescriptorPanel.jsx b/skyquake/plugins/launchpad/src/instantiate/instantiateDescriptorPanel.jsx
new file mode 100644 (file)
index 0000000..039478e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React, {Component} from 'react';
+import Panel from 'widgets/panel/panel';
+import CatalogCard from './catalogCard.jsx'
+import CatalogDescriptorRaw from './catalogDescriptorRaw.jsx'
+
+export default class InstantiateDescriptorPanel extends Component {
+    constructor(props) {
+        super(props)
+    }
+    render() {
+        return (
+            <Panel title="Descriptor">
+                <CatalogCard descriptor={this.props.descriptor} isOpen={true} />
+                <CatalogDescriptorRaw descriptor={this.props.descriptor} />
+            </Panel>
+        )
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateInputParams.jsx b/skyquake/plugins/launchpad/src/instantiate/instantiateInputParams.jsx
new file mode 100644 (file)
index 0000000..00397ed
--- /dev/null
@@ -0,0 +1,603 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React, {Component} from 'react';
+import ReactDOM from 'react-dom';
+import SelectOption from 'widgets/form_controls/selectOption.jsx';
+import imgAdd from '../../node_modules/open-iconic/svg/plus.svg'
+import imgRemove from '../../node_modules/open-iconic/svg/trash.svg'
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import './instantiateInputParams.scss';
+
+export default class InstantiateInputParams extends Component {
+  constructor(props) {
+    super(props);
+  }
+  nsConfigHTML = (props) => {
+    return (
+      <div className="configure-nsd_section">
+        <div className="inputControls">
+            <TextInput label="Instance Name" type="text" pattern="^[a-zA-Z0-9_]*$" style={{textAlign:'left'}} onChange={props.updateName} value={props.name}/>
+          <label>Select VIM Account
+            <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} onChange={props.nsFn.updateSelectedCloudAccount} />
+          </label>
+          {
+            isOpenMano(props.selectedCloudAccount) ? this.dataCentersHTML(props.dataCenters[selectedCloudAccount.name], props.nsFn.updateSelectedDataCenter) : null
+          }
+        </div>
+      </div>
+    )
+  }
+  vnfCloudAccountsHTML = (props) => {
+    let nsd = props.nsd;
+    let dataCenters = props.dataCenters;
+    return (
+      <div className="configure-nsd_section">
+        <h3 className="launchpadCard_title">NS/VNF ACCOUNT PLACEMENTS</h3>
+        {
+
+            //selectedNSDid
+              nsd['constituent-vnfd'] && nsd['constituent-vnfd'].map(function(v, i) {
+                let defaultValue = false;
+                if(props.vnfdCloudAccounts && props.vnfdCloudAccounts.hasOwnProperty(v['member-vnf-index'])) {
+                  defaultValue = props.vnfdCloudAccounts[v['member-vnf-index']]
+                }
+                return (
+                    <div className="inputControls" key={i}>
+                    <h4 className="inputControls-title">VNFD: {v.name}</h4>
+                      <label>Select VIM Account
+                        <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} initial={true} onChange={props.vnfFn.updateSelectedCloudAccount.bind(v['member-vnf-index'])} defaultValue={defaultValue} />
+                      </label>
+                      {
+                        isOpenMano(defaultValue) ? dataCentersHTML(dataCenters[defaultValue.account.name], props.vnfFn.updateSelectedDataCenter(v['member-vnf-index'])) : null
+                      }
+                      {
+                        (props.configAgentAccounts && props.configAgentAccounts.length > 0) ?
+                        <label>Select Config Agent Account
+                          <SelectOption options={props.configAgentAccounts && props.configAgentAccounts.map(function(c) {
+                            return {
+                              label: c.name,
+                              value: c.name
+                            }
+                          })} initial={true} onChange={props.vnfFn.updateSelectedConfigAgent(v['member-vnf-index'])} defaultValue={false} />
+                        </label> : null
+                      }
+                    </div>
+                )
+              })
+        }
+      </div>
+    )
+  }
+  inputParametersHTML = (props) => {
+    let inputParameters = props.inputParameters;
+    return inputParameters && inputParameters.map(function(input, i) {
+        return (
+                <div className="configure-nsd_section" key={i}>
+                  <h3 className="launchpadCard_title">Input Parameters</h3>
+                  <div className="inputControls">
+                      <TextInput label={ input.label || input.xpath } type="text" onChange={props.updateInputParam.bind(self, i)} />
+                  </div>
+                </div>
+        )
+      })
+  }
+  nsPlacementGroupsHTML = (props) => {
+    let nsPlacementGroups = props.nsPlacementGroups;
+    let displayPlacementGroups = props.displayPlacementGroups;
+    if (nsPlacementGroups && nsPlacementGroups.length > 0 && displayPlacementGroups) {
+      return (
+        <div className="configure-nsd_section">
+          <h3 className="launchpadCard_title">NS Placement Groups</h3>
+            {
+              nsPlacementGroups.map(function(input, i) {
+                return (
+                  <div  key={i} className="configure-nsd_section-info">
+                    <div className="placementGroup_description">
+                      <div className="placementGroup_description-name">
+                        <strong>{input.name}</strong> contains: {
+                          input['member-vnfd'].map((m,i) => {
+                            let s = m.name;
+                            if(i>0) {
+                              s = ', ' + m.name
+                            };
+                            return s;
+                          })
+                        }
+                      </div>
+                      <div><em>{input.requirement}</em></div>
+                      <div><strong>Strategy:</strong> {input.strategy}</div>
+                    </div>
+                    <label>
+                      <span> Availability Zone <span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span> </span>
+                      <div  style={{display:'none'}}>
+                      <TextInput type="text" onChange={props.nsFn.placementGroupUpdate.bind(self, i, 'availability-zone')} />
+                      <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
+                      </div>
+                    </label>
+                    <label>
+                      <span> Affinity/Anti-affinity Server Group<span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span></span>
+                      <div style={{display:'none'}}>
+                        <TextInput type="text" onChange={props.nsFn.placementGroupUpdate.bind(self, i, 'server-group')} />
+                        <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
+                      </div>
+                    </label>
+                    <div className="host-aggregate">
+                      <label>
+                        <span> Host Aggregates <span onClick={props.nsFn.addHostAggregate.bind(self, i)} className="addInput"  ><img src={imgAdd} />Add</span></span>
+                      {
+                        input['host-aggregate'].length > 0 ?
+                          input['host-aggregate'].map((h,j) => {
+                            let key = h.key || '';
+                            let value = h.value || '';
+                            return (
+
+                                  <div className="input_group" key={j}>
+                                    <TextInput type="text" onChange={props.nsFn.placementGroupUpdate.bind(self, i, j, 'key')} placeholder="KEY" value={key} />
+                                    <TextInput type="text" onChange={props.nsFn.placementGroupUpdate.bind(self, i, j, 'value')} placeholder="VALUE"  value={value} />
+                                    <span onClick={props.nsFn.removeHostAggregate.bind(self, i, j)} className="removeInput"><img src={imgRemove} />Remove</span>
+                                  </div>
+                            )
+                          }) : ''
+                      }
+                      </label>
+                    </div>
+                    </div>
+                );
+              })
+            }
+       </div>
+     );
+    }
+  }
+  vnfPlacementGroupsHTML = (props) => {
+    let vnfPlacementGroups = props.vnfPlacementGroups;
+    let displayPlacementGroups = props.displayPlacementGroups;
+    if (vnfPlacementGroups && vnfPlacementGroups.length > 0 && displayPlacementGroups) {
+      return vnfPlacementGroups.map(function(input, i) {
+            return (
+              <div className="configure-nsd_section" key={i}>
+                <h3 className="launchpadCard_title">{input['vnf-name']} VNF Placement Group</h3>
+                  <div className="configure-nsd_section-info">
+                    <div className="placementGroup_description">
+                      <div className="placementGroup_description-name">
+                        <strong>{input.name}</strong> contains: {
+                          input['member-vdus'].map((m,i) => {
+                            let s = m['member-vdu-ref'];
+                            if(i>0) {
+                              s = ', ' + m['member-vdu-ref']
+                            };
+                            return s;
+                          })
+                        }
+                      </div>
+                      <div><em>{input.requirement}</em></div>
+                      <div><strong>Strategy</strong>: {input.strategy}</div>
+                    </div>
+                    <label>
+                      <span> Availability Zone <span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span></span>
+                      <div  style={{display:'none'}}>
+                        <TextInput type="text" onChange={props.vnfFn.placementGroupUpdate.bind(self, i, 'availability-zone')} />
+                           <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
+                      </div>
+                    </label>
+                    <label>
+                      <span> Affinity/Anti-affinity Server Group<span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span></span>
+                      <div  style={{display:'none'}}>
+                        <TextInput type="text" onChange={props.vnfFn.placementGroupUpdate.bind(self, i, 'server-group')} />
+                         <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
+                      </div>
+                    </label>
+                    <div className="host-aggregate">
+                    <label>
+                      <span> Host Aggregates <span onClick={props.vnfFn.addHostAggregate.bind(self, i)} className="addInput"><img src={imgAdd} />Add</span></span>
+                      {
+                        input['host-aggregate'].length > 0 ?
+                          input['host-aggregate'].map((h,j) => {
+                            let key = h.key || '';
+                            let value = h.value || '';
+                            return (
+
+                                  <div className="input_group" key={j}>
+                                    <TextInput type="text" onChange={props.vnfFn.hostAggregateUpdate.bind(self, i, j, 'key')} placeholder="KEY" value={key} />
+                                    <TextInput type="text" onChange={props.vnfFn.hostAggregateUpdate.bind(self, i, j, 'value')} placeholder="VALUE"  value={value} />
+                                    <span onClick={props.vnfFn.removeHostAggregate.bind(self, i, j)} className="removeInput"><img src={imgRemove} />Remove</span>
+                                  </div>
+
+                            )
+                          }) : ''
+                      }
+                      </label>
+                    </div>
+                    </div>
+                </div>
+            );
+          });
+    }
+  }
+  vldsHTML = (props) => {
+    let self = this;
+    let ipProfileList = props.ipProfileList;
+    let vlds = props.vlds;
+    return vlds && (
+      <div className="configure-nsd_section">
+        <h3 className="launchpadCard_title">VLDs</h3>
+            {vlds && vlds.map(function(v, i) {
+                  let currentType = v.type;
+                  let isVIM = (currentType == 'vim-network-name');
+                  let isUnknown = (currentType == 'unknown') || ((currentType != 'vim-network-name') && (currentType != 'ip-profile-ref'));
+                  return (
+                    <div key={self.props.nsd.id + '-' + i} className="inputControls">
+                        <h4 className="inputControls-title">VLD: {v['short-name']}</h4>
+                        <div  className="inputControls-radioGroup">
+                          <label className="inputControls-radio" style={{display: ipProfileList ? 'flex' : 'none'}}>
+                            <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={!isVIM && !isUnknown} value='ip-profile-ref' />
+                            IP Profile
+                          </label>
+                          <label className="inputControls-radio">
+                            <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={isVIM && !isUnknown} value='vim-network-name' />
+                            VIM Network Name
+                          </label>
+                          <label className="inputControls-radio">
+                            <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={isUnknown} value='unknown' />
+                            Unknown
+                          </label>
+                        </div>
+                          {
+                            isUnknown ? null : isVIM ?
+                            <TextInput label="Network Name" onChange={self.props.vldFn.updateValue(i, currentType)} value={v[currentType]} /> :
+                            <div>
+                              <SelectOption
+                              label="IP PROFILE NAME"
+                                options={ipProfileList && ipProfileList.map(function(ip) {
+                                  return {
+                                    label: ip.name,
+                                    value: ip.name
+                                  }
+                                })}
+                                initial={
+                                  v['ip-profile-ref'] ? false : true
+                                }
+                                defaultValue={v['ip-profile-ref']}
+                                onChange={self.props.vldFn.updateValue(i, currentType)}>
+                              </SelectOption>
+
+                            </div>
+                          }
+                    </div>
+                  )
+                })}
+      </div>
+    );
+  }
+  ipProfilesHTML = (props) => {
+    let ipProfileList = props.ipProfileList;
+    return ipProfileList &&
+      (
+      <div className="configure-nsd_section">
+        <h3 className="launchpadCard_title">IP Profiles</h3>
+        {
+          //IP Config
+          ipProfileList && ipProfileList.map(function(ip, j) {
+            let ipl = ip['ip-profile-params'];
+              return (
+                <div className="inputControls" key={j}>
+                  <div className="inputControls-title" >
+                    {ip.name}
+                  </div>
+                  <div  className="inputControls-radioGroup">
+                    <label className="inputControls-radio">
+                      <input type="radio" name={'ip-profile-' + j } onChange={props.ipProfileFn.updateVersion(j)} checked={ipl['ip-version'] == 'ipv4'} value='ipv4' />
+                      ipv4
+                    </label>
+                    <label className="inputControls-radio">
+                      <input type="radio" name={'ip-profile-' + j } onChange={props.ipProfileFn.updateVersion(j)} checked={ipl['ip-version'] == 'ipv6'} value='ipv6' />
+                      ipv6
+                    </label>
+                    <label className="inputControls-radio">
+                      <input type="radio" name={'ip-profile-' + j } onChange={props.ipProfileFn.updateVersion(j)} checked={ipl['ip-version'] == 'unknown'} value='unknown' />
+                      unknown
+                    </label>
+                  </div>
+                  <TextInput
+                    label="subnet address"
+                    onChange={props.ipProfileFn.updateProfile(j, 'subnet-address')}
+                    value={ipl['subnet-address']}
+                    />
+                  <TextInput
+                    label="gateway address"
+                    onChange={props.ipProfileFn.updateProfile(j, 'gateway-address')}
+                    value={ipl['gateway-address']}
+                    />
+                  <TextInput
+                    label="security group"
+                    onChange={props.ipProfileFn.updateProfile(j, 'security-group')}
+                    value={ipl['security-group']}
+                    />
+                    <label>
+                      <div style={{display:'flex'}}>
+                        DNS SERVERS <span onClick={props.dnsFn.addDNS(j)} className="addInput"><img src={imgAdd} />Add</span>
+                      </div>
+                      {
+                        ipl['dns-server'] && ipl['dns-server'].map(function(dns, k) {
+                          return (
+                            <div key={k} style={{display:'flex'}}>
+                              <TextInput
+                                  onChange={props.ipProfileFn.updateProfile(j,k)}
+                                  value={ipl['dns-server'][k]}
+                                  />
+                              <span onClick={props.dnsFn.removeDNS(j,k)} className="removeInput">
+                                <img src={imgRemove} />Remove</span>
+                            </div>
+                          )
+                        })
+                      }
+                    </label>
+                  <div  className="inputControls-radioGroup">
+                    <label className="inputControls-radio">
+                    DHCP ENABLED
+                      <input type="radio"
+                        name={'ip-profile-dhcp' + j }
+                        onChange={props.ipProfileFn.updateDHCP(j, 'enabled')}
+                        checked={ipl.hasOwnProperty('dhcp-params') && ipl['dhcp-params'].enabled}
+                        value={true} />
+                      YES
+                    </label>
+                    <label className="inputControls-radio">
+                      <input type="radio"
+                        name={'ip-profile-dhcp' + j }
+                        onChange={props.ipProfileFn.updateDHCP(j, 'enabled')}
+                        checked={!ipl.hasOwnProperty('dhcp-params') || !ipl['dhcp-params'].enabled}
+                        value={false} />
+                      NO
+                    </label>
+                  </div>
+                  {
+                    (ipl['dhcp-params'] && ipl['dhcp-params'].enabled) ? dhcpHTML(props, ipl, j) : null
+                  }
+                </div>
+              )
+          })
+        }
+        </div>);
+    function dhcpHTML(props, ipl, j){
+      return (<div>
+                  <TextInput
+                    label="DCHP Start Address"
+                    onChange={props.ipProfileFn.updateDHCP(j, 'start-address')}
+                    value={ipl['dhcp-params'] && ipl['dhcp-params']['start-address']}
+                    />
+                  <TextInput
+                    label="DCHP Count"
+                    onChange={props.ipProfileFn.updateDHCP(j, 'count')}
+                    value={ipl['dhcp-params'] && ipl['dhcp-params']['count']}
+                    />
+                </div>
+                );
+    }
+  }
+  sshKeysHTML = (props) => {
+    let sshKeysList = props.sshKeysList;
+    let sshKeysRef = props.sshKeysRef;
+    if(sshKeysList && sshKeysList.length > 0) {
+      return (
+        <div className="configure-nsd_section">
+          <h3 className="launchpadCard_title">SSH Authorized Keys</h3>
+
+            {
+              sshKeysRef.map(function(ref, i) {
+                return (
+                  <div key={i} className="inputControls inputControls-sshkeys">
+                    <label>
+                      <div>
+                      <SelectOption
+                        label="Key Pair"
+                        options={sshKeysList && sshKeysList.map(function(k) {
+                          return {
+                            label: k.name,
+                            value: k
+                          }
+                        })}
+                        ref="keyPairSelection"
+                        initial={false}
+                        defaultValue={sshKeysList[0].name}
+                        onChange={self.props.updateSshKeyRef(i)}>
+                      </SelectOption>
+                      </div>
+                    </label>
+                    <label>
+                      <span onClick={self.props.updateSshKeyRef(i, true)} className="removeInput">
+                        <img src={imgRemove} />
+                        Remove
+                      </span>
+                    </label>
+                  </div>
+                )
+              })
+            }
+            <div className="inputControls inputControls-sshkeys ">
+              <label style={{display: 'flex', 'flexDirection': 'row'}}>
+              SSH KEY PAIR
+                <span onClick={self.props.updateSshKeyRef().bind(null, {target:{value: JSON.stringify(sshKeysList[0])}})} className="addInput">
+                  <img src={imgAdd} />
+                  ADD
+                </span>
+              </label>
+            </div>
+        </div>
+      );
+    }
+  }
+  usersHTML = (props) => {
+    let usersFn = props.usersFn;
+    let usersList = props.usersList && props.usersList.map(function(u, i) {
+      return (
+        <div className="input_group input_group-users" key={i}>
+          <div className="inputControls">
+          <div style={{fontWeight: 'bold', display: 'flex'}}>USER <span onClick={usersFn.remove(i)} className="removeInput"><img src={imgRemove} />Remove</span></div>
+            <TextInput onChange={usersFn.update(i, 'name')} label="USERNAME" value={i.name} />
+            <TextInput onChange={usersFn.update(i, 'gecos')} label="REAL NAME" value={i.gecos} />
+            <TextInput onChange={usersFn.update(i, 'passwd')} type="password" label="PASSWORD" value={i.passwd} />
+          </div>
+        </div>
+      )
+    });
+    return (
+      <div className="configure-nsd_section">
+        <h3 className="launchpadCard_title">USERS</h3>
+        {usersList}
+        <div className="inputControls inputControls-sshkeys ">
+            <span onClick={usersFn.add} className="addInput">
+              <img src={imgAdd} onClick={usersFn.add} />
+              ADD USER
+            </span>
+        </div>
+      </div>
+    )
+  }
+
+  render() {
+    const props = this.props;
+    let html;
+    let self = this;
+
+    html = (
+        <div className="instantiateInputParams">
+          {
+            //NS NAMEA AND CLOUD
+            this.nsConfigHTML(props)
+          }
+          {
+            //VNF VIM ACCOUNTS
+            this.vnfCloudAccountsHTML(props)
+          }
+          {
+            //INPUT PARAMETERS
+            this.inputParametersHTML(props)
+          }
+          {
+            //NS PLACEMENTGROUPS
+            this.nsPlacementGroupsHTML(props)
+          }
+          {
+            //VNF PLACEMENTGROUPS
+            this.vnfPlacementGroupsHTML(props)
+          }
+          {
+            //VLD CONFIGURATION
+            this.vldsHTML(props)
+          }
+          {
+            //IP PROFILE CONFIGURATION
+            this.ipProfilesHTML(props)
+          }
+          {
+            //SSH KEY ASSIGNMENTS
+            this.sshKeysHTML(props)
+          }
+          {
+            //USER MANAGEMENT
+            this.usersHTML(props)
+          }
+        </div>
+    )
+    return html;
+  }
+}
+function showInput(e){
+  let target = e.target;
+  if(target.parentElement.classList.contains("addInput")) {
+    target = target.parentElement;
+  }
+  target.style.display = 'none';
+  target.parentElement.nextElementSibling.style.display = 'flex';
+  // e.target.parentElement.nextElementSibling.children[1].style.display = 'initial';
+}
+function hideInput(e){
+  let target = e.target;
+  if(target.parentElement.classList.contains("removeInput")) {
+    target = target.parentElement;
+  }
+  target.parentElement.style.display = 'none';
+  target.parentElement.previousElementSibling.children[1].style.display = 'inline';
+  target.previousSibling.value = '';
+}
+function addDNS(){}
+function removeDNS(){}
+function constructCloudAccountOptions(cloudAccounts){
+  let CloudAccountOptions = cloudAccounts && cloudAccounts.map(function(ca, index) {
+    return {
+      label: ca.name,
+      value: ca
+    }
+  });
+  return CloudAccountOptions;
+}
+function dataCentersHTML(state, onChange) {
+  //Build DataCenter options
+  //Relook at this, why is it an object?
+  let dataCenters = state.dataCenters || [];
+  let DataCenterOptions = {};
+  if(dataCenters){
+    for (let d in dataCenters) {
+      DataCenterOptions[d] = dataCenters[d].map(function(dc, index) {
+        return {
+          label: dc.name,
+          value: dc.uuid
+        }
+      });
+    }
+  }
+  if (dataCenters.length > 0) {
+    return (
+      <label>Select Data Center
+        <SelectOption options={DataCenterOptions} onChange={onChange} />
+      </label>
+    )
+  }
+}
+function isOpenMano(account) {
+  if (account) {
+    let a = account;
+    if (a.constructor.name == 'String') {
+      a = JSON.parse(a);
+    }
+    if(a.hasOwnProperty('account')) {
+      a = a.account;
+    }
+    return a['account-type'] == 'openmano';
+  } else {
+    return false;
+  }
+}
+function updateNewSshKeyRefSelection(e) {
+  this.setState({
+    newRefSelection: e.target.value
+  })
+}
+function resetRef() {
+    this.setState({
+    newRefSelection: null
+  })
+}
+InstantiateInputParams.defaultProps = {
+  data: [],
+  sshKeysList: [],
+  sshKeysRef: [],
+  users: {}
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateInputParams.scss b/skyquake/plugins/launchpad/src/instantiate/instantiateInputParams.scss
new file mode 100644 (file)
index 0000000..3494316
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@import 'style/_colors.scss';
+@import 'style/layout.scss';
+.instantiateInputParams {
+    -ms-flex-preferred-size: 70%;
+        flex-basis: 70%;
+    &_section {
+      width:100%;
+      padding-top:0rem;
+      &:last-child {
+        padding-bottom:2rem;
+      }
+      &:first-child{
+        padding-top:0;
+      }
+      &:nth-child(odd) {
+        background:$gray-lighter;
+      }
+      >div {
+        padding:1rem;
+      }
+      h3 {
+        width:100%;
+        text-transform:uppercase;
+        padding-right: 0;
+
+      }
+      &-info {
+        /*add button*/
+        button{
+          margin:0;
+        }
+        label {
+          >div {
+            display: none;
+            -ms-flex-align: center;
+                -ms-grid-row-align: center;
+                align-items: center;
+          }
+          >span{
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-align:center;
+                align-items:center;
+          }
+        }
+      }
+    }
+    &-body {
+      -ms-flex-align: center;
+          -ms-grid-row-align: center;
+          align-items: center;
+      -ms-flex: none;
+          flex: none;
+      display: block;
+      width:100%;
+
+    }
+    label {
+        display: -ms-flexbox;
+        display: flex;
+        -ms-flex-direction: column;
+            flex-direction: column;
+        width: 100%;
+        margin: 0.5rem 0;
+        -ms-flex-align: start;
+            align-items: flex-start;
+        -ms-flex-pack:start;
+            justify-content:flex-start;
+        input[type="text"], input[type="password"] {
+          height: 35px;
+          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+          font-size: 1rem;
+          display: block;
+          background: white !important;
+          margin: 0;
+          margin-top: 0.25rem;
+          min-width:75%;
+        }
+        select {
+          font-size: 1rem;
+          min-width:75%;
+          height:35px;
+        }
+        span {
+          color:$darker-gray;
+          text-transform:uppercase;
+        }
+        >span {
+          display:-ms-flexbox;
+          display:flex;
+          margin-bottom: 0.5rem;
+        }
+        :first-child {
+        }
+      }
+      .input_group{
+          display:-ms-flexbox;
+          display:flex;
+          -ms-flex-wrap: wrap;
+              flex-wrap: wrap;
+          -ms-flex-pack: justify;
+              justify-content: space-between;
+          input, button{
+            -ms-flex: 1 1 auto;
+                flex: 1 1 auto;
+            margin-right: 1rem;
+            min-width:auto;
+          }
+          &-users {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-align: start;
+                align-items: flex-start;
+            .removeInput {
+              -ms-flex: 0 1;
+                  flex: 0 1;
+            }
+          }
+          button {
+            /*remove button*/
+            padding: 0.75rem 0.75rem;
+            -ms-flex:0 1 auto;
+                flex:0 1 auto;
+          }
+        }
+    .inputControls {
+      -ms-flex: 1 0;
+          flex: 1 0;
+      &-sshkeys {
+        display:-ms-flexbox;
+        display:flex;
+        padding-top:0.5rem;
+        padding-bottom:0px;
+          -ms-flex: 1 1;
+              flex: 1 1;
+        > label {
+          margin-bottom:0;
+          margin-top:0;
+        }
+        > label:nth-child(2) {
+              -ms-flex: 0 1 25%;
+                  flex: 0 1 25%;
+                  display: -ms-flexbox;
+                  display: flex;
+    -ms-flex-direction: column;
+        flex-direction: column;
+    -ms-flex-pack: center;
+        justify-content: center;
+        }
+      }
+      &-title {
+        margin-bottom: 0.5rem;
+        font-weight:bold;
+        text-transform:uppercase;
+      }
+      &-radio {
+        -ms-flex-direction:row;
+            flex-direction:row;
+            margin:0.5rem 0.5rem 0.5rem 0;
+            width:auto;
+      }
+      &-radioGroup {
+        display:-ms-flexbox;
+        display:flex;
+      }
+    }
+     .addInput, .removeInput {
+          display:-ms-flexbox;
+          display:flex;
+          -ms-flex-align:center;
+              align-items:center;
+          margin-left: 1rem;
+
+          font-size:0.75rem;
+          text-transform:uppercase;
+          font-weight:bold;
+
+          cursor:pointer;
+          img {
+            height:0.75rem;
+            margin-right:0.5rem;
+            width:auto;
+          }
+      }
+    .LaunchpadCard_title {
+      margin:1rem 0;
+    }
+    .placementGroup_description {
+      margin: 1rem 0;
+      >div {
+        margin:1rem 0;
+        strong {
+          font-weight:bold;
+        }
+        em {
+          font-style:italic;
+        }
+      }
+      &-name strong{
+        font-weight:bold;
+      }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateParameters.jsx b/skyquake/plugins/launchpad/src/instantiate/instantiateParameters.jsx
new file mode 100644 (file)
index 0000000..47bce91
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React, {Component} from 'react';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import {Panel, PanelWrapper} from 'widgets/panel/panel';
+import InstantiateDescriptorPanel from './instantiateDescriptorPanel.jsx';
+import InstantiateInputParams from './instantiateInputParams.jsx';
+class Instantiate extends Component {
+    constructor(props) {
+    super(props);
+  }
+    handleSelectVNFConfigAgent = (vnfid) => {
+        let self = this;
+        return function(e) {
+          let configAgentRef = JSON.parse(e.target.value);
+          self.Store.updateSelectedVNFConfigAgent(vnfid, configAgentRef);
+        }
+    }
+  render(){
+    //temporary
+    let selectedNSD = {};
+    let self = this;
+    this.props.nsd[0] && this.props.nsd[0].descriptors && this.props.nsd[0].descriptors.map(function(d) {
+        if(self.props.params.nsd == d.id) {
+            selectedNSD = d;
+        }
+    });
+    return (
+            <PanelWrapper>
+            <InstantiateDescriptorPanel descriptor={selectedNSD} />
+            <Panel title="Input Parameters">
+        <InstantiateInputParams
+
+            nsFn={this.props.nsFn()}
+            vnfFn={this.props.vnfFn()}
+            vldFn={this.props.vldFn()}
+            ipProfileFn={this.props.ipProfileFn()}
+            dnsFn={this.props.dnsFn()}
+            usersFn={this.props.usersFn()}
+            sshFn={this.props.sshFn()}
+            updateName={this.props.nameUpdated}
+            updateInputParam={this.props.updateInputParam}
+
+            nsd={selectedNSD}
+            selectedNSDid={this.props.selectedNSDid}
+            name={this.props.name}
+
+            cloudAccounts={this.props.cloudAccounts}
+            selectedCloudAccount={this.props.selectedCloudAccount}
+            vnfdCloudAccounts={this.props.vnfdCloudAccounts}
+            dataCenters={this.props.dataCenters}
+            configAgentAccounts={this.props.configAgentAccounts}
+            inputParameters={this.props['input-parameters']}
+
+            displayPlacementGroups={this.props.displayPlacementGroups}
+
+
+            nsPlacementGroups={this.props['ns-placement-groups']}
+            vnfPlacementGroups={this.props['vnf-placement-groups']}
+
+            vlds={this.props.vld}
+
+            ipProfileList={this.props.ipProfiles}
+
+            dnsServers={this.props.dnsServers}
+
+            usersList = {this.props.usersList}
+            selectedID={this.props.selectedNSDid}
+            selectedNSD={selectedNSD}
+
+        /></Panel>
+        </PanelWrapper>
+    )
+  }
+}
+
+Instantiate.defaultProps = {
+    nsd: [{}]
+}
+
+export default SkyquakeComponent(Instantiate);
+
+
+/*
+
+
+
+
+    ipProfiles={this.state.ipProfiles}
+    dnsServers={this.state.dnsServers}
+    vld={this.state.vld}
+    nsd={this.state.nsd[0]}
+    selectedID={this.state.selectedNSDid}
+    selectedNSD={this.state.selectedNSD}
+
+    vldFn={this.Store.vldFn()}
+    ipProfileFn={this.Store.ipProfileFn()}
+    dnsFn={this.Store.dnsFn()}
+    usersFn={this.Store.usersFn()}
+    sshFn={this.Store.sshFn()}
+ */
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateSelectDescriptorPanel.jsx b/skyquake/plugins/launchpad/src/instantiate/instantiateSelectDescriptorPanel.jsx
new file mode 100644 (file)
index 0000000..a8d4b67
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import CatalogCard from './catalogCard.jsx'
+import Panel from 'widgets/panel/panel.jsx'
+import React, {Component} from 'react';
+import './instantiateSelectDescriptorPanel.scss';
+export default class InstantiateSelectDescriptorPanel extends Component {
+    constructor(props) {
+        super(props)
+    }
+    render() {
+        let self = this;
+        let {catalog, onPreviewDescriptor, onSelectDescriptor, selectedDescriptorID, previewing, isPreviewing, closeCard, openDescriptor, ...props} = self.props;
+        return (
+            <Panel title="Select Descriptor"  className={"InstantiateSelectDescriptorPanel" + (isPreviewing ? " InstantiateSelectDescriptorPanel--previewmode" : '')}>
+            {
+                catalog.descriptors && catalog.descriptors.map(function(descriptor, i) {
+                    let isSelected = (descriptor.id === selectedDescriptorID);
+                    return (
+                        <CatalogCard
+                            key={i}
+                            isActive={isPreviewing && isSelected}
+                            isSelected={isSelected}
+                            descriptor={descriptor}
+                            onClick={onSelectDescriptor.bind(null, descriptor)}
+                            onDoubleClick={openDescriptor.bind(null, descriptor)}
+                            onPreviewDescriptor={onPreviewDescriptor}
+                            onCloseCard={closeCard}
+                        />
+                    )
+                })
+            }
+            </Panel>
+        )
+    }
+}
+
+InstantiateSelectDescriptorPanel.defaultProps = {
+    catalog: {},
+    onSelectDescriptor: function(descriptor) {
+        return (e) => {
+            console.log('Selecting NSD: ' + descriptor.id)
+        }
+    },
+    onPreviewDescriptor: function(descriptor) {
+        return (e) => {
+            console.log('Previewing NSD: ' + descriptor.id)
+        }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateSelectDescriptorPanel.scss b/skyquake/plugins/launchpad/src/instantiate/instantiateSelectDescriptorPanel.scss
new file mode 100644 (file)
index 0000000..b49132e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.InstantiateSelectDescriptorPanel {
+    display: -ms-flexbox;
+    display: flex;
+
+    &--previewmode {
+        -ms-flex: 1 1;
+            flex: 1 1;
+    }
+    &-body {
+        -ms-flex-direction:row;
+            flex-direction:row;
+        -ms-flex-wrap:wrap;
+            flex-wrap:wrap;
+            -ms-flex-line-pack: start;
+            align-content: flex-start;
+            height: 100%;
+            box-sizing: border-box;
+            overflow:auto;
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/instantiate/instantiateStore.js b/skyquake/plugins/launchpad/src/instantiate/instantiateStore.js
new file mode 100644 (file)
index 0000000..eafac26
--- /dev/null
@@ -0,0 +1,780 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import NetworkServiceActions from './launchNetworkServiceActions.js';
+import NetworkServiceSource from './launchNetworkServiceSource.js';
+import GUID from 'utils/guid.js';
+import AppHeaderActions from 'widgets/header/headerActions.js';
+import Alt from '../alt';
+import _ from 'lodash';
+
+
+class LaunchNetworkServiceStore {
+    constructor() {
+        this.nsd = [];
+        this.nsdDict = {};
+        this.vnfd = [];
+        this.pnfd = [];
+        this.vld = [];
+        this.name = "";
+        this.ipProfiles = [];
+        this.dnsServers = [];
+        this.sshKeysList = [];
+        this.sshKeysRef = [];
+        this.sla_parameters = [];
+        this.selectedNSDid;
+        this.selectedNSD = {};
+        this.selectedCloudAccount = {};
+        this.dataCenters = {};
+        this.cloudAccounts = [];
+        this.isLoading = false;
+        this.hasConfigureNSD = false;
+        this['input-parameters'] = [];
+        this.displayPlacementGroups = false;
+        this.bindActions(NetworkServiceActions);
+        this.nsdConfiguration = {
+            name:'',
+            selectedCloudAccount: {},
+            dataCenterID: null
+        };
+        /*Collection of vnf state containting cloud account and datacenter info.
+        keyed off vnfd-id-ref
+        */
+        this.vnfdCloudAccounts = {};
+        this.usersList = [];
+        this.configAgentAccounts = [];
+
+        this.isPreviewing = false;
+        this.registerAsync(NetworkServiceSource);
+        this.exportPublicMethods({
+            getMockData: getMockData.bind(this),
+            getMockSLA: getMockSLA.bind(this),
+            saveNetworkServiceRecord: this.saveNetworkServiceRecord,
+            nsFn: this.nsFn,
+            vnfFn: this.vnfFn,
+            updateInputParam: this.updateInputParam,
+            resetView: this.resetView,
+            nameUpdated: this.nameUpdated,
+            //nspg
+            descriptorSelected: this.descriptorSelected.bind(this),
+            deselectDescriptor: this.deselectDescriptor,
+            previewDescriptor: this.previewDescriptor,
+            vldFn: this.vldFn,
+            ipProfileFn: this.ipProfileFn,
+            dnsFn: this.dnsFn,
+            usersFn: this.usersFn,
+            sshFn: this.sshFn
+        });
+    }
+
+    //
+    resetView = () => {
+        console.log('reseting state');
+        this.setState({
+            name: '',
+            'input-parameter-xpath': null,
+            'ns-placement-groups': null,
+            'vnf-placement-groups':null,
+            vnfdCloudAccounts: {}
+        })
+    }
+
+
+    //Action Handlers
+    getCatalogSuccess(catalogs) {
+        let self = this;
+        let nsdDict = {};
+        let nsd = [];
+        let vnfd = [];
+        let pnfd = [];
+        catalogs.forEach(function(catalog) {
+            switch (catalog.type) {
+                case "nsd":
+                    nsd.push(catalog);
+                    try {
+                        self.descriptorSelected(catalog.descriptors[0])
+                    } catch (e) {
+                        console.log('unable to select catalog')
+                    }
+                    break;
+                case "vnfd":
+                    vnfd.push(catalog);
+                    break;
+                case "pnfd":
+                    pnfd.push(catalog);
+                    break;
+            }
+        });
+        nsd[0].descriptors.map(function(n) {
+            nsdDict[n.id] = n;
+        })
+        this.setState({
+            nsd, vnfd, pnfd, nsdDict,
+
+        });
+    }
+    getLaunchCloudAccountSuccess(cloudAccounts) {
+        let newState = {};
+        newState.cloudAccounts = cloudAccounts || [];
+        if(cloudAccounts && cloudAccounts.length > 0) {
+            newState.selectedCloudAccount = cloudAccounts[0];
+            if (cloudAccounts[0]['account-type'] == 'openstack') {
+                newState.displayPlacementGroups = true;
+            } else {
+             newState.displayPlacementGroups = false;
+            }
+        } else {
+            newState.selectedCloudAccount = {};
+        }
+
+        this.setState(newState);
+    }
+    getConfigAgentSuccess(configAgentAccounts) {
+        this.setState({
+            configAgentAccounts: configAgentAccounts
+        })
+    }
+    getDataCentersSuccess(dataCenters) {
+        let newState = {
+            dataCenters: dataCenters
+        };
+        if (this.selectedCloudAccount['account-type'] == 'openmano') {
+            newState.dataCenterID = dataCenters[this.selectedCloudAccount.name][0].uuid
+        }
+        this.setState(newState)
+    }
+    getVDUSuccess(VNFD) {
+        this.setState({
+            sla_parameters: VNFD
+        })
+    }
+    launchNSRLoading() {
+        Alt.actions.global.showScreenLoader.defer();
+        this.setState({
+            isLoading: true
+        });
+        console.log('is Loading', this)
+    }
+    launchNSRSuccess(data) {
+        console.log('Launching Network Service')
+        let tokenizedHash = window.location.hash.split('/');
+        Alt.actions.global.hideScreenLoader.defer();
+        this.setState({
+            isLoading: false
+        });
+        return window.location.hash = 'launchpad/' + tokenizedHash[2];
+    }
+    launchNSRError(error) {
+        Alt.actions.global.showError.defer('Something went wrong while trying to instantiate. Check the error logs for more information');
+        Alt.actions.global.hideScreenLoader.defer();
+        this.setState({
+            isLoading: false
+        });
+    }
+    getInstantiateSshKeySuccess = (data) => {
+        this.setState({
+            sshKeysList: data,
+            sshKeysRef: []
+        })
+    }
+    //Form handlers
+    nameUpdated = (e) => {
+        this.setState({
+            name: e.target.value
+        })
+    }
+    deselectDescriptor = () => {
+        console.log('deselecting')
+        this.setState({
+            selectedNSDid: null,
+            selectedNSD: {},
+            isPreviewing: false
+        })
+    }
+    descriptorSelected = (data) => {
+        let NSD = data;
+        let VNFIDs = [];
+        this.resetView();
+        let newState = {
+            selectedNSDid: NSD.id,
+            vld: NSD && NSD.vld && NSD.vld.map(function(v) {
+                //Adding a type for UI state management
+                //This is deleted before launch
+                if(v['ip-profile-ref']) {
+                    v.type = 'ip-profile-ref';
+                } else {
+                    if(v['vim-network-name']) {
+                        v.type = 'vim-network-name';
+                    } else {
+                        v.type = 'unknown';
+                    }
+                }
+                return v;
+            }),
+            ipProfiles: NSD['ip-profiles']
+        };
+        newState.selectedNSD = data;
+        if (NSD['input-parameter-xpath']) {
+            newState.hasConfigureNSD = true;
+            newState['input-parameters'] = NSD['input-parameter-xpath'];
+        } else {
+            newState.hasConfigureNSD = false;
+            newState['input-parameters'] = null;
+        }
+        if(NSD['ns-placement-groups'] && NSD['ns-placement-groups'].length > 0 ) {
+            newState['ns-placement-groups'] = NSD['ns-placement-groups'];
+        }
+        if(NSD['vnf-placement-groups'] && NSD['vnf-placement-groups'].length > 0 ) {
+            newState['vnf-placement-groups'] = NSD['vnf-placement-groups'];
+        }
+        NSD["constituent-vnfd"].map((v) => {
+            VNFIDs.push(v["vnfd-id-ref"]);
+        })
+        this.getInstance().getVDU(VNFIDs);
+        this.setState(newState);
+    }
+    previewDescriptor = (data) => {
+        let self = this;
+        return function(e) {
+            self.setState({
+                isPreviewing: true,
+                selectedNSD: data
+            })
+        }
+    }
+    updateInputParam = (i, value) => {
+        let ip = this['input-parameters'];
+        ip[i].value = value;
+        this.setState({
+            'input-parameters': ip
+        });
+    }
+    nsFn = () => {
+        let self = this;
+        return {
+            updateSelectedCloudAccount: (cloudAccount) => {
+                let nsd = self.nsd[0];
+                var newState = {
+                    selectedCloudAccount: cloudAccount
+                };
+                if (cloudAccount['account-type'] == 'openstack') {
+                    newState.displayPlacementGroups = true;
+                } else {
+                     newState.displayPlacementGroups = false;
+                }
+                if (cloudAccount['account-type'] == 'openmano' && this.dataCenters && self.dataCenters[cloudAccount['name']]) {
+                    let datacenter = self.dataCenters[cloudAccount['name']][0];
+                    newState.dataCenterID = datacenter.uuid;
+                }
+                self.setState(newState);
+            },
+            updateSelectedDataCenter: (dataCenter) => {
+                self.setState({
+                    dataCenterID: dataCenter
+                });
+            },
+            placementGroupUpdate: (i, k, value) => {
+                let pg = self['ns-placement-groups'];
+                pg[i][k] = value;
+                self.setState({
+                    'ns-placement-groups': pg
+                })
+            },
+            hostAggregateUpdate: (pgi, hai, k, value) => {
+                let pg = self['ns-placement-groups'];
+                let ha = pg[pgi]['host-aggregate'][hai];
+                ha[k] = value;
+                self.setState({
+                    'ns-placement-groups': pg
+                })
+            },
+            addHostAggregate: (pgi) => {
+                let pg = self['ns-placement-groups'];
+                let ha = pg[pgi]['host-aggregate'];
+                ha.push({});
+                self.setState({
+                    'ns-placement-groups': pg
+                })
+            },
+            removeHostAggregate: (pgi, hai) => {
+                let pg = self['ns-placement-groups'];
+                let ha = pg[pgi]['host-aggregate'];
+                ha.splice(hai, 1);
+                self.setState({
+                    'ns-placement-groups': pg
+                })
+            },
+            getNSDByID: (id) => {
+
+            }
+        }
+    }
+    vnfFn = () => {
+        let self = this;
+        return {
+            placementGroupUpdate: (i, k, value) => {
+                let pg = self['vnf-placement-groups'];
+                pg[i][k] = value;
+                self.setState({
+                    'vnf-placement-groups': pg
+                })
+            },
+            hostAggregateUpdate: (pgi, hai, k, value) => {
+                let pg = self['vnf-placement-groups'];
+                let ha = pg[pgi]['host-aggregate'][hai];
+                ha[k] = value;
+                self.setState({
+                    'vnf-placement-groups': pg
+                })
+            },
+            addHostAggregate: (pgi) => {
+                let pg = self['vnf-placement-groups'];
+                let ha = pg[pgi]['host-aggregate'];
+                ha.push({});
+                self.setState({
+                    'vnf-placement-groups': pg
+                })
+            },
+            removeHostAggregate: (pgi, hai) => {
+                let pg = self['vnf-placement-groups'];
+                let ha = pg[pgi]['host-aggregate'];
+                ha.splice(hai, 1);
+                self.setState({
+                    'vnf-placement-groups': pg
+                })
+            },
+            updateSelectedCloudAccount: (id, cloudAccount) => {
+                let vnfCA = self.vnfdCloudAccounts;
+                if(cloudAccount) {
+                    if(!vnfCA.hasOwnProperty(id)) {
+                        vnfCA[id] = {};
+                    }
+                    vnfCA[id].account = cloudAccount;
+
+                    if (cloudAccount['account-type'] == 'openmano' && this.dataCenters && self.dataCenters[cloudAccount['name']]) {
+                        let datacenter = self.dataCenters[cloudAccount['name']][0];
+                        vnfCA[id].datacenter = datacenter.uuid;
+                    } else {
+                        if (vnfCA[id].datacenter) {
+                            delete vnfCA[id].datacenter;
+                        }
+                    }
+                } else {
+                    if(vnfCA.hasOwnProperty(id)) {
+                        if(vnfCA[id].hasOwnProperty('config-agent-account')) {
+                            delete vnfCA[id].account;
+                        } else {
+                            delete vnfCA[id];
+                        }
+                    }
+                }
+                self.setState({
+                    vnfdCloudAccounts: vnfCA
+                });
+            },
+            updateSelectedConfigAgent:  (id) => {
+                return function(e) {
+                    let configAgentRef = JSON.parse(e.target.value);
+                    let vnfCA = self.vnfdCloudAccounts;
+                    if(configAgentRef) {
+                        if(!vnfCA.hasOwnProperty(id)) {
+                            vnfCA[id] = {};
+                        }
+                        vnfCA[id]['config-agent-account'] = configAgentRef;
+                    } else {
+                        if(vnfCA[id].hasOwnProperty('account')) {
+                            delete vnfCA[id]['config-agent-account'];
+                        } else {
+                            delete vnfCA[id];
+                        }
+                    }
+                    self.setState({
+                        vnfdCloudAccounts: vnfCA
+                    });
+                }
+            },
+            updateSelectedDataCenter: (id, dataCenter) => {
+                let vnfCA = self.vnfdCloudAccounts;
+                vnfCA[id].datacenter = dataCenter;
+                self.setState({
+                    vnfdCloudAccounts: vnfCA
+                });
+            }
+        }
+    }
+    vldFn = () => {
+        let self = this;
+        return {
+            updateType: (i) => {
+                return function(e){
+                    let type = e.target.value;
+                    let vld = self.vld;
+                    if (vld[i].hasOwnProperty('type')) {
+                        delete vld[i][vld[i].type]
+                    }
+                    vld[i].type = type;
+                    vld[i][type] = '';
+                    if(type == 'ip-profile-ref') {
+                        let IPProfile = self.ipProfiles;
+                        vld[i][type] = IPProfile[0] && IPProfile[0].name;
+                        delete vld[i]['vim-network-name'];
+                    } else {
+                        delete vld[i]['dns-server'];
+                    }
+                    if(type == 'unknown') {
+                        delete vld[i]['ip-profile-ref'];
+                        delete vld[i]['vim-network-name'];
+                    }
+                    self.setState({vld:vld});
+                }
+            },
+            updateValue:  (i, type) => {
+                return function(e) {
+                    // Select Option returns JSON values.
+                    let value = e.target.nodeName == "SELECT" ? JSON.parse(e.target.value) : e.target.value;
+                    let vld = self.vld;
+                    vld[i][type] = value;
+                    self.setState({vld:vld});
+                }
+            }
+        }
+    }
+    ipProfileFn = () => {
+        let self = this;
+        return {
+            updateProfile: (i, key) => {
+                return function(e) {
+                    // Select Option returns JSON values.
+                    let value = e.target.nodeName == "SELECT" ? JSON.parse(e.target.value) : e.target.value;
+                    self.ipProfiles[i]['ip-profile-params'][key] = value;
+
+                    self.setState({ipProfiles:self.ipProfiles});
+                }
+            },
+            updateVersion: (i) => {
+                return function(e) {
+                    // Select Option returns JSON values.
+                    let value = e.target.value;
+                    self.ipProfiles[i]['ip-profile-params']['ip-version'] = value;
+                    self.setState({ipProfiles:self.ipProfiles});
+                }
+            },
+            updateDNS: (i, dnsIndex) => {
+                return function(e) {
+                    // Select Option returns JSON values.
+                let value = e.target.nodeName == "SELECT" ? JSON.parse(e.target.value) : e.target.value;
+                    self.ipProfiles[i]['ip-profile-params']['dns-server'][dnsIndex] = value;
+                    self.setState({ipProfiles:self.ipProfiles});
+                }
+            },
+            updateDHCP: (i, property) => {
+                return function(e) {
+                    let value = e.target.value;
+                    //If value is meant to be boolean, convert it
+                    if(value == "true" || value == "false") {
+                        value = JSON.parse(value);
+                    }
+                    if(!self.ipProfiles[i]['ip-profile-params'].hasOwnProperty('dhcp-params')) {
+                        self.ipProfiles[i]['ip-profile-params']['dhcp-params'] = {
+                            enabled: true,
+                            'start-address': '',
+                            count: ''
+                        }
+                    }
+                    //Removing DCHP property on disable to allow instantiation
+                    if(!value) {
+                        delete self.ipProfiles[i]['ip-profile-params']['dhcp-params'];
+                    } else {
+                        self.ipProfiles[i]['ip-profile-params']['dhcp-params'][property] = value;
+                    }
+                    self.setState({ipProfiles:self.ipProfiles});
+                }
+            }
+        }
+    }
+    dnsFn = () => {
+        let self = this;
+        return {
+            addDNS: (i) => {
+                let self = this;
+                return function(e) {
+                    if(self.ipProfiles[i]['ip-profile-params']['dns-server']) {
+                        self.ipProfiles[i]['ip-profile-params']['dns-server'].unshift('')
+                    } else {
+                        self.ipProfiles[i]['ip-profile-params']['dns-server'] = [''];
+                    }
+
+                    self.setState({ipProfiles:self.ipProfiles});
+                }
+            },
+            removeDNS: (i, k) => {
+                let self = this;
+                return function(e) {
+                    self.ipProfiles[i]['ip-profile-params']['dns-server'].splice(k, 1);
+                    if(self.ipProfiles[i]['ip-profile-params']['dns-server'].length == 0) {
+                        delete self.ipProfiles[i]['ip-profile-params']['dns-server'];
+                    }
+                    self.setState({ipProfiles:self.ipProfiles});
+                }
+            }
+        }
+    }
+    sshFn = () => {
+        let self = this;
+        return {
+            updateNewKeyRefSelection: (e) => {
+                self.setState({
+                    newRefSelection: e.target.value
+                })
+            },
+            updateKeyRef: (refIndex, remove) => {
+                let self = this;
+                return function(e) {
+                    let sshKeysRef = self.sshKeysRef;
+                    if(!remove) {
+                        // if(!e.target.value) {
+                        //     return Alt.actions.global.showError.defer('Please select a key pair');
+                        // } else {
+                            if(!isNaN(refIndex)){
+                                sshKeysRef.splice(refIndex, 1);
+                                sshKeysRef.push(e.target.value);
+                            } else {
+                                sshKeysRef.push(e.target.value);
+                            }
+                        // }
+                    } else {
+                        sshKeysRef.splice(refIndex, 1);
+                    }
+                    self.setState({
+                        sshKeysRef: sshKeysRef,
+                        newRefSelection: null
+                    })
+                }
+            }
+        }
+    }
+    usersFn = () => {
+        let self = this;
+        return {
+            add: function() {
+                console.log('adding user')
+                let newUser = {
+                    name: '',
+                    gecos: '',
+                    passwd: ''
+                }
+                let usersList = self.usersList;
+                usersList.push(newUser);
+                self.setState({
+                    usersList:  usersList
+                })
+            },
+            remove: function(i) {
+                return function() {
+                    self.usersList.splice(i, 1);
+                    self.setState({
+                        usersList: self.usersList
+                    })
+                }
+            },
+            update: function(i, key) {
+                return function(e) {
+                    let value = e.target.value;
+                    self.usersList[i][key] = value;
+                    self.setState({
+                        usersList: self.usersList
+                    })
+                }
+            }
+        }
+    }
+    saveNetworkServiceRecord(name, launch) {
+        //input-parameter: [{uuid: < some_unique_name>, xpath: <same as you got from nsd>, value: <user_entered_value>}]
+        /*
+        'input-parameter-xpath':[{
+                'xpath': 'someXpath'
+            }],
+         */
+        let nsPg = null;
+        let vnfPg = null;
+        let guuid = GUID();
+
+        // Create a filtered NSD payload from the decorated one as RW.REST cannot handle extra parameters now
+        let nsdPayload = {};
+        nsdPayload = _.cloneDeep(_.find(this.state.nsd[0].descriptors, {id: this.state.selectedNSDid}));
+
+        if (nsdPayload != {}) {
+            nsdPayload['meta'] && delete nsdPayload['meta'];
+            nsdPayload['constituent-vnfd'] && nsdPayload['constituent-vnfd'].map((constituentVnfd) => {
+                constituentVnfd['vnf-name'] && delete constituentVnfd['vnf-name'];
+                constituentVnfd['name'] && delete constituentVnfd['name'];
+            });
+            nsdPayload['placement-groups'] && nsdPayload['placement-groups'].map((placementGroup) => {
+                placementGroup['member-vnfd'] && placementGroup['member-vnfd'].map((memberVnfd) => {
+                memberVnfd['name'] && delete memberVnfd['name'];
+            });
+            })
+            nsdPayload['ns-placement-groups'] && delete nsdPayload['ns-placement-groups'];
+            nsdPayload['vnf-placement-groups'] && delete nsdPayload['vnf-placement-groups'];
+            nsdPayload.vld = this.state.vld;
+            nsdPayload.vld && nsdPayload.vld.map(function(v){
+                delete v['unknown'];
+                delete v.type;
+            })
+        }
+        let vnfdCloudAccounts = this.state.vnfdCloudAccounts;
+        let payload = {
+            id: guuid,
+            "name": name,
+            "short-name": name,
+            "description": "a description for " + guuid,
+            "admin-status": launch ? "ENABLED" : "DISABLED",
+            "nsd": nsdPayload
+        }
+        payload["cloud-account"] = this.state.selectedCloudAccount.name;
+        if (this.state.selectedCloudAccount['account-type'] == "openmano") {
+            payload['om-datacenter'] = this.state.dataCenterID;
+        }
+        if (this.state.hasConfigureNSD) {
+            let ips = this.state['input-parameters'];
+            let ipsToSend = ips.filter(function(ip) {
+                if (ip.value && ip.value != "") {
+                    ip.uuid = GUID();
+                    delete ip.name;
+                    return true;
+                }
+                return false;
+            });
+            if (ipsToSend.length > 0) {
+                payload['input-parameter'] = ipsToSend;
+            }
+        }
+        // These placement groups need to be refactored. Too much boilerplate.
+        if (this.state.displayPlacementGroups) {
+            nsPg = this.state['ns-placement-groups'];
+            vnfPg = this.state['vnf-placement-groups'];
+            if(nsPg && (nsPg.length > 0)) {
+                payload['nsd-placement-group-maps'] = nsPg.map(function(n, i) {
+                    if(n['availability-zone'] || n['server-group'] || (n['host-aggregate'].length > 0)) {
+                        var obj = {
+                            'cloud-type': 'openstack'
+                        };
+                        if(n['host-aggregate'].length > 0) {
+                            obj['host-aggregate'] = n['host-aggregate'].map(function(h, j) {
+                                return {
+                                    'metadata-key': h.key,
+                                    'metadata-value': h.value
+                                }
+                            })
+                        }
+                        if(n['availability-zone'] && (n['availability-zone'] != '')) {
+                            obj['availability-zone'] = {name: n['availability-zone']};
+                        }
+                        if(n['server-group'] && (n['server-group'] != '')) {
+                            obj['server-group'] = {name: n['server-group']};
+                        }
+                        obj['placement-group-ref'] = n.name;
+                        return obj;
+                    }
+                }).filter(function(o){
+                    if(o) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                });
+            };
+            if(vnfPg && (vnfPg.length > 0)) {
+                payload['vnfd-placement-group-maps'] = vnfPg.map(function(n, i) {
+                    if(n['availability-zone'] || n['server-group'] || (n['host-aggregate'].length > 0)) {
+                        var obj = {
+                            'cloud-type': 'openstack'
+                        };
+                        if(n['host-aggregate'].length > 0) {
+                            obj['host-aggregate'] = n['host-aggregate'].map(function(h, j) {
+                                return {
+                                    'metadata-key': h.key,
+                                    'metadata-value': h.value
+                                }
+                            })
+                        }
+                        if(n['server-group'] && (n['server-group'] != '')) {
+                            obj['server-group'] = {name: n['server-group']};
+                        }
+                        if(n['availability-zone'] && (n['availability-zone'] != '')) {
+                            obj['availability-zone'] = {name: n['availability-zone']};
+                        }
+                        obj['placement-group-ref'] = n.name;
+                        obj['vnfd-id-ref'] = n['vnfd-id-ref'];
+                        return obj;
+                    }
+                }).filter(function(o){
+                    if(o) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                });
+            }
+        }
+        //Construct VNF cloud accounts
+        payload['vnf-cloud-account-map'] = [];
+        for(let k in vnfdCloudAccounts) {
+            let vnf = {};
+            vnf['member-vnf-index-ref'] = k;
+            if(vnfdCloudAccounts[k].hasOwnProperty('account') && (vnfdCloudAccounts[k]['account'] && vnfdCloudAccounts[k]['account'].name)) {
+                vnf['cloud-account'] = vnfdCloudAccounts[k].account.name;
+            }
+            if(vnfdCloudAccounts[k].hasOwnProperty('config-agent-account') && vnfdCloudAccounts[k]['config-agent-account']) {
+                vnf['config-agent-account'] = vnfdCloudAccounts[k]['config-agent-account'];
+            }
+            if(vnfdCloudAccounts[k].hasOwnProperty('datacenter')) {
+                vnf['om-datacenter'] = vnfdCloudAccounts[k].datacenter;
+            }
+            payload['vnf-cloud-account-map'].push(vnf);
+        }
+        //Add SSH-Keys
+        payload['ssh-authorized-key'] = this.state.sshKeysRef.map(function(k) {
+            return {'key-pair-ref': JSON.parse(k).name};
+        });
+        //Add Users
+        payload['user'] = this.state.usersList;
+        this.launchNSR({
+            'nsr': [payload]
+        });
+    }
+}
+
+
+
+function getMockSLA(id) {
+    console.log('Getting mock SLA Data for id: ' + id);
+    this.setState({
+        sla_parameters: slaData
+    });
+}
+
+function getMockData() {
+    console.log('Getting mock Descriptor Data');
+    this.setState({
+        nsd: data.nsd,
+        vnfd: data.vnfd,
+        pnfd: data.pnfd
+    });
+}
+// export default Alt.createStore(LaunchNetworkServiceStore);
+export default LaunchNetworkServiceStore;
diff --git a/skyquake/plugins/launchpad/src/instantiate/launchNetworkServiceActions.js b/skyquake/plugins/launchpad/src/instantiate/launchNetworkServiceActions.js
new file mode 100644 (file)
index 0000000..7f44bfe
--- /dev/null
@@ -0,0 +1,40 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from '../alt';
+export default Alt.generateActions(
+                                   'descriptorSelected',
+                                   'nameUpdated',
+                                   'omDatacenterUpdated',
+                                   'getCatalogSuccess',
+                                   'getCatalogError',
+                                   'getVDUSuccess',
+                                   'getVDUError',
+                                   'getLaunchCloudAccountSuccess',
+                                   'getLaunchCloudAccountError',
+                                   'getDataCentersSuccess',
+                                   'getDataCentersError',
+                                   'launchNSRLoading',
+                                   'launchNSRSuccess',
+                                   'launchNSRError',
+                                   'getInstantiateSshKeySuccess',
+                                   'getInstantiateSshKeyLoading',
+                                   'getInstantiateSshKeyError',
+                                   'getConfigAgentSuccess',
+                                   'getConfigAgentError'
+                                   )
diff --git a/skyquake/plugins/launchpad/src/instantiate/launchNetworkServiceSource.js b/skyquake/plugins/launchpad/src/instantiate/launchNetworkServiceSource.js
new file mode 100644 (file)
index 0000000..d2d950f
--- /dev/null
@@ -0,0 +1,195 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import $ from 'jquery';
+let Utils = require('utils/utils.js');
+let rw = require('utils/rw.js');
+const API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+const API_PORT = require('utils/rw.js').getSearchParams(window.location).api_port;
+export default function(Alt){
+  const Actions = Alt.actions.global;
+  return {
+  getCatalog: {
+      remote (state) {
+        return new Promise((resolve,reject) => {
+          $.ajax({
+            url: 'api/decorated-catalog?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function (data) {
+              resolve(
+                      typeof(data) == "string" ? JSON.parse(data):data
+                      );
+            }
+          }).fail(function(xhr){
+            console.log(xhr)
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });
+        });
+      },
+      success: Alt.actions.global.getCatalogSuccess,
+      error: Alt.actions.global.getCatalogError
+  },
+  getCloudAccount:{
+      remote (state, cb) {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/cloud-account?api_server=' +
+              API_SERVER,
+              type: 'GET',
+              beforeSend: Utils.addAuthorizationStub,
+              success: function (data) {
+                resolve(data);
+                if(cb) {
+                  cb();
+                }
+              }
+          })
+        })
+      },
+      success: Alt.actions.global.getLaunchCloudAccountSuccess,
+      error: Alt.actions.global.getLaunchCloudAccountError
+  },
+  getDataCenters:{
+      remote () {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/data-centers?api_server=' +
+              API_SERVER,
+              type: 'GET',
+              beforeSend: Utils.addAuthorizationStub,
+              success: function (data) {
+                resolve(data);
+              }
+          })
+        })
+      },
+      success: Alt.actions.global.getDataCentersSuccess,
+      error: Alt.actions.global.getDataCentersError
+  },
+  getVDU: {
+      remote (state, VNFDid) {
+        return new Promise((resolve,reject) => {
+          $.ajax({
+            url: 'api/vnfd?api_server=' + API_SERVER,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            dataType:'json',
+            data: {
+              data: VNFDid
+            },
+            success: function (data) {
+              resolve(
+                typeof(data) == "string" ? JSON.parse(data):data
+              );
+            }
+          })
+        });
+      },
+      success: Alt.actions.global.getVDUSuccess,
+      error: Alt.actions.global.getVDUError
+  },
+  launchNSR: {
+      remote (state, NSR) {
+        return new Promise((resolve, reject) => {
+          console.log('Attempting to instantiate NSR:', NSR)
+          $.ajax({
+            url: 'api/nsr?api_server=' + API_SERVER,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            dataType:'json',
+            data: {
+              data: NSR
+            },
+            success: function (data) {
+              resolve(
+                      typeof(data) == "string" ? JSON.parse(data):data
+                      );
+            },
+            error: function (err) {
+              console.log('There was an error launching')
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+            reject();
+          });
+        })
+      },
+      loading: Alt.actions.global.launchNSRLoading,
+      success: Alt.actions.global.launchNSRSuccess,
+      error: Alt.actions.global.launchNSRError
+  },
+  getSshKey: {
+      remote (state) {
+        return new Promise((resolve,reject) => {
+          $.ajax({
+            url: 'api/ssh-key?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function (data) {
+              resolve(data);
+            }
+          }).fail(function(xhr){
+            console.log(xhr)
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });
+        });
+      },
+      loading: Actions.getInstantiateSshKeyLoading,
+      success: Actions.getInstantiateSshKeySuccess,
+      error: Actions.getInstantiateSshKeyError
+  },
+  getSshKeys:{
+      remote(state) {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/nsd/' + NSDId + '/input-param?api_server=' + API_SERVER,
+            type: 'GET',
+              beforeSend: Utils.addAuthorizationStub,
+              success: function (data) {
+                resolve(data);
+              }
+          });
+        });
+      }
+  },
+  getConfigAgent:{
+      remote (state, cb) {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/config-agent-account?api_server=' +
+              API_SERVER,
+              type: 'GET',
+              beforeSend: Utils.addAuthorizationStub,
+              success: function (data) {
+                resolve(data);
+                if(cb) {
+                  cb();
+                }
+              }
+          })
+        })
+      },
+      success: Alt.actions.global.getConfigAgentSuccess,
+      error: Alt.actions.global.getConfigAgentError
+  }
+}
+}
diff --git a/skyquake/plugins/launchpad/src/launchpad-create.js b/skyquake/plugins/launchpad/src/launchpad-create.js
new file mode 100644 (file)
index 0000000..cbe6d4b
--- /dev/null
@@ -0,0 +1,132 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+require('../components/form-controls.js');
+require('./launchpad-launch-fleet.html');
+var createStore = require('./createStore.js');
+var createActions = require('./createActions.js');
+
+
+angular.module('launchpad')
+    .controller('launchpadCreateCtrl', function($timeout, $stateParams, $state) {
+        var self = this;
+        self.createStore =
+        // var createChannel = $rw.radio.channel('createFleet');
+        var apiServer = self.isOnline = require('utils/rw.js').getSearchParams(window.location).api_server;
+        // var federationChannel = $rw.radio.channel('federationChannel');
+        self.fleet = {
+            template_id: null,
+            pool_id: null,
+            description: '',
+            epa_attributes: {},
+            status: "active",
+            name: 'NEW FLEET'
+        };
+        self.slaParams = [];
+        self.federation = $stateParams.id;
+        createStore.getNetworkServices();
+        createStore.getSlaParams();
+        createStore.getPools();
+        createStore.listen(function(state) {
+                $timeout(function() {
+                    self.networkServices = state.networkServices;
+                    self.slaParams = state.slaParams;
+                    self.fleet.pool = state.pools[0];
+                        self.pools = state.pools;
+                    angular.forEach(self.slaParams, function(v) {
+                        if (!v.hasOwnProperty('value')) {
+                            v.value = v.options.second;
+                        };
+                        return v;
+                    });
+                })
+            })
+            // federationChannel.request("federation:services").then(function(data) {
+            //     $timeout(function() {
+            //         // self.fleet.service = 'cag';
+            //         self.networkServices = data;
+            //         createChannel.request('vnfParams', 'cag').then(function(data) {
+            //         $timeout(function() {
+            //             self.vnfParams = data;
+            //         });
+            //     });
+            //     });
+            // });
+            //     federationChannel.request('federation:pools', apiServer).then(function(data) {
+            //         $timeout(function() {
+            //             console.log('pools:', data)
+            //             self.fleet.pool = data[0];
+            //             self.pools = data;
+            //         })
+            //     });
+
+        //         federationChannel.request('federation:sla-params').then(function(data) {
+        //             $timeout(function() {
+        //                 self.slaParams = data;
+        //                 angular.forEach(self.slaParams, function(v) {
+        //                     if (!v.hasOwnProperty('value')) {
+        //                         v.value = v.options.second;
+        //                     };
+        //                     return v;
+        //                 });
+        //             }
+        //             );
+        //         });
+
+        // federationChannel.on("launchpadCreate", function() {
+        //         $state.go('launchpad', null, {reload: false});
+
+        // });
+
+        self.generateServiceImage = function(service) {
+            return ('assets/img/svg/' + service.src + (self.isSelectedService(service.id) ? '-active' : '-inactive') + '.svg');
+        };
+        self.generatePoolImage = function(pool) {
+            return ('assets/img/svg/' + self.refsDB.resources.openstackCloud.pools[pool.ref].src + (self.isSelectedPool(pool) ? '-active' : '-inactive') + '.svg');
+        };
+        self.isSelectedPool = function(id) {
+            return id == self.fleet.pool_id;
+        };
+        self.isSelectedService = function(id) {
+            return id == self.fleet.template_id;
+        };
+        self.launch = function(launch) {
+            if (self.fleet.name == "") {
+                createActions.validateError('Plase Name the Service')
+            }
+            createActions.validateReset();
+            self.slaParams.forEach(function(v) {
+                if (v.value.indexOf("RRC") > -1) {
+                    v.value = "RRC";
+                }
+                self.fleet.epa_attributes[v.ref] = v.value;
+            });
+            delete self.fleet.pool;
+            self.fleet.status = launch ? 'active' : 'inactive';
+            createStore.createEnvironment(self.fleet)
+        };
+        self.selectPool = function(id) {
+            self.fleet.pool_id = id;
+            // createChannel.command("pool:select", id);
+        };
+        self.selectService = function(id) {
+
+            self.fleet.template_id = id;
+            // createChannel.command("service:select", id);
+        };
+    });
diff --git a/skyquake/plugins/launchpad/src/launchpad.jsx b/skyquake/plugins/launchpad/src/launchpad.jsx
new file mode 100644 (file)
index 0000000..1643926
--- /dev/null
@@ -0,0 +1,127 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import LaunchpadCard from './launchpad_card/launchpadCard.jsx';
+import Loader from 'widgets/loading-indicator/loadingIndicator.jsx';
+import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
+import MPFilter from './monitoring-params-filter.jsx'
+import NsCardPanel from './nsCardPanel/nsCardPanel.jsx';
+import NsListPanel from './nsListPanel/nsListPanel.jsx';
+import Crouton from 'react-crouton'
+import AppHeader from 'widgets/header/header.jsx';
+import Utils from 'utils/utils.js';
+import './launchpad.scss';
+let ReactCSSTransitionGroup = require('react-addons-css-transition-group');
+var LaunchpadFleetActions = require('./launchpadFleetActions.js');
+var LaunchpadFleetStore = require('./launchpadFleetStore.js');
+
+export default class LaunchpadApp extends React.Component {
+  constructor(props) {
+    super(props);
+    var self = this;
+    this.state = LaunchpadFleetStore.getState();
+    this.state.slideno = 0;
+    this.handleUpdate = this.handleUpdate.bind(this);
+
+  }
+  componentDidMount() {
+    LaunchpadFleetStore.getCatalog();
+    LaunchpadFleetStore.listen(this.handleUpdate);
+
+    // Can not put a dispatch here it causes errors
+    // LaunchpadFleetActions.validateReset();
+    setTimeout(function() {
+      LaunchpadFleetStore.openNSRSocket();
+    },100);
+  /*
+  setTimeout(function() {
+    consoleo.log("launchpad.componentDidMount openNsrListSocket");
+    LaunchpadFleetStore.openNsrListSocket();
+  },100);
+    */
+
+  }
+  change(e) {
+
+  }
+  handleUpdate(data){
+    this.setState(data);
+  }
+  closeError() {
+    LaunchpadFleetActions.validateReset()
+  }
+  componentWillUnmount() {
+    LaunchpadFleetStore.closeSocket();
+    LaunchpadFleetStore.unlisten(this.handleUpdate);
+  }
+
+  handleOpenNsCard(nsr) {
+    LaunchpadFleetActions.openNSRCard(nsr);
+  }
+
+  handleCloseNsCard(id) {
+    LaunchpadFleetActions.closeNSRCard(id);
+  }
+
+  handleShowHideNsListPanelToggle() {
+    this.setState({
+      showNsListPanel: !this.state.showNsListPanel
+    })
+  }
+
+  openNsrs() {
+    return this.state.nsrs;
+  }
+
+  render () {
+    var self = this;
+    let mgmtDomainName = window.location.hash.split('/')[2];
+    let navItems = [];
+    if(!mgmtDomainName) {
+      mgmtDomainName = 'dashboard';
+    }
+    if(mgmtDomainName.toUpperCase() == 'DASHBOARD' || mgmtDomainName.toUpperCase() == 'UNDEFINED') {
+      mgmtDomainName = '';
+    } else {
+      mgmtDomainName = ' : ' + mgmtDomainName;
+    }
+    let nav = <AppHeader title={'LAUNCHPAD' + mgmtDomainName} nav={navItems} />
+
+    return (
+      <div className="app-body">
+        <div className="lp_dashboard">
+          <NsListPanel nsrs={self.state.nsrs}
+            openedNsrIDs={self.state.openedNsrIDs}
+            isVisible={self.state.isNsListPanelVisible}
+            />
+          <NsCardPanel nsrs={self.state.nsrs}
+            openedNsrIDs={self.state.openedNsrIDs} />
+        </div>
+      </div>
+    );
+    }
+}
+LaunchpadApp.contextTypes = {
+    router: React.PropTypes.object
+};
+LaunchpadApp.defaultProps = {
+  // name: 'Loading...',
+  // data: []
+  openedNsrIDs: []
+};
diff --git a/skyquake/plugins/launchpad/src/launchpad.scss b/skyquake/plugins/launchpad/src/launchpad.scss
new file mode 100644 (file)
index 0000000..4ef6d1c
--- /dev/null
@@ -0,0 +1,274 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+@import "style/layout.scss";
+@import '../node_modules/open-iconic/font/css/open-iconic.css';
+
+.app-body {
+    display:flex;
+    flex-direction:column;
+    display: flex;
+    flex-direction: column;
+    align-items: stretch;
+    height: 100%;
+}
+
+.name-input {
+  color: $gray-darkest;
+}
+.lpReactDashboard {
+  display:flex;
+  height:100%;
+  .app-body {
+    > header {
+      flex: 0 1 auto;
+      flex-shrink: 0;
+    }
+  }
+}
+.lp-react-launch {
+  display: flex;
+}
+.app-body.create-fleet {
+  height: 100%;
+}
+.name-input input {
+  background:white !important;
+  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+  display: block;
+  font-size: 120%;
+  height: 35px;
+  margin: 0;
+  margin-top: 0.25rem;
+  width: 350px;
+}
+
+.baseGridCell {
+  align-items: center;
+  display: flex;
+  flex: 0 0 auto;
+  min-height: 30px;
+  overflow: hidden;
+  padding-left: 2px;
+  padding-right: 2px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.lp_dashboard {
+  display: flex;
+  flex: 1;
+  flex-direction: row;
+  height: 100%;
+
+  /* Network service list styles */
+
+  .leftMinimizedNsListPanel {
+    display: flex;
+    flex: 1 100%;
+    height: auto;
+    max-width: 30px;
+    min-width: 30px;
+    header {
+      background-color: white;
+      display:block;
+      h3 {
+        // vertical | horizontal
+        // top | horizonal | bottom
+        // top right bottom left
+        padding: 1.5rem 0;
+        color: white;
+
+      }
+    }
+  }
+
+  .nsListPanel {
+    display: flex;
+    flex: 1 100%;
+    height: auto;
+    max-width: 500px;
+    min-width: 500px;
+
+    header {
+      background-color: white;
+      display:block;
+    }
+
+    &-body {
+      flex-flow: col wrap;
+    }
+  }
+
+  .nsListPanelToggle {
+    position:absolute;
+    top:1.5rem;
+    right:0.5rem;
+    cursor:pointer;
+    display:flex;
+    &:before {
+    }
+    &.on:before{
+    }
+  }
+
+  .nsListPanelToolbar {
+    background-color: $gray;
+    display: flex;
+    flex: 0 0 auto;
+    flex-direction: row;
+    padding-left: 1rem;
+    .button {
+      cursor: pointer;
+      display: flex;
+      //flex: 0;
+      margin: 4px;
+      margin: 0.5rem;
+      img {
+        height: 1.5rem;
+        margin-right: 0.85rem;
+      }
+      span {
+        padding-top: 0.2rem;
+      }
+    }
+  }
+  .nsList {
+    display: flex;
+    flex: 1;
+    flex-direction: column;
+    overflow: auto;
+    padding-left: 0;
+    padding-right: 0;
+    &-body {
+      overflow-y: scroll;
+    }
+  }
+  .nsListItemRow {
+    display: flex;
+    flex-direction: row;
+  }
+  .cellValue {
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+  .nsList-body .nsListItemRow:nth-child(odd):not(.openedCard) {
+    background-color: $gray-lighter;
+  }
+  .nsList-body .nsListItemRow:nth-child(even):not(.openedCard) {
+    background-color: $gray-lightest;
+  }
+  .nsListItemRow.openedCard {
+    background-color: $lighter-blue;
+  }
+  .nsListHeaderRow {
+    background-color: $gray;
+    border-top: 1px solid $gray-lightest;
+    border-bottom: 1px solid $gray-lightest;
+    display: flex;
+    flex: 0 0 auto;
+    flex-direction: row;
+  }
+  .nsListItemField {
+    @extend .baseGridCell;
+    span {
+      text-overflow: ellipsis;
+    }
+
+  }
+  .nsListHeaderField {
+    @extend .baseGridCell;
+    text-transform: uppercase;
+  }
+  .nsListHeaderField.nsColAction {
+  }
+  .nsListItemField.nsColAction {
+      padding-left: 0.2rem;
+  }
+
+  .colBorderRight {
+    border-right: 1px solid $gray-lightest;
+  }
+
+  .nsColNsName {
+    @extend .colBorderRight;
+    width: 130px;
+  }
+  .nsColNsdName {
+    @extend .colBorderRight;
+    width: 130px;
+  }
+  .nsColStatus {
+    @extend .colBorderRight;
+    width: 85px;
+  }
+  .nsColUptime {
+    @extend .colBorderRight;
+    width: 110px;
+  }
+  .nsColAction {
+    width: 20px;
+    text-overflow: clip;
+  }
+
+  .actionButton {
+    cursor: pointer;
+    // margin-top is a hack to fix the top of the glyph from
+    // being chopped off
+    margin-top: 5px;
+  }
+
+  .nsViewportLink {
+    text-decoration: none;
+    color: black;
+  }
+
+  /* Network service detail card styles */
+
+  .nsCardPanel {
+    //border: 1px solid black;
+    display: flex;
+    flex: 1 1 auto;
+    flex-wrap: nowrap;
+    height: auto;
+    header {
+      background-color: white;
+    }
+    &_content {
+    }
+    &-body {
+      background-color: $gray;
+      display: flex;
+      flex: 1;
+      flex-direction: row;
+      min-width: 0;
+      min-height: 0;
+      overflow-y: auto;
+      overflow-x: auto;
+    }
+  }
+
+  /* Angular wrapping */
+  lp-react-dashboard {
+    display:flex;
+  }
+}
+
+
+
diff --git a/skyquake/plugins/launchpad/src/launchpadBreadcrumbs.jsx b/skyquake/plugins/launchpad/src/launchpadBreadcrumbs.jsx
new file mode 100644 (file)
index 0000000..290f0fe
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+export default class LaunchpadBreadcrumbs extends React.Component {
+
+  constructor(props) {
+    super(props);
+    this.current = props.current;
+  }
+  componentDidMount() {
+
+  }
+  componentWillReceiveProps(props) {
+
+  }
+  breadcrumbItem(url, name, isCurrent) {
+    if (isCurrent) {
+      return (<span className="current">{name}</span>);
+    } else {
+      return (<a href={url} onClick={this.props.clickHandler}>{name}</a>);
+    }
+  }
+  render() {
+    let mgmtDomainName = window.location.hash.split('/')[2];
+    let nsrId = window.location.hash.split('/')[3];
+    let url_base = '#/launchpad/' + mgmtDomainName + '/' + nsrId;
+    let html = (
+      <div className="header-nav">
+        <a href={'#/launchpad/' + mgmtDomainName} onClick={this.props.clickHandler}>DASHBOARD</a>
+        <span className="spacer"> > </span>
+        {this.breadcrumbItem(url_base+'/detail', 'Viewport', (this.props.current == 'viewport'))}
+        <span className="spacer"> | </span>
+        {this.breadcrumbItem(url_base+'/topology', 'Topology', (this.props.current == 'topology' ))}
+        <span className="spacer"> | </span>
+        {this.breadcrumbItem(url_base+'/topologyL2', 'Topology L2', (this.props.current == 'topologyL2' ))}
+        <span className="spacer"> | </span>
+        {this.breadcrumbItem(url_base+'/topologyL2Vm', 'Topology L2Vm', (this.props.current == 'topologyL2Vm'))}
+      </div>
+    );
+    return html;
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/launchpadFleetActions.js b/skyquake/plugins/launchpad/src/launchpadFleetActions.js
new file mode 100644 (file)
index 0000000..2863c7a
--- /dev/null
@@ -0,0 +1,42 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from './alt';
+module.exports = Alt.generateActions(
+                                       'getNsrInstancesSuccess',
+                                       'getNsrInstancesError',
+                                       'openNSRSocketLoading',
+                                       'openNSRSocketSuccess',
+                                       'openNSRSocketError',
+                                       'setNSRStatusSuccess',
+                                       'setNSRStatusError',
+                                       'deleteNsrInstance',
+                                       'deleteNsrInstanceSuccess',
+                                       'deleteNsrInstanceError',
+                                       'nsrControlSuccess',
+                                       'nsrControlError',
+                                       'slideNoStateChange',
+                                       'slideNoStateChangeSuccess',
+                                       'validateError',
+                                       'validateReset',
+                                       'deletingNSR',
+                                       'openNsrCard',
+                                       'closeNsrCard',
+                                       'instantiateNetworkService',
+                                       'setNsListPanelVisible',
+                                       );
diff --git a/skyquake/plugins/launchpad/src/launchpadFleetSource.js b/skyquake/plugins/launchpad/src/launchpadFleetSource.js
new file mode 100644 (file)
index 0000000..71e3d7d
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || 8000;
+let DEV_MODE = require('utils/rw.js').getSearchParams(window.location).dev_mode || false;
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+var isSocketOff = true;
+var FleetActions = require('./launchpadFleetActions.js');
+var Utils = require('utils/utils.js');
+import $ from 'jquery';
+
+
+module.exports = function(Alt) {
+  //NEW SOURCE
+  return {
+    nsrControl: {
+      remote: function(state, method, url, value) {
+        return new Promise(function(resolve, reject) {
+          // $.ajax({});
+          // console.log(method + 'ing: "' + value + '" to "' + url + '"');
+          resolve(method + 'ing: "' + value + '" to "' + url + '"')
+        });
+      },
+      success: FleetActions.nsrControlSuccess,
+      error: FleetActions.nsrControlError
+    },
+    getNsrInstances: {
+      remote: function() {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'api/nsr?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          });
+        });
+      },
+      success: FleetActions.getNsrInstancesSuccess,
+      error: FleetActions.getNsrInstancesError
+    },
+    deleteNsrInstance: {
+      remote: function(d, id) {
+        console.log(id)
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'api/nsr/' + id + '?api_server=' + API_SERVER,
+            type: 'DELETE',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          });
+        });
+      },
+      success: FleetActions.deleteNsrInstanceSuccess,
+      error: FleetActions.deleteNsrInstancesError
+    }  ,
+    openNSRSocket: {
+      remote: function(state) {
+        return new Promise(function(resolve, reject) {
+          //If socket connection already exists, eat the request.
+          if(state.socket) {
+            return resolve(false);
+          }
+           $.ajax({
+            url: '/socket-polling?api_server=' + API_SERVER ,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              url: 'launchpad/api/nsr?api_server=' + API_SERVER
+            },
+            success: function(data, textStatus, jqXHR) {
+              Utils.checkAndResolveSocketRequest(data, resolve, reject);
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });;
+        });
+      },
+      loading: Alt.actions.global.openNSRSocketLoading,
+      success: FleetActions.openNSRSocketSuccess,
+      error: FleetActions.openNSRError
+    },
+    setNSRStatus: {
+      remote: function(state, id, status) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'api/nsr/' + id + '/admin-status?api_server=' + API_SERVER ,
+            type:'PUT',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              status: status
+            },
+            success: function(data, textStatus, jqXHR) {
+
+            }
+          });
+        });
+      },
+      success: FleetActions.setNSRStatusSuccess,
+      error: FleetActions.setNSRStatusError
+    }
+  }
+};
+
+Object.size = function(obj) {
+  var size = 0,
+    key;
+  for (key in obj) {
+    if (obj.hasOwnProperty(key)) size++;
+  }
+  return size;
+};
diff --git a/skyquake/plugins/launchpad/src/launchpadFleetStore.js b/skyquake/plugins/launchpad/src/launchpadFleetStore.js
new file mode 100644 (file)
index 0000000..54c45e4
--- /dev/null
@@ -0,0 +1,278 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from './alt';
+
+var FleetSource = require('./launchpadFleetSource.js');
+var FleetActions = require('./launchpadFleetActions.js');
+import CardActions from './launchpad_card/launchpadCardActions.js';
+var Utils = require('utils/utils.js');
+import LaunchNetworkServiceSource from './instantiate/launchNetworkServiceSource.js';
+import LaunchNetworkServiceActions from './instantiate/launchNetworkServiceActions.js';
+
+import {LaunchpadSettings} from './settings.js';
+
+
+var FleetStore;
+var _ = require('underscore');
+//  _.debounce(function(){});
+function FleetStoreConstructor() {
+  var self = this;
+  this.fleets = [];
+  this.descriptorCount = 0;
+  this.socket = null;
+  this.selectedSlaParam = '';
+  this.launchpads = [];
+  this.nsrs = [];
+  this.exportAsync(FleetSource);
+  this.exportAsync(LaunchNetworkServiceSource);
+  this.slideno = 0;
+  this.dropdownSlide = ['', 0];
+  this.slideChange = -1;
+  this.validateErrorEvent = 0;
+  this.launchpadSettings = new LaunchpadSettings();
+  this.openedNsrIDs = this.launchpadSettings.openedNSRs();
+  this.isNsListPanelVisible = true;
+  this.bindListeners({
+    //NEW
+    //Socket Actions
+    openNSRSocketLoading: FleetActions.openNSRSocketLoading,
+    openNSRSocketSuccess: FleetActions.openNSRSocketSuccess,
+    //Card Actions
+    handleUpdateControlInput: CardActions.updateControlInput,
+    //Source Actions
+    handleNsrControlSuccess: FleetActions.nsrControlSuccess,
+    handleNsrControlError: FleetActions.nsrControlError,
+    handleSlideNoStateChange: FleetActions.slideNoStateChange,
+    handleSlideNoStateChangeSuccess: FleetActions.slideNoStateChangeSuccess,
+    getNsrInstancesSuccess: FleetActions.getNsrInstancesSuccess,
+    getNsrInstancesError: FleetActions.getNsrInstancesError,
+    deleteNsrInstanceSuccess: FleetActions.deleteNsrInstanceSuccess,
+    deletingNSR: FleetActions.deletingNSR,
+    deleteNsrInstanceError: FleetActions.deleteNsrInstanceError,
+    setNSRStatusSuccess: FleetActions.setNSRStatusSuccess,
+    setNSRStatusError: FleetActions.setNSRStatusError,
+    validateReset: FleetActions.validateReset,
+    validateError: FleetActions.validateError,
+    //Launch Network Service Source Actions
+    getCatalogSuccess: LaunchNetworkServiceActions.getCatalogSuccess,
+    // Card management actions
+    openNsrCard: FleetActions.openNsrCard,
+    closeNsrCard: FleetActions.closeNsrCard,
+    instantiateNetworkService: FleetActions.instantiateNetworkService,
+    setNsListPanelVisible: FleetActions.setNsListPanelVisible,
+
+  });
+  this.bindAction(LaunchNetworkServiceActions.launchNSRSuccess, responseData => {
+    try {
+      this.openNsrCard(responseData.data.nsr_id);
+    } catch (e) {
+      console.log("Unable to open NS Card for response data: ", responseData);
+    }
+  });
+  this.exportPublicMethods({
+    getFleets: function() {
+      return this.getState().fleets;
+    },
+    closeSocket: this.closeSocket.bind(self)
+  });
+}
+
+FleetStoreConstructor.prototype.handleLogout = function() {
+  this.closeSocket();
+}
+
+FleetStoreConstructor.prototype.closeSocket = function() {
+  if(this.socket) {
+    window.multiplexer.channel(this.channelId).close();
+  }
+  this.setState({
+    socket:null
+  })
+}
+
+//NEW
+FleetStoreConstructor.prototype.openNSRSocketLoading = function(connection) {
+  console.log('open socketloading')
+  Alt.actions.global.showScreenLoader.defer();
+};
+FleetStoreConstructor.prototype.openNSRSocketSuccess = function(connection) {
+  var self = this;
+  var isLoading = true;
+  var ws = window.multiplexer.channel(connection);
+  if (!connection) return;
+  self.setState({
+    socket: ws.ws,
+    channelId: connection
+  });
+  ws.onmessage = function(socket) {
+    try {
+      var data = JSON.parse(socket.data);
+      if (!data.nsrs) {
+        console.warn('NSRS property not present on the payload, check that the api server is functioning correct and that the LP is fully launched. Received: ', data);
+        data.nsrs = [];
+      }
+      Utils.checkAuthentication(data.statusCode, function() {
+        self.closeSocket();
+      });
+      let deletingNSRs = [];
+
+      if (self.nsrs) {
+        deletingNSRs = _.filter(self.nsrs, function(nsr) {
+          return nsr.deleting == true;
+        });
+      };
+
+      deletingNSRs.forEach(function(deletingNSR) {
+        data.nsrs.map(nsr => {
+          if (nsr.id == deletingNSR.id) {
+            _.extend(nsr, deletingNSR);
+          }
+        });
+      });
+      if(isLoading) {
+        isLoading = false;
+        Alt.actions.global.hideScreenLoader.defer();
+      }
+      self.setState({
+        nsrs: data.nsrs
+      });
+     } catch(e) {
+      console.log('HIT an exception in openNSRSocketSuccess', e);
+    }
+  };
+}
+FleetStoreConstructor.prototype.getNsrInstancesSuccess = function(data) {
+  this.setState({
+    nsrs: data.nsrs
+  });
+};
+FleetStoreConstructor.prototype.deleteNsrInstanceSuccess = function(data) {
+  console.log('deleted', data)
+};
+
+FleetStoreConstructor.prototype.deletingNSR = function(id) {
+  console.log('deleting NSR', id);
+  let nsrs = [];
+  let self = this;
+  try {
+    nsrs = this.nsrs.map(nsr => {
+      if (nsr.id == id) {
+        nsr.deleting = true;
+        self.closedNsrCard(id);
+      }
+      return nsr;
+    });
+    this.setState({
+      nsrs: nsrs
+    })
+  } catch (e) {
+    console.log('No NSR\'s found. Should never get here');
+  }
+};
+
+FleetStoreConstructor.prototype.deleteNsrInstanceError = function(data) {};
+FleetStoreConstructor.prototype.getNsrInstancesError = function(data) {
+  console.log('ERROR', data)
+};
+FleetStoreConstructor.prototype.handleUpdateControlInput = _.debounce(function(data) {
+  var opt = data[0];
+  FleetStore.nsrControl(opt.operation, opt.url, data[1])
+}, 500).bind(null);
+FleetStoreConstructor.prototype.handleNsrControlSuccess = function(data) {
+  console.log(data)
+};
+FleetStoreConstructor.prototype.handleNsrControlError = function() {};
+FleetStoreConstructor.prototype.handleSlideNoStateChange = function(data) {
+  this.setState({
+    dropdownSlide: data.pane,
+    slideno: data.no,
+    slideChange: data.slideChange
+  });
+};
+FleetStoreConstructor.prototype.handleSlideNoStateChangeSuccess = function() {
+  this.setState({
+    slideChange: this.slideChange - 1
+  });
+};
+FleetStoreConstructor.prototype.setNSRStatusSuccess = function() {};
+FleetStoreConstructor.prototype.setNSRStatusError = function(data) {
+  console.log('Error changing NSR State', data)
+};
+
+FleetStoreConstructor.prototype.getCatalogSuccess = function(data) {
+  var self = this;
+  var descriptorCount = 0;
+  data.forEach(function(catalog) {
+    descriptorCount += catalog.descriptors.length;
+  });
+
+  self.setState({
+    descriptorCount: descriptorCount
+  });
+};
+
+FleetStoreConstructor.prototype.validateError = function(msg) {
+  this.setState({
+    validateErrorEvent: true,
+    validateErrorMsg: msg
+  });
+};
+FleetStoreConstructor.prototype.validateReset = function() {
+  this.setState({
+    validateErrorEvent: false
+  });
+};
+
+// Card management
+FleetStoreConstructor.prototype.openNsrCard = function(id) {
+  //console.log("*** *** FleetStore.openNsrCard with nsr id:", id);
+  const openedNsrIDs = this.openedNsrIDs.slice(0);
+  // Only add if card is not there
+  if (id) {
+    if (!openedNsrIDs.includes(id)) {
+      openedNsrIDs.unshift(id);
+      this.launchpadSettings.addOpenNSR(id);
+      this.setState({
+        openedNsrIDs: openedNsrIDs
+      });
+    } else {
+      console.log("NSR already open, id:%s", id);
+    }
+  } else {
+    console.log("null nsr id.");
+  }
+}
+FleetStoreConstructor.prototype.closeNsrCard = function(id) {
+  this.launchpadSettings.removeOpenNSR(id);
+  this.setState({
+      openedNsrIDs: this.openedNsrIDs.filter(nsr_id => nsr_id !== id)
+  });
+}
+FleetStoreConstructor.prototype.instantiateNetworkService = function(id) {
+  window.location.hash = window.location.hash + '/launch';
+}
+
+FleetStoreConstructor.prototype.setNsListPanelVisible = function(isVisible) {
+  this.setState({
+    isNsListPanelVisible: isVisible
+  })
+}
+
+FleetStore = Alt.createStore(FleetStoreConstructor);
+module.exports = FleetStore;
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/jobListCard.jsx b/skyquake/plugins/launchpad/src/launchpad_card/jobListCard.jsx
new file mode 100644 (file)
index 0000000..2a66540
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import './jobListCard.scss'
+import Uptime from 'widgets/uptime/uptime.jsx';
+import Modal from 'react-awesome-modal';
+
+
+class JobListCard extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.hideParameters = true;
+        this.state.modalVisible = false;
+    }
+    openModal() {
+        this.setState({
+            modalVisible : true
+        });
+    }
+
+    closeModal() {
+        this.setState({
+            modalVisible : false
+        });
+    }
+    getStatusColor(status) {
+        let color;
+        switch(status) {
+            case 'success' : color = 'green'; break;
+            case 'failure' : color = 'red'; break;
+            default : color = 'yellow'; break;
+        }
+        return 'jobListCard--status_' + color;
+    }
+    toggleParametersView(hideParameters) {
+        this.setState({
+            hideParameters: !hideParameters
+        })
+    }
+    getJobDetails(job) {
+        let jobDetails = null;
+        if (job['job-status-details']) {
+            jobDetails = (
+                <section className='jobListCard--details'>
+                    <h4 onClick={this.openModal.bind(this)}>Job Details</h4>
+                    <Modal
+                        visible={this.state.modalVisible}
+                        width="600"
+                        height="400"
+                        effect="fadeInUp">
+                        <div>
+                            <div className='jobListCard--details--content'>{job['job-status-details']}</div>
+                            <h4 className='jobListCard--details--close' onClick={this.closeModal.bind(this)}>Close</h4>
+                        </div>
+                    </Modal>
+                </section>
+            );
+        }
+        return jobDetails;
+    }
+    nsrCardHTML(props, key) {
+        let self = this;
+        let jobListStatus = this.getStatusColor(this.props['job-status']);
+        let hideParameters = this.state.hideParameters;
+        let parameterList = function(props) {
+            return props['parameter'] && props['parameter'].map((p, i) => {
+                let k = null;
+                if(key) {
+                    k = k + '-' + i;
+                }
+                return (
+                    <div key={k || i} className="jobListCard--listitem">
+                        <span className="jobListCard--parameter">{p.name}:</span> {p.value}
+                    </div>
+                );
+            });
+        }
+        let jobDetailsHTML = this.getJobDetails(this.props);
+        return (
+            <div className="jobListCard">
+                <div className="jobListCard--header">
+                    <div className="jobListCard--name">
+                        {props['job-name']}
+                    </div>
+                    <div className={"jobListCard--status " + jobListStatus} title={jobListStatus.toUpperCase()}/>
+                </div>
+                <div className="jobListCard--subtitle">
+                    <span>ID: {this.props['job-id']}</span>
+                </div>
+                <div className="jobListCard--subtitle">
+                    <Uptime initialTime={props['create-time']} run={false} /> ago
+                </div>
+                <div className={"jobListCard--parameters"}>
+                    <h4 onClick={self.toggleParametersView.bind(self, hideParameters)}>{hideParameters ? 'Show' : 'Hide'} Parameters</h4>
+                    <div className={"jobListCard--list"} style={{display: hideParameters ? 'none' : 'flex'}}>
+                        {
+                            parameterList(props)
+                        }
+                        {
+                            props.vnfr && props.vnfr.map(function(v) {
+                                return v.primitive && v.primitive.map(function(p) {
+                                    return parameterList(p, p.name)
+                                })
+                            })
+                        }
+                    </div>
+                </div>
+                {jobDetailsHTML}
+            </div>
+        )
+    }
+    vnfrCardHTML(props) {
+        let self = this;
+        let jobListStatus = this.getStatusColor(props['execution-status'] );
+        let hideParameters = this.state.hideParameters;
+        return (
+            <div className="jobListCard">
+                <div className="jobListCard--header">
+                    <div className="jobListCard--name">
+                        {props.name}
+                    </div>
+                    <div className={"jobListCard--status " + jobListStatus} title={jobListStatus.toUpperCase()}/>
+                </div>
+                <div className="jobListCard--subtitle">
+                    <span>ID: {props['job-id']}</span>
+                </div>
+                <div className={"jobListCard--parameters"}>
+                    <h4 onClick={self.toggleParametersView.bind(self, hideParameters)}>
+                        { hideParameters ? 'Show' : 'Hide' } Parameters
+                    </h4>
+                    <div style={{display: hideParameters ? 'none' : 'initial'}}>
+                        <div className={"jobListCard--list"}>
+                            {
+                                props['parameter'] && props['parameter'].map((q, k) => {
+                                        return (
+                                            <div key={k} className="jobListCard--listitem">
+                                                <span className="jobListCard--parameter">{q.name}:</span> {q.value}
+                                            </div>
+                                        );
+                                })
+                            }
+                        </div>
+                    </div>
+                </div>
+            </div>
+        )
+    }
+    render() {
+        let html;
+        let card = <div></div>
+        if (this.props.type=="nsr") {
+            card = this.nsrCardHTML(this.props);
+        }
+        if (this.props.type=="vnfr") {
+            card = this.vnfrCardHTML(this.props);
+        }
+        return card;
+    }
+}
+export default JobListCard;
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/jobListCard.scss b/skyquake/plugins/launchpad/src/launchpad_card/jobListCard.scss
new file mode 100644 (file)
index 0000000..8551abb
--- /dev/null
@@ -0,0 +1,86 @@
+@import 'style/_colors.scss';
+
+.jobListCard {
+    background:white;
+    border-radius: 5px;
+    padding:0.5rem;
+    margin:0.5rem;
+    &--header {
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-pack: justify;
+        justify-content: space-between;
+        -ms-flex-align: center;
+        align-items: center;
+        -ms-flex-wrap: wrap;
+        flex-wrap: wrap;
+        margin-bottom:0.25rem;
+    }
+    &--subtitle {
+        color:$darker-gray;
+        font-size:0.75rem;
+        margin-bottom:0.125rem;
+    }
+    &--status {
+        height: 0.75rem;
+        width: 0.75rem;
+        border-radius:50%;
+        &_red {
+            background:red;
+            border-color:red;
+        }
+        &_green {
+            background:green;
+            border-color:green;
+        }
+        &_yellow {
+            background:yellow;
+            border-color:yellow;
+        }
+    }
+    &--parameters {
+        font-size:0.75rem;
+        h4 {
+            padding-bottom:0.5rem;
+            text-decoration:underline;
+            cursor:pointer;
+        }
+
+    }
+    &--list {
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-wrap:wrap;
+            flex-wrap:wrap;
+    }
+    &--listitem {
+        -ms-flex: 1 1 48%;
+            flex: 1 1 48%;
+        margin:0.125rem;
+    }
+    &--listname {
+        -ms-flex:1 1 100%;
+            flex:1 1 100%;
+    }
+    &--parameter {
+        color:$darker-gray;
+    }
+    &--details {
+        font-size:0.75rem;
+        h4 {
+            padding-bottom:0.5rem;
+            text-decoration:underline;
+            cursor:pointer;
+        }
+        &--content {
+            height: 26em;
+            overflow-y: scroll;
+            padding: 1em;
+        }
+        &--close {
+            text-align: center;
+            margin-top: 3em;
+        }
+
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpad-card.js b/skyquake/plugins/launchpad/src/launchpad_card/launchpad-card.js
new file mode 100644 (file)
index 0000000..de27638
--- /dev/null
@@ -0,0 +1,370 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+require('./launchpad-fleet-card-params.html');
+var React = require('react');
+var LaunchpadCard = require('./launchpadCard.jsx');
+// var LaunchpadCard = require('../../components/dashboard_card/dashboard_card.jsx');
+angular.module('launchpad')
+  .directive('fleetCard', function($state, $stateParams) {
+    return {
+      restrict: 'AE',
+      replace: true,
+      template: '<div></div>',
+      scope: {
+        fleet: '=data',
+        $index: '=',
+        metric: '=?',
+        slaParam: '=?',
+        nfviMetric: '=?'
+      },
+
+      bindToController: true,
+      controllerAs: 'card',
+      link: function(scope, element, attributes) {
+
+      },
+      controller: function($timeout, $interval, $scope, $rootScope, $element) {
+        var self = this;
+
+        console.log(self.fleet)
+         $scope.$watch(function() {
+          return self.fleet}, reactRender)
+        function reactRender() {
+          console.log('rendering', self.fleet)
+          React.render(
+            React.createElement(LaunchpadCard, {className:'launchpadCard'}
+            ),
+           $element[0]
+          );
+        }
+        //FOR WAG ONLY
+        //   self.isOn = false;
+
+        //   //END WAG ONLY
+        //   //Remove for testing only
+        //   $scope.$watch(function() {
+        //     return self.fleet;
+        //   }, function() {});
+
+        //   // var fleetChannel = $rw.radio.channel('fleetChannel');
+        //   var FleetStore = require('../launchpadFleetStore.js');
+        //   self.valueFormat = {
+        //     "int": 1,
+        //     "dec": 0
+        //   };
+        //   self.federationID = $stateParams.id;
+        //   //if this is true, set gauges to start
+        //   if (require('utils/rw.js').getSearchParams(window.location).api_server) {
+        //     self.fleet.started = true;
+        //   }
+        //   self.apiServer = require('utils/rw.js').getSearchParams(window.location).api_server;
+        //   self.isNoisy = false;
+        //   var rateChanged = function(rate) {
+        //     self.rate = rate;
+        //     fleetChannel.command('fleet:change:rate', rate)
+        //   }
+        //   var packetSizeChanged = function(packetSize) {
+        //     self.packetSize = packetSize
+        //     fleetChannel.command('fleet:change:packetSize', packetSize)
+        //   };
+        //   self.openFleet = function(index) {
+        //     var params = require('utils/rw.js').getSearchParams(window.location);
+        //     if (params.api_server) {
+        //       if (params.api_server == "http://10.0.201.25:5000") {
+        //         var newLoc = window.location.origin + window.location.pathname + '?config=' + params.config + '&api_server=' + 'http://10.0.201.25:5050' + '#/wag';
+        //         window.open(newLoc);
+        //         return;
+        //       }
+        //       if (self.fleet.api == "10.0.117.22") self.fleet.api = "10.0.117.17";
+        //       var newLoc = window.location.origin + window.location.pathname + '?config=' + params.config + '&api_server=' + 'http://' + self.fleet.api + ':5050' + '&name=' + self.fleet.name + '&env_id=' + self.fleet.id + '#/dashboard/' + $stateParams.id + '/' + index;;
+        //       console.log('Opening new window at: %s', newLoc)
+        //       window.open(newLoc);
+        //     } else {
+        //       if (self.fleet.id == 'wag-fleet') {
+        //         var newLoc = window.location.origin + window.location.pathname + '?config=' + params.config + '#/wag';
+        //         window.open(newLoc);
+        //       }
+        //       window.open('#/dashboard/' + $stateParams.id + '/' + index);
+        //     }
+        //   };
+        //   self.openConsole = function(index) {
+        //     console.log(self);
+        //     var params = require('utils/rw.js').getSearchParams(window.location);
+        //     if (params.api_server) {
+        //       if (self.fleet.api == "10.0.117.22") self.fleet.api = "10.0.117.17";
+        //       var newLoc = self.apiServer + '/api/environments/' + self.fleet.id + '/console';
+        //       window.open(newLoc);
+        //     } else {
+        //       window.open('#/dashboard/' + $stateParams.id + '/' + index);
+        //     }
+        //   };
+
+
+        //   self.noisyToggle = function() {
+        //     var action;
+        //     if (self.isNoisy) {
+        //       action = 'stop';
+        //       self.isNoisy = false;
+        //     } else {
+        //       action = 'start';
+        //       self.isNoisy = true;
+        //     }
+        //     $.ajax({
+        //       url: "http://" + self.fleet.api + ':5050/api/operations/' + action + '-stream',
+        //       type: "POST",
+        //       headers: {
+        //         "Content-Type": "application/vnd.yang.operation+json"
+        //       },
+        //       dataType: "json",
+        //       data: JSON.stringify({
+        //         "input": {
+        //           "now": ""
+        //         }
+        //       })
+        //     });
+        //   };
+
+        //   self.toggleStatus = function() {
+        //     var state;
+        //     var status = self.fleet.status;
+        //     console.log(self.fleet)
+        //     if (status == "starting" || status == "stopping") {
+        //       return;
+        //     }
+        //     if (status == "active") {
+        //       state = "inactive";
+        //     } else {
+        //       state = "active";
+        //     }
+        //     self.fleet.status = state;
+        //     FleetStore.setFleetState(self.fleet.id, state);
+        //   };
+        //   //CAT + NOISY NEIGHBOR ONLY
+
+        //   self.catStarted = false;
+        //   self.catToggle = function() {
+        //     var action;
+        //     if (self.catStarted) {
+        //       action = 'stop';
+        //       self.catStarted = false;
+        //     } else {
+        //       action = 'start';
+        //       self.catStarted = true;
+        //     }
+        //     $.ajax({
+        //       url: "http://" + self.fleet.api + ':5050/api/operations/' + action + '-cat',
+        //       type: "POST",
+        //       headers: {
+        //         "Content-Type": "application/vnd.yang.operation+json"
+        //       },
+        //       dataType: "json",
+        //       data: JSON.stringify({
+        //         "input": {
+        //           "now": ""
+        //         }
+        //       })
+        //     });
+        //   };
+
+        //   self.deleteFleet = function() {
+        //     if (confirm("Do you really want to delete this fleet?")) {
+        //       // if (confirm("Seriously, you REALLY want to delete this?")) {
+        //         // fleetChannel.request('fleet:delete', self.fleet);
+        //         FleetStore.deleteFleet(self.fleet.id)
+        //       // }
+        //     }
+        //   };
+
+
+        //   /**
+        //    *  WAG Code Start
+        //    **/
+        //   // var wagChannel = $rw.radio.channel('wag');
+
+        //   //If Wag page Offline
+        //   if (!self.apiServer && self.fleet.id == 'wag-fleet') {
+        //     self.offline = setInterval(function() {
+        //       if (self.fleet.started) {
+        //         self.fleet.wagpage.clientsim['traffic-gen']['rx-pps'] = 100 * (Math.random() - .5) + 200;
+        //         self.fleet.wagpage.clientsim['traffic-gen']['tx-pps'] = 100 * (Math.random() - .5) + 200;
+        //       }
+        //     }, 2000);
+        //   }
+
+        //   // If Wag page Online
+        //   if (self.fleet.template_name == 'Wireless Access Gateway') {
+        //     wagChannel.command('wag-poll');
+        //     wagChannel.on('wag-update', function(data) {
+        //       $timeout(function() {
+        //         self.fleet.wagpage = {};
+        //         self.fleet.wagpage.clientsim = data.clientsim
+        //           // self.data.clientsim['traffic-sink']['rx-pps'] / 1000000;
+        //         self.isOn = data.clientsim['traffic-gen-status'].running;
+        //       });
+        //     });
+        //   }
+
+        //   $rootScope.$on('$stateChangeStart', function() {
+        //     wagChannel.command('wag-poll:kill');
+        //   });
+
+        //   /**
+        //    *  WAG Code End
+        //    **/
+
+
+      }
+    };
+  })
+
+.directive('launchpadFleetCardParams', function() {
+  return {
+    restrict: 'AE',
+    replace: true,
+    templateUrl: '/modules/launchpad/launchpad_card/launchpad-fleet-card-params.html',
+    controllerAs: 'params',
+    scope: {
+      $index: "=",
+      cardData: '=',
+      slaParam: '=?',
+      nfviMetric: '=?'
+    },
+    bindToController: true,
+    controller: function($scope, $stateParams, $timeout, $interval, $rootScope) {
+      //remove watch
+      $scope.$watch(function() {
+        return self.cardData;
+      }, function() {})
+      var self = this;
+      var apiServer = require('utils/rw.js').getSearchParams(window.location).api_server;
+      self.apiServer = apiServer;
+      // self.refs = refsDB;
+
+
+      // var LaunchpadFleetActions = require('../launchpadFleetActions.js');
+      // var LaunchpadFleetStore = require('../launchpadFleetStore.js');
+      //var LaunchpadFleetActions = require('./launchpadFleetActions.js');
+
+      self.rate = 40;
+      self.packetSize = 256;
+      self.refParam = $rw.refParams;
+      var currentNFVIRef;
+
+      this.visible = 'default';
+      if (self.cardData.id == "wag-fleet") {
+        self.cardData.started = self.cardData.wagpage.clientsim['traffic-gen-status'].running;
+      }
+
+
+      self.selectedNFVI = 0;
+      self.selectedSLAParam = {};
+      self.refPools = $rw.refPools;
+
+      // Event Listeners
+      // View Actions
+      self.load = function(panel) {
+        self.visible = panel;
+      };
+      self.filterSLA = function(ref) {
+        // fleetChannel.command('filter:SLAParams', ref);
+        FleetActions.filterSLAParams(ref);
+      };
+      self.filterNFVI = function(ref) {
+        FleetActions.filterNfviMetrics(ref)
+          // fleetChannel.command('filter:NFVIMetrics', ref);
+      };
+      self.serviceToggle = function(fleet, control) {
+        if (apiServer) {
+          var vnfrChannel = $rw.radio.channel('vnfr');
+          switch (control.ref) {
+            case "trafgen":
+              var action = (control.started) ? 'stop' : 'start';
+              vnfrChannel.command("vnf:command", action, control.data.api, "http://" + fleet.api + ':5050');
+              break;
+            case "iot_army":
+              var action = (control.started) ? 'stop' : 'start';
+              vnfrChannel.command("vnf:command", action, control.data.api, "http://" + fleet.api + ':5050');
+              break;
+          }
+        } else {
+          fleetChannel.command('fleet:start', $stateParams.id, self.$index);
+          if ($stateParams.id == 'wag-federation') {
+            if (!self.cardData.wagpage.clientsim['traffic-gen-status']) {
+              self.cardData.wagpage.clientsim['traffic-gen-status'] = {};
+            }
+            self.cardData.wagpage.clientsim['traffic-gen-status'].running = !self.cardData.wagpage.clientsim['traffic-gen-status'].running;
+          }
+        }
+
+      };
+      // Init Params
+
+
+      //WAG ONLY
+      if (self.apiServer == "http://10.0.201.25:5000") {
+        self.isWag = true;
+      }
+      self.toggleOn = function(e) {
+        // self.setPacket(e, self.packetSize);
+        // self.setRate(e, self.rate);
+        // self.setSubscribers(e, self.subscribers);
+        // self.setAP(e, self.ap);
+        var wagServer = ""
+        if (self.apiServer) {
+          if (self.isOn) {
+            $.ajax({
+              type: "POST",
+              url: "http://10.0.201.25:5050/api/running/stop-device-group/",
+              success: (function() {
+                console.log('stahp post sent')
+              })
+            });
+            $.ajax({
+              type: "POST",
+              url: "http://10.0.201.25:5050/api/running/stop-sink-server/",
+              success: (function() {
+                console.log('stahp post sent')
+              })
+            });
+          } else {
+            $.ajax({
+              type: "POST",
+              url: "http://10.0.201.25:5050/api/running/start-sink-server/",
+              success: (function() {
+                console.log('start post sent')
+              })
+            });
+            $.ajax({
+              type: "POST",
+              url: "http://10.0.201.25:5050/api/running/start-device-group/",
+              success: (function() {
+                console.log('start post sent')
+              })
+            });
+          }
+        }
+        self.isOn = !self.isOn;
+      }
+
+      //END WAG ONLY
+
+    },
+    link: function(s, e, a) {}
+  }
+});
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadCard.jsx b/skyquake/plugins/launchpad/src/launchpad_card/launchpadCard.jsx
new file mode 100644 (file)
index 0000000..e68a659
--- /dev/null
@@ -0,0 +1,285 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import './launchpad_card.scss';
+import LaunchpadNSInfo from './launchpadNSInfo.jsx';
+import LaunchpadHeader from './launchpadHeader.jsx';
+import MonitoringParamsCarousel from '../monitoring_params/monitoringParamsCarousel.jsx';
+import LaunchpadControls from './launchpadControls.jsx';
+import NfviMetricBars from 'widgets/nfvi-metric-bars/nfviMetricBars.jsx';
+import MetricBarGroup from 'widgets/metric-bars/metricBarGroup.jsx';
+import LoadingIndicator from 'widgets/loading-indicator/loadingIndicator.jsx';
+import RecordViewStore from '../recordViewer/recordViewStore.js';
+import TreeView from 'react-treeview';
+
+import circleXImage from '../../node_modules/open-iconic/svg/circle-x.svg';
+
+class LaunchpadCard extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  shouldComponentUpdate(nextProps) {
+    return true;
+  }
+  openLaunch = () => {
+    this.context.router.push({pathname:'instantiate'});
+  }
+  render() {
+    let html;
+    let metrics = '';
+    let monitoring_params_data;
+    let deleting = false;
+    let metricsAndParameters = [];
+    let carousel = ''
+    let closeCardAction = this.props.closeButtonAction;
+
+    if(this.props.nsr && this.props.nsr.data) {
+      metrics = this.props.nsr.data.map((info, index)=> {
+          return (<LaunchpadNSInfo  key={index} name={info.name} data={info.data}/>)
+      });
+    }
+    // debugger
+    if(this.props.nsr && this.props.nsr["monitoring-param"]) {
+      monitoring_params_data = this.props.nsr["monitoring-param"];
+    } else {
+      monitoring_params_data = null;
+    }
+
+    if (this.props.nsr && this.props.nsr.deleting) {
+      deleting = true;
+    }
+
+    if(true) {
+      // metricsAndParameters.push(<LaunchpadControls controlSets={this.props.nsr.nsControls} />)
+      if (this.props.nsr) {
+        if (this.props.nsr["nfvi-metrics"]) {
+          metricsAndParameters.push((
+                                     <div className="nfvi-metrics" key="nfviMetrics">
+                                      <LpCardNfviMetrics key="nfvi-metrics" name="NFVI METRICS" id={this.props.id} data={this.props.nsr["nfvi-metrics"]} />
+                                     </div>
+                                     ))
+        }
+        if (this.props.nsr["epa-params"]) {
+          metricsAndParameters.push(<EpaParams key="epa-params" data={this.props.nsr["epa-params"]} />);
+        }
+      }
+      carousel = <MonitoringParamsCarousel component_list={monitoring_params_data} slideno={this.props.slideno}/>;
+    }
+
+    if(this.props.create){
+      html = (
+        <DashboardCard>
+          <div className={'launchpadCard_launch'} onClick={this.openLaunch} style={{cursor:'pointer'}}>
+            <img src={require("style/img/launchpad-add-fleet-icon.png")}/> Instantiate Network Service </div>
+        </DashboardCard>
+        );
+    } else {
+      let self = this;
+      let closeButton = (
+            <a onClick={self.props.closeButtonAction}
+              className={"close-btn"}>
+              <img src={circleXImage} title="Close card" />
+              </a>
+      );
+
+      html = (
+        <DashboardCard className={'launchpadCard'} closeCard={closeButton}>
+          <LaunchpadHeader nsr={this.props.nsr} name={this.props.name} isActive={this.props.isActive} id={this.props.id}/>
+          {
+          deleting ?
+          <div className={'deletingIndicator'}>
+            <LoadingIndicator size={10} show={true} />
+          </div>
+          :
+          <div className="launchpadCard_content">
+            <div className="launchpadCard_title">
+              NSD: {this.props.nsr.nsd_name}
+            </div>
+            {carousel}
+            {metricsAndParameters}
+          </div>
+          }
+        </DashboardCard>
+      );
+    }
+    return html;
+  }
+}
+LaunchpadCard.contextTypes = {
+    router: React.PropTypes.object
+};
+LaunchpadCard.propTypes = {
+  nsr: React.PropTypes.object,
+  isActive: React.PropTypes.bool,
+  name: React.PropTypes.string
+ };
+LaunchpadCard.defaultProps = {
+  name: 'Loading...',
+  data: {},
+  isActive: false
+};
+
+export class LpCardNfviMetrics extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+  convertToArray(o){
+    let a = [];
+    Object.keys(o).map(function(k){
+      a.push(o[k]);
+    });
+    return a;
+  }
+  render() {
+    let mets = this.props.data;
+    let self = this;
+    let html = (
+      <div style={{overflow: 'hidden'}}>
+        <div className="launchpadCard_title">
+          NFVI-METRICS
+        </div>
+        <div className="metricBars">
+        { (mets && mets.length > 0 ) ? mets.map(function(m,i) {
+          return <MetricBarGroup key={i} index={i} title={m.title} lp_id={self.props.id} data={m.data.sort(function(a,b){return a.id > b.id})} />
+        }) : <div className="empty"> NO NFVI METRICS CONFIGURED</div>}
+        </div>
+      </div>
+    )
+    return html;
+  }
+}
+export class EpaParams extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+  render() {
+    let metrics =[];
+    let epa = this.props.data;
+    let count = 0;
+    for(let k in epa) {
+      let epaHTMLsub = [];
+      let epaHTML;
+      epaHTMLsub.push(buildParams(epa[k], count));
+      epaHTML = (
+        <li key={count + k}>
+          <h1>{k}</h1>
+          {
+            epaHTMLsub
+          }
+        </li>
+      );
+      metrics.push(epaHTML);
+      count++;
+    }
+    function buildParams(epa, index) {
+      let html = [];
+      let tCount = 0;
+      let checkForTotal = function checkForTotal(epa, html, i) {
+        for (let k in epa) {
+          if("total" in epa[k]) {
+            html.push(<dd key={"total" + tCount + k + i}>{k} : {epa[k].total} {(epa[k].total>1) ? 'vms' : 'vm'}</dd>)
+          } else {
+            html.push(<dt key={tCount + k + i}>{k}</dt>)
+            checkForTotal(epa[k], html, tCount)
+          }
+          tCount++;
+        }
+      }
+      checkForTotal(epa, html, index)
+      return (<dl key={"subTop-" + index}>{html}</dl>);
+    }
+    let display = (<ul>
+              {metrics}
+            </ul>)
+    // metrics = false;
+    if(metrics.length == 0) display = <div className="empty">NO EPA PARAMS CONFIGURED</div>
+    let html = (
+      <div style={{overflow: 'hidden'}}>
+        <div className="launchpadCard_title">
+          EPA-PARAMS
+        </div>
+        <div className={"launchpadCard_data-list" + ' ' + 'EPA-PARAMS'}>
+          {display}
+        </div>
+      </div>
+    )
+    return html;
+  }
+}
+
+
+export class NsrPrimitiveJobList extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+  render () {
+    let tree = null;
+    tree = this.props.jobs.sort(function(a,b){
+      return b['job-id'] > a['job-id'];
+    }).map(function(job, jindex) {
+          let nsrJobLabel = job['job-name'] ? job['job-name'] + ': ' + job['job-status'] : "NSR Job ID:" + job['job-id'] + ': ' + job['job-status']
+          return (
+              <TreeView key={jindex} nodeLabel={nsrJobLabel} className="nsrJob" defaultCollapsed={true}>
+                <h4>NSR Job Name: {job['job-name']}</h4>
+                <h4>NSR Job ID: {job['job-id']}</h4>
+                <h4>NSR Job Status: {job['job-status']}</h4>
+                  {job.vnfr ?
+                  <TreeView defaultCollapsed={true} className="vnfrJobs" nodeLabel="VNFR Jobs">
+                    {job.vnfr.map(function(v, vindex) {
+                      return (
+                        <TreeView key={vindex} nodeLabel="VNFR Job">
+                          <h5>VNFR ID: {v.id}</h5>
+                          <h5>VNFR Job Status: {v['vnf-job-status']}</h5>
+                            {v.primitive && v.primitive.map((p, pindex) => {
+                              return (
+                                <div key={pindex}>
+                                  <div>Name: {p.name}</div>
+                                  <div>Status: {p["execution-status"]}</div>
+                                </div>
+                              )
+                            })}
+                        </TreeView>
+                      )
+                    })}
+                  </TreeView>
+                  :null}
+              </TreeView>
+          )
+        });
+    let html = (
+      <div  className="nsConfigPrimitiveJobList">
+        <div className="launchpadCard_title">
+          JOB-LIST
+        </div>
+        <div className="listView">
+          <div>
+            {tree}
+          </div>
+        </div>
+      </div>
+    );
+    return html;
+  }
+}
+NsrPrimitiveJobList.defaultProps = {
+  jobs: []
+}
+
+export default LaunchpadCard
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadCardActions.js b/skyquake/plugins/launchpad/src/launchpad_card/launchpadCardActions.js
new file mode 100644 (file)
index 0000000..4666dd6
--- /dev/null
@@ -0,0 +1,20 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from '../alt';
+export default Alt.generateActions('updateControlInput');
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadCardCloudAccount.jsx b/skyquake/plugins/launchpad/src/launchpad_card/launchpadCardCloudAccount.jsx
new file mode 100644 (file)
index 0000000..1856dda
--- /dev/null
@@ -0,0 +1,60 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import Loader from 'widgets/loading-indicator/loadingIndicator.jsx';
+
+export default class LaunchpadCardCloudAccount extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  componentWillReceiveProps(nextProps) {
+
+  }
+  render() {
+    let html;
+    let isDisplayed = this.props.display;
+    let status = [];
+    if (this.props.nsr['cloud-account']) {
+      status.push(
+        (<li key="nsr"><h3>NSR: {this.props.nsr['cloud-account']}</h3></li>)
+      )
+    }
+    this.props.nsr['vnfrs'].map(function(v,i) {
+      if(v.hasOwnProperty('cloud-account')) {
+        status.push(
+          (<li key={i}><h3>VNFR {v['short-name']}: {v['cloud-account']}</h3></li>)
+        )
+      }
+    })
+    html = (
+          <ul>
+            {status}
+          </ul>
+      )
+    return (<div className={this.props.className + (isDisplayed ? '_open':'_close')}><h2>VIM Accounts</h2>{html}</div>);
+  }
+}
+
+LaunchpadCardCloudAccount.defaultProps = {
+  display: false,
+  nsr: {}
+}
+
+
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadCardMgmtInterfaces.jsx b/skyquake/plugins/launchpad/src/launchpad_card/launchpadCardMgmtInterfaces.jsx
new file mode 100644 (file)
index 0000000..782e99f
--- /dev/null
@@ -0,0 +1,108 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import React from 'react';
+import Loader from 'widgets/loading-indicator/loadingIndicator.jsx';
+
+export default class managementInterfaces extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  componentWillReceiveProps(nextProps) {
+
+  }
+  render() {
+    let dashboard_html;
+    let console_html;
+    let isDisplayed = this.props.display;
+    let status;
+    let applicationDashboards = this.props.interfaces.sort(function(a,b) {
+      try {
+            if ((a["short-name"] + '-' + a.id.substr(0,4)) > (b["short-name"] + '-' + b.id.substr(0,4))) {
+              return 1;
+            }
+      } catch(e) {
+        return 1;
+      }
+      return -1;
+    });
+
+    if(applicationDashboards.length > 0){
+      status = applicationDashboards.map(function(i, index) {
+        let mgmtLink = i["dashboard-url"] ? i["dashboard-url"] : 'None';
+          return (
+            <li key={index}><h3>{i["short-name"] + '-' + i.id.substr(0,4)}</h3><a href={i["dashboard-url"]} target="_blank">{mgmtLink}</a></li>
+          )
+        });
+    } else {
+      status = <li>No Application Dashboard Links have been specified.</li>
+    }
+    dashboard_html = (
+          <ul>
+            {status}
+          </ul>
+      );
+
+    let consoleLinks = this.props.consoleUrls && this.props.consoleUrls.sort(function(a,b) {
+      try {
+            if ((a["name"] + '-' + a.id.substr(0,4)) > (b["name"] + '-' + b.id.substr(0,4))) {
+              return 1;
+            }
+      } catch(e) {
+        return 1;
+      }
+      return -1;
+    });
+
+    if(consoleLinks && consoleLinks.length > 0){
+      status = consoleLinks.map(function(i, index) {
+        let consoleLink = i["console-url"] ? 'Open VM Console' : 'None';
+          return (
+            <li key={index}><h3>{i["name"] + '-' + i.id.substr(0,4)}</h3><a href={i["console-url"]} target="_blank">{consoleLink}</a></li>
+          )
+        });
+    } else {
+      status = <li>No VDU Console Links have been specified.</li>
+    }
+    console_html = (
+        <ul>
+          {status}
+        </ul>
+    );
+
+    return (
+      <div className={this.props.className + (isDisplayed ? '_open':'_close')}>
+        <h2>
+          Application Dashboard Links
+        </h2>
+        {dashboard_html}
+        <h2>
+          VM Console Links
+        </h2>
+        {console_html}
+      </div>);
+  }
+}
+
+managementInterfaces.defaultProps = {
+  display: false,
+  interfaces: []
+}
+
+
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadControls.jsx b/skyquake/plugins/launchpad/src/launchpad_card/launchpadControls.jsx
new file mode 100644 (file)
index 0000000..2ad3ce9
--- /dev/null
@@ -0,0 +1,188 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import RWslider from 'widgets/input-range-slider/input-range-slider.jsx';
+import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
+import CardActions from './launchpadCardActions.js';
+
+let currentID, lastSelected;
+
+function isTabNode(node) {
+  return node.nodeName === 'LI' && node.getAttribute('role') === 'tab';
+}
+class launchpadControls extends React.Component {
+  constructor(props, context) {
+    super(props, context);
+    this.state = {
+      controlSets:  this.props.controlSets,
+      selectedIndex: 0,
+      currentId: 0
+    };
+    this.handleInputUpdate = this.handleInputUpdate.bind(this);
+    this.handleSelected = this.handleSelected.bind(this);
+    this.handleSameTab = this.handleSameTab.bind(this);
+  }
+  handleSelected(index,last) {
+      this.state.selectedIndex = index;
+  }
+  //If same Tab is clicked, default to empty tab contents
+  handleSameTab(e) {
+    var node = e.target.parentNode;
+    var isTab = isTabNode(node);
+    if(isTab) {
+       if(node.id == currentID) {
+        this.state.selectedIndex = 0;
+        currentID = null;
+        this.forceUpdate();
+      } else {
+        currentID = node.id
+      }
+    }
+  }
+  componentWillReceiveProps(nextProps) {
+    if((!this.state.controlSets && nextProps.controlSets) || this.state.controlSets && !nextProps.controlSets) {
+      this.state.controlSets = nextProps.controlSets;
+    };
+
+  }
+  shouldComponentUpdate(nextProps, nextState) {
+    // console.log(this.props, nextProps);
+    // console.log(this.state, nextState)
+    return true;
+  }
+  handleInputUpdate(gIndex, groupID, cIndex, options, value) {
+    this.state.controlSets[gIndex][groupID]['control-param'][cIndex].value = value;
+    CardActions.updateControlInput(options, value)
+  }
+  render() {
+    let self = this;
+    if(!this.state.controlSets) {
+      return (<div></div>)
+    } else {
+      return (
+        <div className="launchpadCard_controls" onClick={self.handleSameTab}>
+        {
+          this.state.controlSets.map(function(group, gIndex) {
+            for(let id in group) {
+              return (
+                <Tabs key={gIndex} selectedIndex={self.state.selectedIndex}  onSelect={self.handleSelected}>
+
+                  <TabList>
+                    <Tab>
+                      {
+                        group[id]['action-param'].map(function(action, aIndex) {
+                          return (
+                            <button key={aIndex} className="light small" title={action.name}>{action.name}</button>
+                          )
+                        })
+                      }
+                    </Tab>
+                    {
+                      group[id]['control-param'].map(function(control, cIndex) {
+                        return (
+                          <Tab key={cIndex}>
+                          <span  title={control.name}>
+                            {control.name} : {control.value || control["current-value"]} {control.units}
+                            </span>
+                          </Tab>
+                        )
+                      })
+                    }
+                  </TabList>
+                  <TabPanel actionplaceholder>
+                  </TabPanel>
+                  {
+                    group[id]['control-param'].map(function(control, cIndex) {
+                      return (
+                        <TabPanel key={cIndex}>
+                          <RWslider {...control} handleInputUpdate={self.handleInputUpdate.bind(self, gIndex, id, cIndex, {operation:control.operation,
+                            url:control.url
+                          })}/>
+                        </TabPanel>
+                      )
+                    })
+                  }
+                </Tabs>
+              )
+            }
+          })
+        }
+        </div>
+      )
+    }
+  }
+};
+
+export default launchpadControls;
+
+
+/**
+ *
+ *   grouping control-param {
+    list control-param {
+      description
+          "List of control parameters to manage and
+           update the running configuration of the VNF";
+      key id;
+
+      leaf id {
+        type string;
+      }
+
+      leaf name {
+        type string;
+      }
+
+      leaf description {
+        type string;
+      }
+
+      leaf group-tag {
+        description "A simple tag to group control parameters";
+        type string;
+      }
+
+      leaf min-value {
+        description
+            "Minimum value for the parameter";
+        type uint64;
+      }
+
+      leaf max-value {
+        description
+            "Maxium value for the parameter";
+        type uint64;
+      }
+
+      leaf step-value {
+        description
+            "Step value for the parameter";
+        type uint64;
+      }
+
+      leaf units {
+        type string;
+      }
+
+      leaf widget-type {
+        type manotypes:widget-type;
+      }
+    }
+  }
+ */
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadHeader.jsx b/skyquake/plugins/launchpad/src/launchpad_card/launchpadHeader.jsx
new file mode 100644 (file)
index 0000000..a310c27
--- /dev/null
@@ -0,0 +1,189 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import UpTime from 'widgets/uptime/uptime.jsx';
+import launchpadFleetStore from '../launchpadFleetStore.js';
+import launchpadFleetActions from '../launchpadFleetActions';
+import LaunchpadOperationalStatus from 'widgets/operational-status/launchpadOperationalStatus.jsx';
+import LaunchpadCardMgmtInterfaces from './launchpadCardMgmtInterfaces.jsx';
+import LaunchpadCardCloudAccount from './launchpadCardCloudAccount.jsx';
+import { Link } from 'react-router';
+
+class LaunchpadHeader extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {};
+    this.state.displayStatus = false;
+    this.state.isLoading = this.isLoading(props);
+    this.state.displayInterfacePanel = false;
+    this.state.displayCloudAccount = false;
+    this.state.failed = false;
+    this.deleteLaunchpad = this.deleteLaunchpad.bind(this);
+    this.openDashboard = this.openDashboard.bind(this);
+    this.openConsole = this.openConsole.bind(this);
+    this.setStatus = this.setStatus.bind(this);
+  }
+  componentWillReceiveProps(props) {
+    this.setState({
+      failed: (props['operational-status'] == 'failed' || props['config-status'] == 'failed')
+    })
+  }
+  //TODO Do not setState within nested component like this. Find a way to use props.
+  doneLoading = (failed) => {
+  this.setState({
+      isLoading: false
+    });
+  }
+  //TODO instead of calling the store method, an action should be emitted and the store should respond.
+  deleteLaunchpad(e) {
+    if (window.confirm("Preparing to delete "+ this.props.name + ".  Are you sure you want to delete this NSR?")) {
+      launchpadFleetStore.deleteNsrInstance(this.props.id);
+      launchpadFleetActions.deletingNSR(this.props.id);
+    }
+  }
+  isLoading(props) {
+      return !((props.nsr['operational-status'] == 'running'))
+  }
+  openDashboard(nsr_id) {
+    window.location.href = '//' + window.location.hostname + ':' + window.location.port + '/index.html' + window.location.search + window.location.hash + '/' + nsr_id + '/detail';
+    launchpadFleetStore.closeSocket();
+  }
+  openConsole() {
+    console.log('open console clicked');
+  }
+  setStatus() {
+    var status;
+    if(this.props.isActive) {
+      status = "DISABLED"
+    } else {
+      status = "ENABLED"
+    }
+    launchpadFleetStore.setNSRStatus(this.props.nsr["id"], status);
+  }
+  openInterfacePanel = () => {
+    this.setState({
+      displayStatus: false,
+      displayInterfacePanel: !this.state.displayInterfacePanel,
+      displayCloudAccount: false
+    })
+     // this.closeHeaderViews();
+  }
+  openStatus = () => {
+    this.setState({
+      displayInterfacePanel: false,
+      displayStatus: !this.state.displayStatus,
+      displayCloudAccount: false
+    });
+    // this.closeHeaderViews();
+  }
+  openCloudAccountPanel = () => {
+    let nsrCloudAccount = this.props.nsr['cloud-account'];
+    this.setState({
+      displayStatus: false,
+      displayInterfacePanel: false,
+      displayCloudAccount: !this.state.displayCloudAccount
+    })
+  }
+  render() {
+    let self = this;
+    let failed = this.state.failed || (this.props.nsr['operational-status'] == 'failed');
+    let nsrCreateTime = this.props.nsr['create-time'];
+    //let nsrUpDuration = (nsrCreateTime)
+    //  ? Math.floor((new Date() / 1000)) - nsrCreateTime
+    //  : null;
+    let isLoading =  failed || this.state.isLoading;
+    let toggleStatus = isLoading ? '' :
+      (
+        <h3 className="launchpadCard_header-link">
+          <a onClick={this.openStatus} title="Open History" className={self.state.displayStatus ? 'activeIcon' : 'inActiveIcon'}>
+            <span className="oi" data-glyph="clock" aria-hidden="true">
+            </span>
+          </a>
+        </h3>
+      );
+    let headerClassName = "launchpadCard_header";
+    // debugger;
+    headerClassName += (failed ? ' failed' : '');
+    let sdnpresent = this.props.nsr['sdn-account'] ? true: false;
+    return (
+      <header className={headerClassName}>
+        <div className={"launchpadCard_header-title " + (this.props.isActive ? '' : 'launchpadCard_header-title-off') + (failed ? ' failed' : '')} >
+            <h3 className="launchpadCard_header-link">
+              {
+                isLoading ?
+                            <a title="Open Viewport Dashboard" style={{cursor:'default'}}>
+                              {this.props.name}
+                            </a>
+                          : <Link to={{pathname: '/viewport', query: {id: this.props.nsr.id,
+                              sdnpresent: sdnpresent}}}
+                              title="Open Viewport Dashboard">
+                              {this.props.name}
+                              <span className="oi" data-glyph="external-link" aria-hidden="true"></span>
+                            </Link>
+              }
+            </h3>
+          <div className="launchpadCard_header-actions">
+            <h3>
+              {isLoading ?
+                this.props.nsr["operational-status"]
+                : this.props.nsr['config-status'] == 'configuring' ?
+                  'Configuring'
+                  : this.props.nsr['config-status'] == 'configured' ?
+                    'Active'
+                    :'Configuration Failed'}
+            </h3>
+            <h3 style={{display: isLoading ? 'none' : 'inherit'}}>
+                <UpTime initialTime={nsrCreateTime} run={true} />
+            </h3>
+            <h3 className="launchpadCard_header-link" style={{display: this.props.nsr['cloud-account'] ? 'inherit' : 'none'}}>
+              <a onClick={this.openCloudAccountPanel} title="VIM Account" className={self.state.displayCloudAccount ? 'activeIcon' : 'inActiveIcon'}>
+                <span className="oi" data-glyph="cloud" aria-hidden="true"></span>
+              </a>
+            </h3>
+            <h3 className="launchpadCard_header-link" style={{'display': !isLoading ? 'inherit' : 'none'}}>
+                <a onClick={this.openInterfacePanel} title="View Management Interfaces" className={self.state.displayInterfacePanel ? 'activeIcon' : 'inActiveIcon'}>
+                  <span className="oi" data-glyph="monitor" aria-hidden="true">
+                  </span>
+                </a>
+            </h3>
+            {toggleStatus}
+            <h3 className="launchpadCard_header-link" style={{display: 'inherit'}}>
+              <a onClick={this.deleteLaunchpad} title="Delete">
+                <span className="oi" data-glyph="trash" aria-hidden="true"></span>
+              </a>
+            </h3>
+          </div>
+        </div>
+        <div className="launchpadCard_header-status">
+        <LaunchpadOperationalStatus className="launchpadCard_header-operational-status" loading={isLoading} doneLoading={this.doneLoading} display={this.state.displayStatus} currentStatus={this.props.nsr["operational-status"]} status={this.props.nsr["rw-nsr:operational-events"]} />
+        <LaunchpadCardMgmtInterfaces display={self.state.displayInterfacePanel} interfaces={this.props.nsr["dashboard-urls"]} className="launchpadCard_header-vnfr_management-links"  consoleUrls={this.props.nsr['console-urls']}/>
+        <LaunchpadCardCloudAccount display={self.state.displayCloudAccount} nsr={this.props.nsr} className="launchpadCard_header-vnfr_management-links" />
+        </div>
+      </header>
+    )
+  }
+};
+LaunchpadHeader.propTypes = {
+  name: React.PropTypes.string
+ };
+LaunchpadHeader.defaultProps = {
+  name: 'Loading...Some Name'
+};
+
+export default LaunchpadHeader;
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpadNSInfo.jsx b/skyquake/plugins/launchpad/src/launchpad_card/launchpadNSInfo.jsx
new file mode 100644 (file)
index 0000000..16dd072
--- /dev/null
@@ -0,0 +1,109 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+//THIS SHOULD BE REMOVED ONCE EPA PARAMS ARE MOVED OVER
+
+import React from 'react';
+let ReactCSSTransitionGroup = require('react-addons-css-transition-group');
+class LaunchpadNSInfo extends React.Component {
+  constructor(props) {
+    super(props);
+    // this.state = {metrics: props.data};
+  }
+  render() {
+    let metricSet = [];
+    let toDisplay;
+    this.props.data.map((metric, index)=> {
+      if (metric.hasOwnProperty('label') && this.props.name != "NFVI-METRICS") {
+
+      let displayValue = '';
+      if (metric.hasOwnProperty('vm')) {
+        displayValue = metric.vm + ' ' + metric.unit;
+      }
+      if (metric.hasOwnProperty('active-vm')) {
+        displayValue = metric["active-vm"] + ' of ' + (parseInt(metric["active-vm"]) + parseInt(metric["inactive-vm"])) + ' Active';
+      }
+      if (metric.hasOwnProperty('used')) {
+        displayValue = metric.used.value + ' / ' + metric.total.value + metric.total.unit;
+      }
+
+         metricSet.push((
+            <li key={index}>
+              <dl>
+                <dt>{metric.label}:</dt>
+                <dd>{displayValue}</dd>
+              </dl>
+            </li>
+          ))
+      };
+      if(this.props.name == "NFVI-METRICS") {
+        toDisplay = <NfviMetricBars metrics={this.props.data} />
+      }
+    });
+        var infoClass = {
+      'EPA-PARAM' : {
+        height: '300px',
+        overflow: 'scroll',
+        width: '707px',
+      },
+      'NFVI-METRICS' : {
+        height: '400px'
+      }
+    }
+    // style={infoClass[this.props.name]}
+    if (!metricSet.length) {
+      let msgString = ''
+
+      //DEMO ONLY
+      if(this.props.name == "NFVI-METRICS") {
+        toDisplay = <NfviMetricBars metrics={this.props.data} />
+      } else {
+        toDisplay = (<div className="empty">{ msgString }</div>);
+      }
+    } else {
+      toDisplay = (
+        <ul >
+          {
+            metricSet
+          }
+        </ul>
+      )
+    }
+
+    return (
+      <div style={{overflow: 'hidden'}}>
+        <div className="launchpadCard_title">
+          { this.props.name }
+        </div>
+        <div className={"launchpadCard_data-list" + ' ' + this.props.name}>
+          { toDisplay }
+        </div>
+      </div>
+    )
+  }
+}
+LaunchpadNSInfo.propTypes = {
+  data: React.PropTypes.array,
+  name: React.PropTypes.string
+ };
+LaunchpadNSInfo.defaultProps = {
+  name: 'Loading...',
+  data: []
+};
+
+export default LaunchpadNSInfo;
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/launchpad_card.scss b/skyquake/plugins/launchpad/src/launchpad_card/launchpad_card.scss
new file mode 100644 (file)
index 0000000..1c77c61
--- /dev/null
@@ -0,0 +1,362 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'style/_colors.scss';
+@import '../../node_modules/open-iconic/font/css/open-iconic.css';
+.launchpadCard {
+  display:flex;
+  margin-top: 0.75rem;
+  &-body{
+    position: relative;
+  }
+  .deletingIndicator {
+    display: flex;
+    flex:1;
+    align-items: center;
+    justify-content: center;
+  }
+  &_launch {
+    display:flex;
+    flex-direction:column;
+    flex: 1;
+    justify-content: center;
+    align-items: center;
+    img {
+      width: 88px;
+      padding:1rem;
+    }
+  }
+  &_header {
+    color:white;
+    padding-right: 1rem;
+    min-width: 693px;
+    max-width: 693px;
+    &-link, a {
+      display:flex;
+      align-items:center;
+      text-decoration: none;
+      color: inherit;
+    }
+    &-link {
+      margin-left:0.5rem;
+      cursor:pointer;
+    }
+    .oi {
+      margin:0 0 -0.25rem 0.5rem;
+    }
+    &-title {
+      display: flex;
+      line-height: 3rem;
+      background-color: $brand-green-light;
+      //background-color: $primary-header;
+      position: relative;
+      flex-direction: row;
+      align-items: center;
+      justify-content: flex-start;
+      padding-right:1rem;
+      &-off {
+        background-color:white;
+        color:black;
+      }
+    }
+        .activeIcon{
+          color: #dadada;
+          position:relative;
+        span:after{
+          content: '\25b2';
+          color:#dadada;
+          width:0.5rem;
+          height:0.5rem;
+          position: absolute;
+          top: 17px;
+          left: 8px;
+        }
+      }
+      .inActiveIcon {
+        color:white;
+        position:relative;
+      }
+    &-actions {
+      flex: 1;
+      display: flex;
+      justify-content: flex-end;
+      padding-right: 1rem;
+      h3{
+        padding-right:0.25rem;
+        text-transform: capitalize;
+      }
+
+    }
+    &-status {
+      background-color: $brand-green;
+      &-current {
+        display:flex;
+        justify-content:space-between;
+        padding: 0.5rem 0;
+        span,a {
+          padding: 0 0.25rem;
+        }
+        a{
+          cursor:pointer;
+          &:hover {
+            text-decoration:underline;
+          }
+        }
+      }
+    }
+    &-operational-status {
+      &_loading {
+        display:flex;
+        flex-direction:column;
+        justify-content: center;
+        justify-content: center;
+        align-items: center;
+        color:$gray-darkest;
+     }
+     &_open {
+        overflow: hidden;
+        background: #ddd;
+        height: 100%;
+        visibility: visible;
+        opacity: 1;
+        position: absolute;
+        width: 100%;
+        z-index: 99;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        align-content: center;
+        color: black;
+        h2{
+              padding: 2rem;
+        }
+        ul,li {
+          margin:0.25rem 1rem 0 0.825rem;
+          list-style-type:disc;
+          color:black;
+        }
+        ul {
+          overflow: auto;
+          padding-left: 0.5rem;
+          padding-right: 1rem;
+          margin-right: 0.5rem;
+          height: inherit;
+
+          ul {
+            li {
+              list-style-type: circle;
+            }
+          }
+        }
+      }
+      &_close {
+        height: 0;
+        visibility:hidden;
+        opacity:0;
+      }
+    }
+    &-vnfr_management-links {
+
+      &_loading {
+        display:flex;
+        flex-direction:column;
+        justify-content: center;
+        align-items: center;
+        color:$gray-darkest;
+     }
+      &_open {
+        overflow:hidden;
+        background: #ddd;
+        height: 100%;
+        visibility:visible;
+        opacity:1;
+        position:absolute;
+        width:100%;
+        z-index: 99;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        align-content: center;
+        color:black;
+        a {
+          cursor: pointer;
+          margin-left: 0.5rem;
+          font-weight: normal;
+          color: black;
+        }
+        h2 {
+          padding:2rem;
+        }
+        ul,li {
+          margin:0.25rem 1rem 0 0.825rem;
+          list-style-type:disc;
+          color:black;
+        }
+        ul {
+          width:90%;
+          overflow: auto;
+          padding-right: 1rem;
+          margin-right: 0.5rem;
+          height: inherit;
+        }
+        li {
+          justify-content: space-between;
+          display: flex;
+        }
+      }
+      &_close {
+        height: 0;
+        visibility:hidden;
+        opacity:0;
+      }
+    }
+    .failed {
+      background-color:white;
+      color:black;
+      a {
+        color:black !important;
+      }
+    }
+  }
+
+  &_content {
+    .launchpadCard_content {
+      overflow-x: hidden;
+      overflow-y: scroll;
+    }
+    .empty {
+      min-height:50px;
+      max-width: 100%;
+      display:flex;
+      justify-content: center;
+      align-items: center;
+    }
+  }
+  &_title {
+      color:$black;
+      background:$secondary-header;
+      padding: 0.5rem;
+      // margin: 0 0 0.5rem 0;
+      // border-top:1px solid #666;
+      // border-bottom:1px solid #666;
+      border-top:1px solid #f1f1f1;
+      border-bottom:1px solid #f1f1f1;
+  }
+
+  &_data-list {
+    ul, dl{
+      display:flex;
+      flex-direction:row;
+      flex-wrap:wrap;
+      align-items:flex-start;
+       font-size: 0.825rem;
+      li{
+        flex:1 1 30%;
+      }
+    }
+    dl {
+      margin: 0.5rem 0 0.5rem 0;
+      dt{
+        margin: 0 0 0 0.5rem;
+        text-transform:uppercase;
+      }
+      dd{
+        margin: 0 0 0 0.5rem;
+      }
+    }
+    &.CONFIG-PRIMITIVES {
+      height: 400px;
+      overflow-y: scroll;
+      h1 {
+        margin: 0 0 0 0.5rem;
+      }
+      > div {
+        overflow: hidden;
+      }
+    }
+  }
+  &_data-list.EPA-PARAMS {
+      // height: 105px;
+      width: 715px;
+      overflow-y: scroll;
+      h1 {
+        margin: 0 0 0 0.5rem;
+      }
+      > div {
+        overflow: hidden;
+      }
+  }
+  &_controls{
+    display:flex;
+    flex-direction:row;
+    .react-tabs {
+      flex: auto;
+    [role=tab][aria-selected=true] {
+      background:none;
+      border:none;
+      color: rgb(85, 26, 139);
+    }
+    [role=tab]{
+      text-decoration:underline;
+      border:none;
+      &:focus{
+        outline:none;
+        box-shadow:none;
+        border:none;
+        &:after {
+           background:none;
+           border:none;
+      }
+    }
+
+  }
+    [role=tablist] {
+      border:none;
+      margin: 0 0 10px;
+      padding: 0;
+      display: flex;
+      justify-content: flex-end;
+
+         [role=tab]:first-child {
+            flex: 1;
+         }
+    }
+
+    }
+
+  }
+  .slick-initialized.slick-slider {
+    // min-height:200px;
+  }
+
+  .close-btn {
+    position: absolute;
+    top: -8px;
+    right: -8px;
+    z-index: 100;
+    cursor: pointer;
+    img {
+      width: 1.25rem;
+      height: 1.25rem;
+      background-color: white;
+      border-radius: 15px;
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/nsConfigPrimitives.scss b/skyquake/plugins/launchpad/src/launchpad_card/nsConfigPrimitives.scss
new file mode 100644 (file)
index 0000000..dfc2744
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'style/_colors.scss';
+@mixin optional() {
+    /* height: 1.25rem;*/
+    /* margin-left: 0.5rem;*/
+    /* margin-top: 0.5rem;*/
+    -ms-flex: 0 1 auto;
+        flex: 0 1 auto;
+}
+.nsConfigPrimitiveContainer {
+    -ms-flex: 1 0 100%;
+        flex: 1 0 100%;
+        .scrollContainer {
+            overflow-y:auto;
+        }
+}
+.nsConfigPrimitives {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex: 1 1 100%;
+        flex: 1 1 100%;
+    -ms-flex-direction: column;
+        flex-direction: column;
+    background: white;
+    .launchpadCard_title {
+        -ms-flex: 0 1 auto;
+            flex: 0 1 auto;
+        min-height: 1rem;
+    }
+    .configuring {
+        pointer-events: none;
+        opacity: 0.3;
+    }
+    .nsConfigPrimitiveTabs {
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex:1 1 auto;
+            flex:1 1 auto;
+        -ms-flex-direction:column;
+            flex-direction:column;
+            h4{
+                padding-bottom: 0.25rem;
+            }
+    }
+    .react-tabs {
+        display: -ms-flexbox;
+        display: flex;
+        -ms-flex: 1 0 auto;
+            flex: 1 0 auto;
+
+        [role=tablist] {
+            border: 0px;
+            margin: 0px;
+            padding-top: 1rem;
+            display: -ms-flexbox;
+            display: flex;
+            -ms-flex: 1 1 40%;
+                flex: 1 1 40%;
+            -ms-flex-direction: column;
+                flex-direction: column;
+            background-color: rgb(221, 221, 221);
+
+            [role=tab] {
+                padding: 1rem;
+            }
+            [role=tab]:hover {
+                background-color: #7e9bc1;
+            }
+            [role=tab][aria-selected=true] {
+                border: 0px;
+                border-radius: 0px;
+                position: relative;
+
+                &:before {
+                    display: block;
+                    position: absolute;
+                    content: ' ';
+                    top: -.125rem;
+                    left: 0rem;
+                    width: 100%;
+                    border-top: 1px dashed #00acee;
+                }
+                &:after {
+                    display: block;
+                    position: absolute;
+                    content: ' ';
+                    bottom: -.125rem;
+                    left: 0rem;
+                    width: 100%;
+                    border-bottom: 1px dashed #00acee;
+                }
+            }
+            [role=tab]:focus {
+                box-shadow: none;
+                border: 0px;
+            }
+            [role=tab]:focus:after {
+                display: none;
+            }
+        }
+        [role=tabpanel] {
+            -ms-flex: 1 1 auto;
+                flex: 1 1 auto;
+            margin-top: 1rem;
+            padding: 1rem;
+            display: -ms-flexbox;
+            display: flex;
+            -ms-flex-direction: column;
+                flex-direction: column;
+            -ms-flex-pack: start;
+                justify-content: flex-start;
+            h2 {
+                padding-bottom: 0.5rem;
+            }
+            h3 {
+                padding: 0.5rem;
+                margin-left: 1rem;
+                font-weight: bold;
+            }
+            .noticeSubText {
+                padding-bottom:0.5rem;
+                color:$darker-gray;
+                font-size:0.75rem;
+                &_right {
+                    text-align:right;
+                }
+            }
+            .parameterGroup {
+                /* margin-left: 2rem;*/
+                >li {
+                }
+                label {
+                    &[data-required="true"] span:after {
+                        content: '*';
+                    }
+                    &.disabled {
+                    }
+                    input {
+                        &[disabled] {
+                            background:#ccc;
+                        }
+                    }
+                    .optional {
+                        @include optional();
+                    }
+                    span {
+                        font-weight: bolder;
+                    }
+                    .readonly {
+                        -ms-flex: 0 0 30%;
+                            flex: 0 0 30%;
+                        height: 1.25rem;
+                        margin: 0.125rem 0 0.5rem 0;
+                    }
+                }
+            }
+            .nsConfigPrimitiveParameterGroupParameters {
+                position:relative;
+                margin-bottom:2.5rem;
+                div {
+                    display:-ms-flexbox;
+                    display:flex;
+                    -ms-flex-direction:column;
+                        flex-direction:column;
+                }
+                .configGroupOverlay {
+                    background: #ccc;
+                    position: absolute;
+                    width: 100%;
+                    height: 100%;
+                    opacity: 0.5;
+                }
+                &:after {
+                }
+                ul {
+                    width:100%;
+                }
+            }
+            .nsConfigPrimitiveParameters {
+
+                label {
+                    &[data-required="true"] span:after {
+                        content: '*';
+                    }
+                    .optional {
+                        @include optional();
+                    }
+                }
+                ul {
+                    width:100%;
+                }
+            }
+            .inputGroup{
+                display:-ms-flexbox;
+                display:flex;
+                -ms-flex:1 1 auto;
+                    flex:1 1 auto;
+                -ms-flex-align:center;
+                    align-items:center;
+            }
+        }
+        button {
+            margin-top: 0.5rem;
+        }
+    }
+}
+.nsConfigPrimitiveJobList {
+            -ms-flex: 1 1 80%;
+                flex: 1 1 80%;
+
+    .listView {
+        padding: 0.1rem;
+        overflow-y: auto;
+
+        >div>div {
+            margin:0.5rem;
+            >.tree-view_item {
+                padding: 1rem;
+            }
+            &:nth-child(odd) {
+                background:white;
+            }
+        }
+
+        .tree-view_children {
+            margin-left: 2rem;
+        }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/nsrConfigPrimitives.jsx b/skyquake/plugins/launchpad/src/launchpad_card/nsrConfigPrimitives.jsx
new file mode 100644 (file)
index 0000000..b44b3d9
--- /dev/null
@@ -0,0 +1,371 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
+import RecordViewStore from '../recordViewer/recordViewStore.js';
+import Button from 'widgets/button/rw.button.js';
+import './nsConfigPrimitives.scss';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+
+class NsrConfigPrimitives extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.vnfrMap = null;
+        this.state.nsConfigPrimitives = null;
+    }
+
+    componentWillReceiveProps(props) {
+        let vnfrs = props.data['vnfrs'];
+        let vnfrMap = {};
+        let nsConfigPrimitives = [];
+        let vnfList = [];
+        if (vnfrs &&  !this.state.nsConfigPrimitives) {
+            vnfrs.map((vnfr) => {
+                let vnfrConfigPrimitive = {};
+                vnfrConfigPrimitive.name = vnfr['short-name'];
+                vnfrConfigPrimitive['vnfr-id-ref'] = vnfr['id'];
+                //input references
+                let configPrimitives = vnfr['vnf-configuration']['service-primitive'];
+                //input references by key
+                let vnfrConfigPrimitives = {}
+
+                if (configPrimitives) {
+                    let vnfPrimitiveList = [];
+                    configPrimitives.map((configPrimitive) => {
+                        vnfrConfigPrimitives[configPrimitive.name] = configPrimitive;
+                        vnfPrimitiveList.push({
+                            name: configPrimitive.name,
+                            parameter: configPrimitive.parameter
+                        })
+                    });
+                    vnfrConfigPrimitive['service-primitives'] = vnfrConfigPrimitives;
+                    vnfrMap[vnfr['member-vnf-index-ref']] = vnfrConfigPrimitive;
+                }
+            });
+            //nsr service-primitives
+            props.data['service-primitive'] && props.data['service-primitive'].map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
+                 //Add optional field to group. Necessary for driving state.
+                let optionalizedNsConfigPrimitiveGroup = nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup)=>{
+                    if(parameterGroup && parameterGroup.mandatory != "true") {
+                        parameterGroup.optionalChecked = true;
+                    };
+                    return parameterGroup;
+                });
+                let nscp = {
+                    name: nsConfigPrimitive.name,
+                    'nsr_id_ref': props.data.id,
+                    'parameter': nsConfigPrimitive.parameter,
+                    'parameter-group': optionalizedNsConfigPrimitiveGroup,
+                    'vnf-primitive-group':[]
+                }
+
+                nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfPrimitiveGroup, vnfPrimitiveGroupIndex) => {
+                    let vnfMap = vnfrMap[vnfPrimitiveGroup['member-vnf-index-ref']];
+                    let vnfGroup = {};
+                    vnfGroup.name = vnfMap.name;
+                    vnfGroup['member-vnf-index-ref'] = vnfPrimitiveGroup['member-vnf-index-ref'];
+                    vnfGroup['vnfr-id-ref'] = vnfMap['vnfr-id-ref'];
+                    vnfGroup.inputs = [];
+                    vnfPrimitiveGroup.primitive.map((primitive, primitiveIndex) => {
+                        console.log(primitive);
+                        primitive.index = primitiveIndex;
+                        primitive.parameter = [];
+                        vnfMap['service-primitives'][primitive.name].parameter.map(function(p) {
+                            p.index = primitiveIndex;
+                            let paramCopy = p;
+                            paramCopy.value = undefined;
+                            primitive.parameter.push(paramCopy);
+                        });
+                        vnfGroup.inputs.push(primitive);
+                    });
+                    nscp['vnf-primitive-group'].push(vnfGroup);
+                });
+                nsConfigPrimitives.push(nscp);
+            });
+            this.setState({
+                vnfrMap: vnfrMap,
+                data: props.data,
+                nsConfigPrimitives: nsConfigPrimitives
+            });
+        }
+    }
+
+    handleParamChange = (parameterIndex, vnfPrimitiveIndex, vnfListIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['vnf-primitive-group'][vnfListIndex]['inputs'][vnfPrimitiveIndex]['parameter'][parameterIndex]['value'] = event.target.value;
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+
+    handleNsParamChange = (parameterIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter'][parameterIndex]['value'] = event.target.value;
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+
+    handleNsParamGroupParamChange = (parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex]['parameter'][parameterIndex]['value'] = event.target.value;
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+
+    handleExecuteClick = (nsConfigPrimitiveIndex, event) => {
+        var isValid = RecordViewStore.validateInputs({
+            nsConfigPrimitives: this.state.nsConfigPrimitives,
+            nsConfigPrimitiveIndex: nsConfigPrimitiveIndex
+        });
+        if(isValid) {
+            RecordViewStore.constructAndTriggerNsConfigPrimitive({
+                nsConfigPrimitives: this.state.nsConfigPrimitives,
+                nsConfigPrimitiveIndex: nsConfigPrimitiveIndex
+             });
+            //Need a better way to reset
+            //Reset disabled per TEF request
+            // this.setState({
+            //     nsConfigPrimitives: null
+            // })
+        } else {
+                this.props.actions.showNotification('Could not execute service config. Please review your parameters');
+        }
+    }
+    handleOptionalCheck = (parameterGroupIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        let optionalChecked = nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex].optionalChecked;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex].optionalChecked = !optionalChecked;
+        console.log(nsConfigPrimitives)
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+    constructConfigPrimitiveTabs = (tabList, tabPanels) => {
+        let self = this;
+        let defaultFromRpc = '';
+        //coded here for dev purposes
+        let mandatoryFieldValue = 'true';
+        if (self.state.vnfrMap) {
+            this.state.nsConfigPrimitives && this.state.nsConfigPrimitives.map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
+                tabList.push(
+                    <Tab key={nsConfigPrimitiveIndex}>{nsConfigPrimitive.name}</Tab>
+                );
+                tabPanels.push(
+                    (
+                        <TabPanel key={nsConfigPrimitiveIndex + '-panel'}>
+                            <h4>{nsConfigPrimitive.name}</h4>
+                            <div className="noticeSubText noticeSubText_right">
+                                * required
+                            </div>
+                            {nsConfigPrimitive['parameter'] && nsConfigPrimitive['parameter'].map((parameter, parameterIndex) => {
+                                let optionalField = '';
+                                let displayField = '';
+                                                               let defaultValue = parameter['default-value'] || '';
+                                let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
+                                let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
+                                if (parameter.mandatory == mandatoryFieldValue) {
+                                    optionalField = <span className="required">*</span>
+                                }
+                                if (isFieldReadOnly) {
+                                    displayField = (
+                                        <label data-required={(parameter.mandatory == mandatoryFieldValue)}>
+                                            {parameter.name}
+                                            <div className='readonly'>
+                                                {parameter.value || defaultValue}
+                                            </div>
+                                        </label>
+                                    )
+                                } else {
+                                    displayField = <TextInput label={parameter.name} required={(parameter.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamChange.bind(this, parameterIndex, nsConfigPrimitiveIndex)} />;
+                                }
+                                return (
+                                    <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
+                                        <ul>
+                                        {
+                                            <li key={parameterIndex} className="">
+                                                    {displayField}
+                                            </li>
+                                        }
+                                        </ul>
+                                    </div>
+                                )
+                            })}
+                            {nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup, parameterGroupIndex) => {
+                                let optionalField = '';
+                                let overlayGroup = null;
+                                let isOptionalGroup = parameterGroup.mandatory != mandatoryFieldValue;
+                                let optionalChecked = parameterGroup.optionalChecked;
+                                let inputIsDiabled = (!optionalChecked && isOptionalGroup);
+                                if (isOptionalGroup) {
+                                    optionalField = <input type="checkbox" name="" checked={optionalChecked} onChange={self.handleOptionalCheck.bind(null, parameterGroupIndex, nsConfigPrimitiveIndex)} />;
+                                    // overlayGroup = <div className="configGroupOverlay"></div>
+                                }
+                                return (
+                                    <div key={parameterGroupIndex} className="nsConfigPrimitiveParameterGroupParameters">
+                                    <h2>{parameterGroup.name} {optionalField}</h2>
+                                    <div className="parameterGroup">
+                                        {overlayGroup}
+                                        <ul className="">
+                                                <li className="">
+
+                                                    {parameterGroup['parameter'] && parameterGroup['parameter'].map((parameter, parameterIndex) => {
+                                                        let optionalField = '';
+                                                        let displayField = '';
+                                                        let defaultValue = parameter['default-value'] || '';
+                                                        let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
+                                                        let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
+                                                        if (parameter.mandatory == mandatoryFieldValue) {
+                                                            optionalField = <span className="required">*</span>
+                                                        }
+                                                        if (isFieldReadOnly) {
+                                                            displayField = <div className='readonly'>{parameter.value || defaultValue}</div>
+                                                        } else {
+                                                            displayField = <input required={(parameter.mandatory == mandatoryFieldValue)} className="" disabled={inputIsDiabled} type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamGroupParamChange.bind(this, parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex)} />
+                                                        }
+                                                        if (parameter.mandatory == mandatoryFieldValue) {
+                                                            optionalField = <span className="required">*</span>
+                                                        }
+                                                        return (
+                                                            <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
+                                                                <ul>
+                                                                {
+                                                                    <li key={parameterIndex} className="">
+                                                                        <label className={inputIsDiabled && 'disabled'} data-required={(parameter.mandatory == mandatoryFieldValue)}>
+                                                                            {parameter.name}
+                                                                            {displayField}
+                                                                        </label>
+
+                                                                    </li>
+                                                                }
+                                                                </ul>
+                                                            </div>
+                                                        )
+                                                    })}
+                                                </li>
+                                            </ul>
+                                        </div>
+                                    </div>
+                                );
+                            })}
+                            {nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfGroup, vnfGroupIndex) => {
+                                return (
+                                    <div key={vnfGroupIndex} className="vnfParamGroup">
+                                        <h2>{vnfGroup.name}</h2>
+
+                                            {vnfGroup.inputs.map((inputGroup, inputGroupIndex) => {
+                                                return (
+                                                    <div key={inputGroupIndex}>
+                                                        <h3>{inputGroup.name}</h3>
+                                                        <ul className="parameterGroup">
+                                                        {
+                                                            inputGroup.parameter.map((input, inputIndex) => {
+                                                                let optionalField = '';
+                                                                let displayField = '';
+                                                                                                                               let defaultValue = input['default-value'] || '';
+                                                                let isFieldHidden = (input['hidden'] && input['hidden'] == 'true') || false;
+                                                                let isFieldReadOnly = (input['read-only'] && input['read-only'] == 'true') || false;
+                                                                if (input.mandatory == mandatoryFieldValue) {
+                                                                    optionalField = <span className="required">*</span>
+                                                                }
+                                                                if (isFieldReadOnly) {
+                                                                    displayField = <div className='readonly'>{input.value || defaultValue}</div>
+                                                                } else {
+                                                                    displayField = <TextInput label={input.name} type="text" required={(input.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={input.value} onChange={this.handleParamChange.bind(this, inputIndex, inputGroupIndex, vnfGroupIndex, nsConfigPrimitiveIndex)}/>
+                                                                }
+                                                                return (
+                                                                    <li key={inputIndex} style={{display: isFieldHidden ? 'none':'inherit'}}>
+                                                                        {displayField}
+                                                                    </li>
+                                                                )
+                                                            })
+                                                        }
+                                                        </ul>
+                                                    </div>
+                                                )
+                                            })}
+
+                                    </div>
+                                )
+                            })}
+                            <Button label="Submit" isLoading={this.state.isSaving} onClick={this.handleExecuteClick.bind(this, nsConfigPrimitiveIndex)} className="dark"/>
+                        </TabPanel>
+                    )
+                );
+            });
+        }
+    }
+
+    handleSelect = (index, last) => {
+        // console.log('Selected tab is', index, 'last index is', last);
+    }
+    render() {
+
+        let tabList = [];
+        let tabPanels = [];
+        let isConfiguring = (this.props.data['config-status'] && this.props.data['config-status'] != 'configured') || false;
+        let displayConfigStatus = isConfiguring ? '(Disabled - Configuring)': '';
+
+        this.constructConfigPrimitiveTabs(tabList, tabPanels);
+
+        return (
+            <div className="nsConfigPrimitives">
+                <div className="launchpadCard_title">
+                  SERVICE-PRIMITIVES {displayConfigStatus}
+                </div>
+                <div className={isConfiguring ? 'configuring': '' + 'nsConfigPrimitiveTabs'}>
+                    <Tabs onSelect={this.handleSelect}>
+                        <TabList>
+                            {tabList}
+                        </TabList>
+                        {tabPanels}
+                    </Tabs>
+                </div>
+            </div>
+
+        );
+    }
+}
+
+
+function deepCopy (toCopy, copyObj) {
+    for (let k in toCopy) {
+        switch (toCopy[k].constructor.name) {
+            case "String":
+                copyObj[k] = toCopy[k];
+                break;
+            case "Array":
+                copyObj[k] = [];
+                toCopy[k].map((v) => {
+                    copyObj[k].push(v)
+                });
+                break;
+            case "Object":
+                deepCopy(toCopy[k], copyObj[k]);
+                break;
+            default:
+                copyObj[k] = toCopy[k]
+        }
+    }
+    return copyObj;
+}
+export default SkyquakeComponent(NsrConfigPrimitives);
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/nsrScalingGroups.jsx b/skyquake/plugins/launchpad/src/launchpad_card/nsrScalingGroups.jsx
new file mode 100644 (file)
index 0000000..b6abf5c
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import RecordViewStore from '../recordViewer/recordViewStore.js';
+import Button from 'widgets/button/rw.button.js';
+import Utils from 'utils/utils.js';
+import _ from 'underscore';
+import UpTime from 'widgets/uptime/uptime.jsx';
+import './nsrScalingGroups.scss';
+
+export default class NsrScalingGroups extends React.Component {
+       constructor(props) {
+               super(props);
+               this.state = {};
+       }
+
+       handleExecuteClick = (nsr_id, scaling_group_id, event) => {
+               RecordViewStore.createScalingGroupInstance({
+                       nsr_id: nsr_id,
+                       scaling_group_id: scaling_group_id
+               });
+       }
+
+       handleDeleteClick = (nsr_id, scaling_group_id, scaling_instance_index, event) => {
+               RecordViewStore.deleteScalingGroupInstance({
+                       nsr_id: nsr_id,
+                       scaling_group_id: scaling_group_id,
+                       scaling_instance_index: scaling_instance_index
+               });
+       }
+
+       createScalingGroupTable = (scalingGroupDesriptorName) => {
+               let trows = [];
+
+               this.props.data['scaling-group-record'] && this.props.data['scaling-group-record'].map((sgr, sgri) => {
+
+                       sgr['instance'] ? sgr['instance'].map((sgrInstance, sgrInstanceIndex) => {
+                               let id = sgrInstance['instance-id'];
+                               let sgrName = sgr['scaling-group-name-ref'];
+
+                               if (sgrName == scalingGroupDesriptorName) {
+                                       trows.push(
+                                               <tr key={sgrInstanceIndex}>
+                                                       <td>{sgrInstanceIndex + 1}</td>
+                                                       <td>{id}</td>
+                                                       <td><UpTime initialTime={sgrInstance['create-time']} run={true} /></td>
+                                                       <td>{sgrInstance['op-status']}</td>
+                                                       <td>
+                                                               {sgrInstance['is-default'] == 'false' ? <a onClick={this.handleDeleteClick.bind(this, this.props.data.id, sgrName, id)} title="Delete">
+                                                       <span className="oi" data-glyph="trash" aria-hidden="true"></span>
+                                               </a> : null}
+                                                       </td>
+                                               </tr>
+                                       );
+                               }
+                       }) : trows.push(
+                               <tr key={sgrInstanceIndex}>
+                                       <td colSpan="5" style={{textAlign: 'center'}}>No network services scaled in this group</td>
+                               </tr>
+                       );
+               });
+
+               let tbody = (
+                       <tbody>
+                       {trows}
+                   </tbody>
+               );
+
+               return (
+                       <table className="scalingGroupsInstancesTable">
+                           <thead>
+                               <tr>
+                                       <th style={{width: '6%'}}></th>
+                                   <th style={{width: '12%'}}>ID</th>
+                                   <th style={{width: '37%'}}>Uptime</th>
+                                   <th style={{width: '37%'}}>Status</th>
+                                   <th style={{width: '7%'}}> </th>
+                               </tr>
+                           </thead>
+                           {tbody}
+                       </table>
+               );
+       }
+
+       getInstancesForScalingGroup = (scalingGroupDesriptorName) => {
+               let count = 0;
+               this.props.data['scaling-group-record'] && this.props.data['scaling-group-record'].map((sgr, sgri) => {
+                       sgr['instance'] && sgr['instance'].map((sgrInstance, sgrInstanceIndex) => {
+                               if (sgr['scaling-group-name-ref'] == scalingGroupDesriptorName) {
+                                       count++;
+                               }
+                       });
+               });
+
+               return count;
+       }
+
+       render() {
+               let scalingGroups = [];
+
+               this.props.data['scaling-group-descriptor'] && this.props.data['scaling-group-descriptor'].map((sgd) => {
+                       let sgvnfs = [];
+                       let sgMaxCount = (
+                               <span>
+                                       <span>Max: </span>
+                                       <span>{sgd['max-instance-count']}</span>
+                               </span>
+                       );
+
+                       sgd['vnfd-member'] && sgd['vnfd-member'].map((vnf) => {
+                               let instanceCount = vnf['count'];
+                               sgvnfs.push(
+                                       <span>{vnf['short-name']} {instanceCount > 1 ? '(' + instanceCount + ')': ''}</span>
+                               );
+                       });
+
+                       sgvnfs = Utils.arrayIntersperse(sgvnfs, ', ');
+
+                       let sgInstanceTable = this.createScalingGroupTable(sgd.name);
+
+                       let sgCreateInstanceButton = <Button label='Create Scaling Group Instance' className="dark" isDisabled={this.getInstancesForScalingGroup(sgd.name) == sgd["max-instance-count"]} isLoading={false} onClick={this.handleExecuteClick.bind(this, this.props.data.id, sgd.name)} />
+
+                       let scalingGroup =
+                               <div>
+                                       <div className='launchpadCard_title' style={{textAlign:'right'}}><span style={{float:'left'}}>{sgd.name}</span></div>
+                                       <div className='vnfsList'><span className='vnfsLabel'>VNFS: </span><span>{sgvnfs}</span></div>
+                                       <div className='scalingGroupsInstancesTableWrapper'>
+                                               {sgInstanceTable}
+                                       </div>
+                                       {sgCreateInstanceButton} {sgMaxCount}
+                               </div>
+
+                       scalingGroups.push(scalingGroup);
+               });
+
+               return (
+                       <div className='nsScalingGroups'>
+                <div className=''>
+                       {scalingGroups}
+                </div>
+            </div>
+               );
+       }
+
+}
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/nsrScalingGroups.scss b/skyquake/plugins/launchpad/src/launchpad_card/nsrScalingGroups.scss
new file mode 100644 (file)
index 0000000..fff43b5
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@import "style/_colors.scss";
+
+@mixin optional() {
+    // height: 1.25rem;
+    // margin-left: 0.5rem;
+    // margin-top: 0.5rem;
+    flex: 0 1 auto;
+}
+.nsScalingGroupContainer {
+    flex: 1 0 100%;
+}
+.nsScalingGroups {
+    display: flex;
+    flex: 1 1 100%;
+    flex-direction: column;
+
+    .vnfsList {
+        padding: 1rem;
+        .vnfsLabel {
+            opacity: 0.5;
+        }    
+    }
+
+    .scalingGroupsInstancesTableWrapper {
+        padding: 1rem;
+
+        .scalingGroupsInstancesTable {
+            background: white;
+            width: 693px;
+            border-collapse: collapse;
+            border: 1px solid black;
+            text-transform: capitalize;
+            th {
+                text-align: left;
+                padding: 0.5rem;
+                background: $gray-dark;
+                border: 1px solid black;
+            }
+            tr:nth-child(odd) {
+                background: $gray-lighter;
+                td {
+                    border: 1px solid black;
+                    padding: 0.5rem;
+                }
+            }
+            tr:nth-child(even) {
+                background: $white;
+                td {
+                    border: 1px solid black;
+                    padding: 0.5rem;
+                }
+            }
+        }
+    }
+
+    
+}
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/vnfrConfigPrimitives.jsx b/skyquake/plugins/launchpad/src/launchpad_card/vnfrConfigPrimitives.jsx
new file mode 100644 (file)
index 0000000..d9b7182
--- /dev/null
@@ -0,0 +1,141 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+ import React from 'react';
+ import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
+ import RecordViewStore from '../recordViewer/recordViewStore.js';
+ import Button from 'widgets/button/rw.button.js';
+ import './vnfrConfigPrimitives.scss';
+ import TextInput from 'widgets/form_controls/textInput.jsx';
+ import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+
+ class VnfrConfigPrimitives extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            vnfrs: []
+        };
+        this.state.execPrimitive = {};
+    }
+
+    handleExecuteClick = (configPrimitiveIndex, vnfrIndex, e) => {
+        let execute = RecordViewStore.constructAndTriggerVnfConfigPrimitive({
+                vnfrs: this.state.vnfrs,
+                configPrimitiveIndex: configPrimitiveIndex,
+                vnfrIndex: vnfrIndex
+        });
+        if (!execute) {
+            this.props.actions.showNotification('Could not execute service config. Please review your parameters');
+        }
+    }
+
+    handleParamChange = (paramIndex, configPrimitiveIndex, vnfrIndex, e) => {
+        let vnfrs = this.state.vnfrs;
+        vnfrs[vnfrIndex]["vnf-configuration"]["service-primitive"][configPrimitiveIndex]["parameter"][paramIndex].value = e.target.value
+        this.setState({
+            vnfrs: vnfrs
+        })
+    }
+
+    componentWillReceiveProps(props) {
+        if (this.state.vnfrs.length == 0) {
+            this.setState({
+                vnfrs: props.data
+            })
+        }
+    }
+
+    constructConfigPrimitiveTabs = (tabList, tabPanels) => {
+        let mandatoryFieldValue = 'true';
+        this.state.vnfrs && this.state.vnfrs.map((vnfr, vnfrIndex) => {
+            if (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) {
+                vnfr['vnf-configuration']['service-primitive'].map((configPrimitive, configPrimitiveIndex) => {
+                    let params = [];
+                    if (configPrimitive['parameter'] && configPrimitive['parameter'].length > 0) {
+                        configPrimitive['parameter'].map((param, paramIndex) => {
+                            let optionalField = '';
+                            let displayField = '';
+                            let defaultValue = param['default-value'] || '';
+                            let isFieldHidden = (param['hidden'] && param['hidden'] == 'true') || false;
+                            let isFieldReadOnly = (param['read-only'] && param['read-only'] == 'true') || false;
+                            if (param.mandatory == mandatoryFieldValue) {
+                                optionalField = <span className="required">*</span>
+                            }
+                            if (isFieldReadOnly) {
+                                displayField = <div className='readonly'>{param.value || defaultValue}</div>
+                            } else {
+                                displayField = <TextInput type="text" label={param.name} required={(param.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={param.value} onChange={this.handleParamChange.bind(this, paramIndex, configPrimitiveIndex, vnfrIndex)} />
+                            }
+                            params.push(
+                                <li key={paramIndex}>
+                                    {displayField}
+                                </li>
+                            );
+                        });
+                    }
+                    tabList.push(
+                        <Tab key={configPrimitiveIndex}>{configPrimitive.name}</Tab>
+                    );
+
+                    tabPanels.push(
+                        <TabPanel key={configPrimitiveIndex + '-panel'}>
+                            <h4>{configPrimitive.name}</h4>
+                            <div className="noticeSubText noticeSubText_right">
+                                * required
+                            </div>
+                            <div>
+                                <ul className="parameterGroup">
+                                    {params}
+                                </ul>
+                            </div>
+                            <button className="dark" role="button" onClick={this.handleExecuteClick.bind(this, configPrimitiveIndex, vnfrIndex)}>{configPrimitive.name}</button>
+                        </TabPanel>
+                    )
+                });
+            }
+        });
+    }
+
+    render() {
+
+        let tabList = [];
+        let tabPanels = [];
+        let isConfiguring = (this.props.data['config-status'] && this.props.data['config-status'] != 'configured') || false;
+        let displayConfigStatus = isConfiguring ? '(Disabled - Configuring)': '';
+
+        this.constructConfigPrimitiveTabs(tabList, tabPanels);
+
+        return (
+            <div className="nsConfigPrimitives vnfrConfigPrimitives">
+                <div className="launchpadCard_title">
+                  SERVICE-PRIMITIVES {displayConfigStatus}
+                </div>
+                <div className={isConfiguring ? 'configuring': 'nsConfigPrimitiveTabs'}>
+                    <Tabs onSelect={this.handleSelect}>
+                        <TabList>
+                            {tabList}
+                        </TabList>
+                        {tabPanels}
+                    </Tabs>
+                </div>
+            </div>
+
+        );
+    }
+}
+export default SkyquakeComponent(VnfrConfigPrimitives);
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/vnfrConfigPrimitives.scss b/skyquake/plugins/launchpad/src/launchpad_card/vnfrConfigPrimitives.scss
new file mode 100644 (file)
index 0000000..c6292e9
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'style/_colors.scss';
+@mixin optional() {
+    /* height: 1.25rem;*/
+    /* margin-left: 0.5rem;*/
+    /* margin-top: 0.5rem;*/
+    -ms-flex: 0 1 auto;
+        flex: 0 1 auto;
+}
+.vnfConfigPrimitiveContainer {
+    -ms-flex: 1 0 100%;
+        flex: 1 0 100%;
+}
+.vnfrConfigPrimitives {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex: 1 1 100%;
+        flex: 1 1 100%;
+    /*max-width: 50%;*/
+    -ms-flex-direction: column;
+        flex-direction: column;
+    background: white;
+    .launchpadCard_title {
+        -ms-flex: 0 1 auto;
+            flex: 0 1 auto;
+        min-height: 1rem;
+    }
+    .configuring {
+        pointer-events: none;
+        opacity: 0.3;
+    }
+    .react-tabs {
+        display: -ms-flexbox;
+        display: flex;
+        -ms-flex: 1 0 auto;
+            flex: 1 0 auto;
+
+        [role=tablist] {
+            border: 0px;
+            margin: 0px;
+            padding-top: 1rem;
+            display: -ms-flexbox;
+            display: flex;
+            -ms-flex: 1 1 40%;
+                flex: 1 1 40%;
+            -ms-flex-direction: column;
+                flex-direction: column;
+            background-color: rgb(221, 221, 221);
+
+            [role=tab] {
+                padding: 1rem;
+            }
+            [role=tab]:hover {
+                background-color: #7e9bc1;
+            }
+            [role=tab][aria-selected=true] {
+                border: 0px;
+                border-radius: 0px;
+                position: relative;
+
+                &:before {
+                    display: block;
+                    position: absolute;
+                    content: ' ';
+                    top: -.125rem;
+                    left: 0rem;
+                    width: 100%;
+                    border-top: 1px dashed #00acee;
+                }
+                &:after {
+                    display: block;
+                    position: absolute;
+                    content: ' ';
+                    bottom: -.125rem;
+                    left: 0rem;
+                    width: 100%;
+                    border-bottom: 1px dashed #00acee;
+                }
+            }
+            [role=tab]:focus {
+                box-shadow: none;
+                border: 0px;
+            }
+            [role=tab]:focus:after {
+                display: none;
+            }
+        }
+        [role=tabpanel] {
+            -ms-flex: 1 1 auto;
+                flex: 1 1 auto;
+            margin-top: 1rem;
+            padding: 1rem;
+            display: -ms-flexbox;
+            display: flex;
+            -ms-flex-direction: column;
+                flex-direction: column;
+            -ms-flex-pack: start;
+                justify-content: flex-start;
+            h2 {
+                padding-bottom: 0.5rem;
+            }
+            h3 {
+                padding: 0.5rem;
+                margin-left: 1rem;
+                font-weight: bold;
+            }
+            .noticeSubText {
+                padding-bottom:0.5rem;
+                color:$darker-gray;
+                font-size:0.75rem;
+                &_right {
+                    text-align:right;
+                }
+            }
+            .parameterGroup {
+                /* margin-left: 2rem;*/
+                >li {
+                }
+                label {
+                    display: -ms-flexbox;
+                    display: flex;
+                    -ms-flex-direction:column;
+                        flex-direction:column;
+                    &[data-required="true"] span:after {
+                        content: '*';
+                    }
+                    &.disabled {
+                    }
+                    .optional {
+                        @include optional();
+                    }
+                    .readonly {
+                        -ms-flex: 0 0 30%;
+                            flex: 0 0 30%;
+                        height: 1.25rem;
+                        margin: 0.125rem 0 0.5rem 0;
+                    }
+                }
+            }
+            .vnfConfigPrimitiveParameterGroupParameters {
+                position:relative;
+                 margin-bottom:2.5rem;
+                div {
+                    display:-ms-flexbox;
+                    display:flex;
+                    -ms-flex-direction:column;
+                        flex-direction:column;
+                }
+                .configGroupOverlay {
+                    background: #ccc;
+                    position: absolute;
+                    width: 100%;
+                    height: 100%;
+                    opacity: 0.5;
+                }
+                &:after {
+                }
+            }
+            .vnfConfigPrimitiveParameters {
+
+                label {
+                    display: -ms-flexbox;
+                    display: flex;
+                    -ms-flex-direction:column;
+                        flex-direction:column;
+                    &[data-required="true"] span:after {
+                        content: '*';
+                    }
+                    input, span {
+                     font-size: 1rem;
+                        -ms-flex: 1 1 auto;
+                            flex: 1 1 auto;
+                    }
+                    input {
+                        -ms-flex: 0 0 30%;
+                            flex: 0 0 30%;
+                        height: 1.25rem;
+                        margin: 0.125rem 0 0.5rem 0;
+                        box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+                    }
+                    .optional {
+                        @include optional();
+                    }
+                    .readonly {
+                        -ms-flex: 0 0 30%;
+                            flex: 0 0 30%;
+                        height: 1.25rem;
+                        margin: 0.125rem 0 0.5rem 0;
+                    }
+                }
+            }
+            .inputGroup{
+                display:-ms-flexbox;
+                display:flex;
+                -ms-flex:1 1 auto;
+                    flex:1 1 auto;
+                -ms-flex-align:center;
+                    align-items:center;
+            }
+        }
+        button {
+            margin-top: 2rem;
+        }
+    }
+}
+.vnfConfigPrimitiveJobList {
+    -ms-flex: 1 1 80%;
+        flex: 1 1 80%;
+
+    .listView {
+        padding: 0.1rem;
+        overflow-y: auto;
+
+        >div>div {
+            margin:0.5rem;
+            >.tree-view_item {
+                padding: 1rem;
+            }
+            &:nth-child(odd) {
+                background:white;
+            }
+        }
+
+        .tree-view_children {
+            margin-left: 2rem;
+        }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/main.js b/skyquake/plugins/launchpad/src/main.js
new file mode 100644 (file)
index 0000000..5dc626f
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+import "babel-polyfill";
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/launchpad/src/monitoring-params-filter.jsx b/skyquake/plugins/launchpad/src/monitoring-params-filter.jsx
new file mode 100644 (file)
index 0000000..301b1c1
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+let ReactCSSTransitionGroup = require('react-addons-css-transition-group');
+var LaunchpadFleetActions = require('./launchpadFleetActions.js');
+var LaunchpadFleetStore = require('./launchpadFleetStore.js');
+
+class MPFilter extends React.Component {
+  constructor(props) {
+    super(props);
+    var self = this;
+    this.state = LaunchpadFleetStore.getState();
+    this.state.slideno = 0;
+
+  }
+  componentDidMount() {
+}
+change(e) {
+  var pane = JSON.parse(e.target.value);
+  var ret = {no: pane[1], pane:pane, slideChange:this.props.nsrs.length}
+  this.setState({slideno:pane[1], dropdownSlide:pane, slideChange: this.state.nsrs.length});
+  LaunchpadFleetActions.slideNoStateChange(ret);
+}
+
+render () {
+    var self = this;
+    /////////
+    // This code shouldn't be in here. It needs to be placed in an isolated component.
+    var drop_down = [];
+    var key = [];
+    if (self.props.nsrs
+        && self.props.nsrs.length > 0
+        && self.props.nsrs[0]
+         && self.props.nsrs[0]["monitoring-param"]) {
+      drop_down.push(<option key={'default'} value={JSON.stringify(['default', -1])}>Monitoring Params</option>)
+      for (var j = 0; j < self.props.nsrs.length; j++) {
+        var monitoring_params = self.props.nsrs[j]["monitoring-param"];
+        checkAndAddKey(monitoring_params);
+        for (var i = 0; i < monitoring_params.length; i++) {
+          if (key.indexOf(monitoring_params[i]["group-tag"]) == -1) {
+            var same = false;
+            for (var k = 0; k < drop_down.length; k++) {
+              if (monitoring_params[i]["mp-id"] == drop_down[k].key) {
+                same = true;
+              }
+            }
+            if (!same) {
+              drop_down.push(<option key={monitoring_params[i]["mp-id"]} value={JSON.stringify([monitoring_params[i]["mp-id"], monitoring_params[i]['group-tag'][6] - 1])}>{monitoring_params[i].name}</option>)
+              key.push(monitoring_params[i]);
+            }
+          }
+        }
+      }
+    }
+    //
+    /////////
+
+    return (
+      <div>
+          <div
+            style={{
+              display:'flex',
+              justifyContent: 'start',
+              flexWrap:'wrap'
+            }}
+          >
+          <h4>CHANGE METRICS</h4>
+            <select style={{margin:'0px 0px 14px 15px'}} onChange={this.change.bind(this)} value={JSON.stringify(['default',0])}>{drop_down}</select>
+          </div>
+        </div>
+            )
+  }
+}
+function checkAndAddKey (monitoring_params) {
+  monitoring_params.forEach(function(v, i) {
+    if(v["mp-id"] == "") {
+      v["mp-id"] = v["group-tag"] + "-" + i;
+    }
+  })
+}
+
+export default MPFilter
diff --git a/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js b/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js
new file mode 100644 (file)
index 0000000..9d52bb8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+
+ */
+import React from 'react';
+import * as Components from 'widgets/components.js';
+import Utils from 'utils/utils.js';
+
+function Component(node, prop, count, length) {
+    var valueProperty;
+    var numericConstraintsMinPresent = false;
+    var numericConstraintsMaxPresent = false;
+    if ("value-type" in node) {
+        switch(node["value-type"]) {
+            case 'INT' :
+                valueProperty = 'value-integer';
+                if (node['numeric-constraints']) {
+                    numericConstraintsMinPresent = node['numeric-constraints']['min-value'] ? true : false;
+                    numericConstraintsMaxPresent = node['numeric-constraints']['max-value'] ? true : false;
+                }
+                break;
+            case 'DECIMAL' :
+                valueProperty = 'value-decimal';
+                if (node['numeric-constraints']) {
+                    numericConstraintsMinPresent = node['numeric-constraints']['min-value'] ? true : false;
+                    numericConstraintsMaxPresent = node['numeric-constraints']['max-value'] ? true : false;
+                }
+                break;
+            case 'STRING' : valueProperty = 'value-string'; break;
+        }
+    } else {
+        valueProperty = 'value-integer';
+    }
+    //' + String((100/length) - 5) + '%'
+    switch(node["widget-type"]) {
+      case 'GAUGE':
+        return (
+            <div
+            className="monitoring_params_component"
+            key={prop + '-' + prop.name+ '-' + count}
+            mp={node["mp-id"]}>
+                <div>{node.name}</div>
+                <Components.default.Gauge value={node[valueProperty] || 0} min={numericConstraintsMinPresent ? node['numeric-constraints']['min-value'] : 0} max={numericConstraintsMaxPresent ? node['numeric-constraints']['max-value'] : 100} units={node['units'] || ''} />
+            </div>);
+        break;
+      case 'TEXTBOX':
+      case 'COUNTER':
+        var displayValue = 0;
+        var backendValue = node[valueProperty] || 0;
+        if (node['units'] == 'KB') {
+            displayValue = Utils.getByteDataWithUnitPrefix(backendValue * 1024, 4);
+        } else if (node['units'] == 'bytes') {
+            displayValue = Utils.getByteDataWithUnitPrefix(backendValue, 4);
+        } else if (node['units'] == 'packets') {
+            displayValue = Utils.getPacketDataWithUnitPrefix(backendValue, 4);
+        } else {
+          displayValue = [backendValue, node['units']];
+        }
+        return (
+            <div
+            key={prop + '-' + prop.name + '-' + count}
+            className="monitoring_params_component"
+            mp={node["mp-id"]}>
+                <div>{node.name}</div>
+                <div style={{fontSize: '3rem'}}>{displayValue[0]}</div>
+                <div style={{fontSize: '1.5rem'}}>{displayValue[1]}</div>
+            </div>);
+        break;
+        default : return(<div>{node["widget-type"]} Widget Type Not Yet Supported</div>)
+    }
+}
+
+export default function parseCardObj(obj_list, type) {
+    var ret = [];
+    var hash = {};
+    if (typeof obj_list != 'undefined') {
+      for (var i = 0; i < obj_list.length; i++) {
+        var node = obj_list[i];
+        var key = node[type] || node["group-tag"];
+        if (key in hash) {
+            hash[key].push(node);
+        } else {
+            hash[key] = [node];
+        }
+      }
+    }
+    for (var prop in hash) {
+      var html = {};
+      var vnfrID = hash[prop][0]['vnfr-id'];
+      var vnfrSubstr = vnfrID ? hash[prop][0]['vnfr-id'].substr(hash[prop][0]['vnfr-id'].length - 4) : ''
+      var GroupName = hash[prop][0]["group-tag"];
+      html.title = GroupName ? GroupName : '';
+      if (hash[prop].length == 1) {
+          html.component = Component.call(this, hash[prop][0], prop, 1);
+      } else {
+          var list = []
+          for (var i = 0; i < hash[prop].length; i++) {
+              list.push(Component.call(this,hash[prop][i], prop, i, hash[prop].length));
+          }
+          html.component = list;
+      }
+      ret.push(html)
+    }
+    return ret.sort(function(a, b){
+      return (a.title > b.title) ? -1 : 1;
+    });
+  }
diff --git a/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamsCarousel.jsx b/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamsCarousel.jsx
new file mode 100644 (file)
index 0000000..0db9553
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import Carousel from '../carousel/carousel-react.jsx';
+import SkyquakeCarousel from '../carousel/skyquakeCarousel.jsx';
+import './monitoring_params.scss';
+import ParseMP from './monitoringParamComponents.js';
+//TODO
+// This Carousel needs to be refactored so that we can sanely add a unique key to each element.
+// The entire component needs some serious refactoring.
+
+export default class launchpadCarousel extends React.Component {
+    constructor(props){
+        super(props);
+    }
+    componentWillMount(){
+        // window.addEventListener('resize', resizeComponents.bind(this))
+    }
+    componentWillUnmount(){
+        // window.removeEventListener('resize', resizeComponents.bind(this))
+    }
+  render() {
+    var slideno = this.props.slideno;
+    if(this.props.component_list) {
+        var components = ParseMP.call(this, this.props.component_list);
+       return <Carousel slideno={this.props.slideno} component_list={components} />
+       // return <SkyquakeCarousel slideno={this.props.slideno} slides={components} />
+    } else {
+        return <div className="empty"> MONITORING PARAMETERS NOT LOADED</div>
+    }
+  }
+}
+
+
diff --git a/skyquake/plugins/launchpad/src/monitoring_params/monitoring_params.scss b/skyquake/plugins/launchpad/src/monitoring_params/monitoring_params.scss
new file mode 100644 (file)
index 0000000..43c871b
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.slick-track {
+  cursor:pointer;
+}
+.slick-slider {
+  margin-right:0;
+  margin-bottom: 50px;
+}
+.slick-next, .slick-prev {
+  opacity:0.25;
+  top:5rem;
+  z-index:5;
+  height:auto;
+  &:hover{
+    opacity:1;
+  }
+  &:before{
+    font-family: "slick";
+    font-size: 50px;
+    font-weight: bold;
+    line-height: 1;
+    color: white;
+    opacity: 0.75;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+  }
+}
+.slick-next {
+    right: -1rem;
+}
+.slick-prev {
+    left: -10px;
+}
+.slick-list {
+  max-width: 693px;
+}
+.slick-slide {
+  height:auto;
+}
+.slick-slide.component {
+  box-sizing:border-box;
+  flex-direction:column;
+  flex-wrap:nowrap;
+  // RIFT-12883
+  // Prevent resizing
+  // height:0;
+  transition:height 200ms, opacity 600ms;
+  opacity:0;
+  .componentWrapper {
+    display:flex;
+    flex-wrap:wrap;
+        flex: 1 0 auto;
+  }
+}
+.slick-active {
+}
+.slick-slide.slick-active.component {
+  align-items:inherit;
+  height:auto;
+  opacity:1;
+  transition:height 200ms, opacity 600ms;
+}
+.slick-initialized.slick-slider{
+  max-width: 693px;
+}
+.slick-initialized .slick-slide {
+    display: flex;
+}
+.monitoring_params_component {
+  flex: 1 1;
+    text-align:center;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+
+    align-content: center;
+    padding: 0.5rem;
+    border:1px solid white;
+}
+.slick-dots li button:before {
+    font-size: 25px;
+}
diff --git a/skyquake/plugins/launchpad/src/nsCardPanel/nsCardPanel.jsx b/skyquake/plugins/launchpad/src/nsCardPanel/nsCardPanel.jsx
new file mode 100644 (file)
index 0000000..2b9b4c1
--- /dev/null
@@ -0,0 +1,48 @@
+import React from 'react';
+
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import LaunchpadCard from '../launchpad_card/launchpadCard.jsx';
+import LaunchpadFleetActions from'../launchpadFleetActions';
+
+export default class NsCardPanel extends React.Component {
+
+       onCloseCard(nsr_id) {
+               return () => {
+                       LaunchpadFleetActions.closeNsrCard(nsr_id);
+               }
+       }
+  findNsr(nsrs, nsr_id) {
+    nsrs.find()
+  }
+  render() {
+    const {nsrs, openedNsrIDs, ...props} = this.props;
+               return (
+      <DashboardCard className="nsCardPanel"
+          showHeader={true} title="NETWORK SERVICE DETAILS">
+                {
+                  openedNsrIDs.map((nsr_id, index) => {
+                      let nsr = nsrs.find(e => { return e.id == nsr_id; })
+                      if (nsr) {
+                        return  (
+                          <LaunchpadCard deleting={nsr.deleting}
+                                slideno={this.props.slideno}
+                                key={index}
+                                id={nsr_id}
+                                name={nsr.name}
+                                data={nsr.data}
+                                nsr={nsr}
+                                isActive={nsr["admin-status"] == "ENABLED"}
+                                closeButtonAction={this.onCloseCard(nsr.id)}/>
+                        );
+                      }
+                    }
+                  )
+                }
+        </DashboardCard>
+      );
+       }
+}
+NsCardPanel.defaultProps = {
+       nsrs: [],
+       slideno:0
+}
diff --git a/skyquake/plugins/launchpad/src/nsListPanel/nsListPanel.jsx b/skyquake/plugins/launchpad/src/nsListPanel/nsListPanel.jsx
new file mode 100644 (file)
index 0000000..c8c8412
--- /dev/null
@@ -0,0 +1,366 @@
+
+import React from 'react';
+import { Link } from 'react-router';
+
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import LaunchpadFleetActions from'../launchpadFleetActions';
+import LaunchpadFleetStore from '../launchpadFleetStore';
+import UpTime from 'widgets/uptime/uptime.jsx';
+
+/*
+ * TODO: Handle when page is loading. See recordView for ref
+ */
+
+
+/*
+ * key -  NSR property name
+ * label - Text to display for the header column label
+ * colClass - class to add for rendering this column
+ * transform: function to call to display the value for the property
+ */
+const FIELD_KEYS = [
+    {
+        // was using 'short-name'
+        key: 'name',
+        label: 'NS Name',
+        colClass: 'nsColNsName',
+        transform: function(nsr, key) {
+            let val = nsr[key];
+            let title = '"' + val + '" Click to open the viewport dashboard.';
+            let sdnpresent = nsr['sdn-account'] ? true: false;
+            return (
+                <Link className="nsViewportLink"
+                    to={{pathname: '/viewport', query: {id: nsr.id,
+                        sdnpresent: sdnpresent}}}
+                    title={title}>
+                    {val}
+                </Link>
+            )
+        }
+    },
+    {
+        key: 'nsd_name',
+        label: 'nsd',
+        colClass: 'nsColNsdName',
+        transform: function(nsr, key) {
+            let val=nsr[key];
+            return (
+                <span title={val}>{val}</span>
+            );
+        }
+    },
+    {
+        key: 'operational-status',
+        label: 'Status',
+        colClass: 'nsColStatus',
+        transform: function(nsr, key, isLoading) {
+            let val = null;
+            if(isLoading) {
+                if (nsr['operational-status'] == 'running') {
+                    if(nsr['config-status'] == 'configuring') {
+                        val = 'Configuring'
+                    } else {
+                        val = 'Configuration Failed'
+                    }
+                } else {
+                    val = nsr['operational-status'];
+                }
+            } else {
+                val = 'Active'
+            }
+            return (
+                <span title={val} style={{'textTransform': 'capitalize'}}>{val}</span>);
+        }
+    },
+    {
+        key: 'create-time',
+        label: 'Uptime',
+        colClass: 'nsColUptime',
+        transform: function(nsr, key) {
+            let val = nsr[key];
+            return (<UpTime initialTime={val} run={true} />);
+        }
+    }
+];
+
+/*
+ * Render the network service grid header row
+ */
+class NsListHeader extends React.Component {
+
+    render() {
+        const {fieldKeys, ...props} = this.props;
+        return (
+            <div className="nsListHeaderRow">
+                {fieldKeys.map( (field, index) =>
+                    <div className={"nsListHeaderField " + field.colClass}
+                        key={index} >
+                        {field.label}
+                    </div>
+                )}
+                <div className="nsListHeaderField nsColAction"></div>
+            </div>
+        );
+    }
+}
+
+/*
+ * Render a row for the network service
+ */
+class NsListItem extends React.Component {
+
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.isLoading = this.isLoading(props)
+        this.state.failed = false;
+    }
+
+    renderFieldBody(nsr, field, isLoading) {
+        return field.transform(nsr, field.key, isLoading);
+    }
+
+    columnStyle(field) {
+        return {
+            'width': field.width
+        }
+    }
+
+    classNames(isCardOpen) {
+        return "nsListItemRow" + (isCardOpen ? " openedCard" : "");
+    }
+
+
+    openDashboard(nsr_id) {
+        window.location.href = '//' + window.location.hostname +
+            ':' + window.location.port + '/index.html' +
+            window.location.search +
+            window.location.hash + '/' + nsr_id + '/detail';
+        launchpadFleetStore.closeSocket();
+    }
+
+    componentWillReceiveProps(props) {
+        this.setState({
+            isLoading:  this.isLoading(props)
+        })
+    }
+    isLoading(props) {
+        return !((props.nsr['operational-status'] == 'running') && (props.nsr['config-status'] == 'configured'))
+    }
+    actionButton(glyphValue, title, onClick) {
+        return (
+           <div className="actionButton"  onClick={onClick}>
+            <span className="oi" data-glyph={glyphValue}
+            title={title} aria-hidden="true"></span>
+           </div>
+        );
+    }
+
+    render() {
+        let failed = this.state.failed;
+        let isLoading =  this.state.isLoading || failed;
+        const {nsr, isCardOpen, fieldKeys, ...props} = this.props;
+        const self = this;
+        return (
+            <div className={this.classNames(isCardOpen)} data-id={nsr.id}>
+                {fieldKeys.map( (field, index) =>
+                    <div className={"nsListItemField " + field.colClass}
+                        key={index} >
+                        <div className="cellValue">
+                        {self.renderFieldBody(nsr, field, isLoading)}
+                        </div>
+                    </div>
+                )}
+                <div className="nsListItemField nsColAction">
+                    <div className="cellValue">
+                    {
+                        (isCardOpen)
+                            ? this.actionButton("circle-x",
+                                "Close network service card",
+                                function() {
+                                    LaunchpadFleetActions.closeNsrCard(nsr.id);
+                                })
+                            : this.actionButton("arrow-circle-right",
+                                "Open network service card",
+                                function() {
+                                    LaunchpadFleetActions.openNsrCard(nsr.id);
+                                })
+                    }
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+
+/*
+ * Used for development/debugging layout
+ */
+class EmptyNsListItem extends React.Component {
+    render() {
+        const {fieldKeys, ...props} = this.props;
+        return (
+            <div className={"nsListItemRow"} >
+                {fieldKeys.map( (field, index) =>
+                    <div className={"nsListItemField " + field.colClass}
+                        key={index} >
+                    </div>
+                )}
+                <div className="nsListItemField nsColAction">
+                </div>
+            </div>
+        );
+    }
+}
+
+/*
+ * Used for development/debugging layout
+ */
+class MockNsListItem extends React.Component {
+
+    simNsr() {
+        return {
+            name: 'Grue',
+            nsd_name: 'Dungeon X',
+            'operational-status': 'Hunting',
+            'create-time': 1163507750
+        };
+    }
+    render() {
+        const {fieldKeys, mockNsr, isCardOpen, ...props} = this.props;
+        let nsr = mockNsr;
+        if (!nsr) {
+            nsr = this.simNsr();
+        }
+        return (<NsListItem nsr={nsr}
+            fieldKeys={fieldKeys}
+            isCardOpen={isCardOpen}
+            />
+        );
+    }
+}
+MockNsListItem.defaultProps = {
+    isCardOpen: false
+}
+
+
+class NsList extends React.Component {
+
+    emptyRows(count) {
+        let emptyRows = [];
+        for (var i=0; i < count; i++) {
+            emptyRows.push(
+                <EmptyNsListItem key={ "empty_"+i}
+                    fieldKeys={this.props.fieldKeys} />
+                );
+        }
+        return emptyRows;
+    }
+
+    mockNsRows(count) {
+        let mockNsRows = [];
+        let isCardOpen = false;
+        for (var i=0; i < count; i++) {
+            isCardOpen = !isCardOpen;
+            mockNsRows.push(
+                <MockNsListItem key={ "empty_"+i}
+                    fieldKeys={this.props.fieldKeys} isCardOpen={isCardOpen} />
+                );
+        }
+        return mockNsRows;
+    }
+
+    render() {
+        const {nsrs, openedNsrIDs, fieldKeys, ...props} = this.props;
+        return (
+            <div className="nsList">
+                <NsListHeader fieldKeys={fieldKeys} />
+                <div className="nsList-body">
+                    <div className="nsList-body_content">
+                        {nsrs.map((nsr, index) =>
+                            <NsListItem key={nsr.id} nsr={nsr}
+                                fieldKeys={fieldKeys}
+                                isCardOpen={openedNsrIDs.includes(nsr.id)} />
+                        )}
+                        {this.mockNsRows(this.props.mockNsRows)}
+                        {this.emptyRows(this.props.emptyRows)}
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+
+NsList.defaultProps = {
+    mockNsRows: 0,
+    emptyRows: 0
+}
+
+
+export default class NsListPanel extends React.Component {
+
+    handleInstantiateNetworkService = () => {
+        this.context.router.push({pathname:'instantiate'});
+    }
+    handleShowHideToggle(newState) {
+        return function() {
+            LaunchpadFleetActions.setNsListPanelVisible(newState);
+        }
+    }
+    panelToolbar() {
+        let plusButton = require("style/img/launchpad-add-fleet-icon.png");
+
+        return (
+            <div className="nsListPanelToolbar">
+
+                <div className="button"
+                    onClick={this.handleInstantiateNetworkService} >
+                    <img src={plusButton}/>
+                    <span>Instantiate Service</span>
+                </div>
+            </div>
+        );
+    }
+
+    render() {
+        const {nsrs, openedNsrIDs, emptyRows, isVisible, ...props} = this.props;
+        const fieldKeys = FIELD_KEYS;
+        let glyphValue = (isVisible) ? "chevron-left" : "chevron-right";
+        if (isVisible) {
+            return (
+                <DashboardCard className="nsListPanel" showHeader={true}
+                    title="NETWORK SERVICES">
+                    {this.panelToolbar()}
+                    <a onClick={this.handleShowHideToggle(!isVisible)}
+                        className={"nsListPanelToggle"}>
+                        <span className="oi"
+                            data-glyph={glyphValue}
+                            title="Toggle Details Panel"
+                            aria-hidden="true"></span></a>
+                    <NsList nsrs={nsrs} openedNsrIDs={openedNsrIDs}
+                        fieldKeys={fieldKeys} emptyRows={emptyRows} />
+                </DashboardCard>
+
+
+            );
+        } else {
+            return (
+                <DashboardCard className="leftMinimizedNsListPanel" showHeader={true}
+                            title="|">
+                <a onClick={this.handleShowHideToggle(!isVisible)}
+                        className={"nsListPanelToggle"}>
+                        <span className="oi"
+                            data-glyph={glyphValue}
+                            title="Toggle Details Panel"
+                            aria-hidden="true"></span></a>
+                </DashboardCard>
+            );
+        }
+    }
+}
+NsListPanel.contextTypes = {
+    router: React.PropTypes.object
+};
+NsListPanel.defaultProps = {
+    isVisible: true
+}
diff --git a/skyquake/plugins/launchpad/src/recordViewer/placementGroupsInfo.jsx b/skyquake/plugins/launchpad/src/recordViewer/placementGroupsInfo.jsx
new file mode 100644 (file)
index 0000000..faecbe7
--- /dev/null
@@ -0,0 +1,204 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+export default class PlacementGroupsInfo extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {};
+    this.state.dict = {};
+    this.state.displayedGroup = null;
+  }
+  componentWillReceiveProps(props) {
+    this.setState({
+      nsr: props.nsr,
+      dict: buildPlacementGroupDictFromVDUR(props.nsr),
+      // dict: buildPlacementGroupDict(props.nsr),
+    });
+  }
+  showDisplayGroup = (context, ref, type) => {
+    // ref = 'Orcus';
+    context.setState({
+      displayedGroup: this.state.dict[ref]
+    })
+  }
+  render(){
+    let html;
+    let vdurs = <VduPlacement nsr={this.props.nsr} showDisplayGroup={this.showDisplayGroup.bind(null, this)}/>;
+    let details = <PlacementGroupDetails displayedGroup={this.state.displayedGroup} />;
+    return <div className="placementGroups">{vdurs}{details}</div>;
+  }
+}
+PlacementGroupsInfo.defaultProps = {
+  nsr: {}
+}
+
+
+class VduPlacement extends React.Component {
+  render() {
+    let html;
+    let {showDisplayGroup, nsr, ...props} = this.props;
+    html = (
+      <div className="panel panel-5">
+        <h3 className="sectionHeader">
+          VDU Placement
+        </h3>
+        <div className="vdupTable">
+          <div className="vdup-title">
+            <h4>Record</h4>
+            <h4>Placement Group</h4>
+          </div>
+          <dl className="nsrType">
+            <dt>
+              <div>NSR: {nsr.name}</div>
+            </dt>
+            <dd></dd>
+          </dl>
+          {
+            flattenPlacementGroupsToHTML(nsr, showDisplayGroup)
+          }
+        </div>
+      </div>
+    );
+    return html;
+  }
+}
+function flattenPlacementGroupsToHTML(nsr, onClick) {
+  let data = [];
+  nsr.vnfrs && nsr.vnfrs.map(function(v, i) {
+    let html;
+    html = (
+      <dl className="vnfrType" key={'vnfr-' + i}>
+        <dt>
+          <div>VNFR: {v['short-name']}</div>
+        </dt>
+        <dd></dd>
+      </dl>
+    )
+    data.push(html);
+    v && v.vdur && v.vdur.map(function(vd, j) {
+      let html;
+      html = (
+        <dl className="vduType" key={'vdur-' + i + '-'+ j}>
+          <dt>
+            <div>VDUR: {vd['name']}</div>
+          </dt>
+          <dd>
+            <ul>
+              {
+                vd['placement-groups-info'].map(function(p, k) {
+                  return <li onClick={onClick.bind(null, p.name)} key={'pg-' + i + '-' + j + '-' + k}>{p.name}</li>
+                })
+              }
+            </ul>
+          </dd>
+        </dl>
+      );
+      data.push(html);
+    });
+  });
+  return data;
+}
+class PlacementGroupDetails extends React.Component {
+  render() {
+    let html;
+    let {displayedGroup, ...props} = this.props;
+    let dg = displayedGroup;
+    let dgHTML = '';
+    if(dg) {
+      dgHTML = (
+        <dl className="placementGroupDetails">
+            <dt>Name</dt>
+            <dd>{dg.name}</dd>
+            <dt>Requirement</dt>
+            <dd>{dg.requirement}</dd>
+            <dt>Strategy</dt>
+            <dd>{dg.strategy}</dd>
+            <dt>Cloud Provider</dt>
+            <dd>{dg['cloud-type']}</dd>
+            {
+              (dg['availability-zone'] != undefined) ?
+                <dt>Availability Zone</dt> : ''
+            }
+            {
+              (dg['availability-zone'] != undefined) ?
+                <dd>{dg['availability-zone']}</dd> : ''
+            }
+            {
+              (dg['server-group'] != undefined) ?
+                <dt>Affinity/Anti-Affinity Server Group</dt> : ''
+            }
+            {
+              (dg['server-group'] != undefined) ?
+                 <dd>{dg['server-group']}</dd> : ''
+            }
+            {
+              (dg['host-aggregate'] != undefined) ?
+                <dt>Host Aggregates</dt> : ''
+            }
+            {
+              dg['host-aggregate'] != undefined ?
+                <dd>
+                  {dg['host-aggregate'].map(function(ha, h) {
+                    return <div key={h}>{ha['metadata-key']}:{ha['metadata-value']}</div>
+                  })}
+                </dd>
+              : ''
+            }
+        </dl>
+      )
+    }
+    html = (
+      <div className="panel panel-5">
+        <h3 className="sectionHeader">
+          Placement Group Details
+        </h3>
+        <div>
+          {dgHTML}
+        </div>
+      </div>
+    );
+    return html;
+  }
+}
+PlacementGroupDetails.defaultProps = {
+  displayedGroup: {}
+}
+function buildPlacementGroupDictFromVDUR(data) {
+  let d = {};
+  data.vnfrs.map(function(vnf) {
+    vnf.vdur && vnf.vdur.map(function(v) {
+      v['placement-groups-info'].map(function(p) {
+        d[p.name] = p;
+      })
+    })
+  })
+  return d;
+}
+function buildPlacementGroupDict(data) {
+  let d = {};
+  let nsd = data['nsd-placement-group-maps'];
+  let vnfd = data['vnfd-placement-group-maps'];
+  nsd.map(function(m, i) {
+    d[m['placement-group-ref']] = m;
+  });
+  vnfd.map(function(m, i) {
+    d[m['placement-group-ref']] = m;
+  });
+  return d;
+}
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordCard.jsx b/skyquake/plugins/launchpad/src/recordViewer/recordCard.jsx
new file mode 100644 (file)
index 0000000..e3c3dad
--- /dev/null
@@ -0,0 +1,352 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import MonitoringParamsCarousel from '../monitoring_params/monitoringParamsCarousel.jsx';
+import VnfrCard from '../vnfr/vnfrCard.jsx';
+import {LaunchpadCard, LpCardNfviMetrics, EpaParams, NsrPrimitiveJobList} from '../launchpad_card/launchpadCard.jsx';
+import VnfrConfigPrimitives from '../launchpad_card/vnfrConfigPrimitives.jsx';
+import NsrConfigPrimitives from '../launchpad_card/nsrConfigPrimitives.jsx';
+import NsrScalingGroups from '../launchpad_card/nsrScalingGroups.jsx';
+import LoadingIndicator from 'widgets/loading-indicator/loadingIndicator.jsx';
+import NfviMetricBars from 'widgets/nfvi-metric-bars/nfviMetricBars.jsx';
+import ParseMP from '../monitoring_params/monitoringParamComponents.js';
+import PlacementGroupsInfo from './placementGroupsInfo.jsx';
+import JobListCard from '../launchpad_card/jobListCard.jsx';
+import NSVirtualLinks from '../virtual_links/nsVirtualLinks.jsx';
+export default class RecordCard extends React.Component {
+  constructor(props) {
+    super(props)
+  }
+
+  handleSelect = (index, last) => {
+      // console.log('Selected tab is', index, 'last index is', last);
+  }
+
+  render(){
+    let html;
+    let content;
+    let card;
+    let cardData = {};
+    let components = [];
+    let configPrimitivesProps = {};
+    let displayConfigPrimitives = false;
+    let configPrimitiveComponent = null;
+    let scalingGroupsProps = {};
+    let displayScalingGroups = false;
+    let scalingGroupComponent = null;
+    let consoleUrlsComponent = null;
+    let consoleUrlsList = [];
+
+    let displayNSVirtualLinks = false;
+    let nsVirtualLinksProps = {};
+    let nsVirtualLinksComponent = null;
+
+    let tabList = [];
+    let tabPanels = [];
+
+    switch(this.props.type) {
+      case 'vnfr' :
+        cardData = this.props.data[0];
+        // Disabling config primitives for VNF
+        configPrimitivesProps = [cardData];
+        displayConfigPrimitives = cardData['service-primitives-present'];
+        if (displayConfigPrimitives) {
+          configPrimitiveComponent = (
+            <div className="flex vnfrConfigPrimitiveContainer">
+              <VnfrConfigPrimitives data={configPrimitivesProps} />
+            {/* <NsrPrimitiveJobList jobs={cardData['config-agent-job']}/> */}
+            <div style={{display:'flex', flexDirection: 'column',     flex: '1 1 40%'}}>
+                <div className="launchpadCard_title">
+                  JOB LIST
+                </div>
+                <div className="scrollContainer">
+                {
+                  //Sort for recent on top
+                    this.props.jobData.sort(function(a,b){
+                    return parseInt(b['job-id']) - parseInt(a['job-id']);
+                  }).map(function(job){
+                    //Return only vnfr configs
+                    if(job["triggered-by"] == 'vnf-primitive') {
+                      return job.vnfr.map(function(v){
+                        //That match the currently selected job id
+                        if(v.id == cardData.id) {
+                          return v.primitive.map(function(p, i) {
+                            return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={i} {...p} />
+                          })
+                        }
+                      })
+                    }
+                  })}
+                </div>
+              </div>
+            </div>
+          );
+        }
+
+        if (cardData['vdur']) {
+          cardData['vdur'].map((vdur, index) => {
+            let consoleLink = vdur['console-url'] ? 'Open VM Console' : 'None';
+            consoleUrlsList.push(
+              <li key={index}>
+                <h3>
+                  {vdur['name'] + '-' + vdur.id.substr(0,4)}
+                </h3>
+                <a href={vdur['console-url']} target='_blank'>
+                  {consoleLink}
+                </a>
+              </li>
+            )
+          });
+          consoleUrlsComponent = (
+            <div className="consoleUrlsComponent">
+              <ul className="consoleUrlsList">
+                {consoleUrlsList}
+              </ul>
+            </div>
+          );
+        }
+        components = ParseMP.call(this, cardData["monitoring-param"], "vnfr-id");
+        break;
+      case 'nsr' :
+        cardData = this.props.data.nsrs[0];
+        configPrimitivesProps = cardData;
+        scalingGroupsProps = cardData;
+        displayConfigPrimitives = cardData['service-primitive'];
+        displayScalingGroups = cardData['scaling-group-descriptor'] ? true : false;
+        let sortedJobs = this.props.jobData.sort(function(a,b){
+                    return parseInt(b['job-id']) - parseInt(a['job-id']);
+                  });
+        if (displayConfigPrimitives) {
+          configPrimitiveComponent = (
+            <div className="flex nsConfigPrimitiveContainer">
+              <NsrConfigPrimitives data={configPrimitivesProps} />
+              <div style={{display:'flex', flexDirection: 'column',     flex: '1 1 40%'}}>
+                <div className="launchpadCard_title">
+                  JOB LIST
+                </div>
+                <div className="scrollContainer">
+                  {sortedJobs.map(function(job, i){
+                    if(job["triggered-by"] == 'ns-primitive') {
+                      return <JobListCard type="nsr" job-id={job['job-id']} cardData={cardData} key={i} {...job} />
+                    }
+                  })
+                  .concat(sortedJobs.map(function(job) {
+                    if(!job.hasOwnProperty('job-name') && (job["triggered-by"] == 'ns-primitive')) {
+                      return job.vnfr.map(function(v){
+                        //That match the currently selected job id
+                        if(v.id == cardData.id) {
+                          return v.primitive.map(function(p, i) {
+                            return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={i} {...p} />
+                          })
+                        }
+                      })
+                    }
+                  }))
+                }
+                </div>
+              </div>
+            </div>
+          );
+        }
+        if (displayScalingGroups) {
+          scalingGroupComponent = (
+            <div className="flex nsrScalingGroupContainer">
+              <NsrScalingGroups data={scalingGroupsProps} />
+            </div>
+          );
+        }
+
+        // Virtual Links tab content
+        displayNSVirtualLinks = true;
+        nsVirtualLinksProps = cardData;
+        if (displayNSVirtualLinks) {
+          nsVirtualLinksComponent = (
+            <div className='flex nsVirtualLinksContainer'>
+              <NSVirtualLinks data={nsVirtualLinksProps} />
+            </div>
+          );
+        };
+
+        components = ParseMP.call(this, cardData["monitoring-param"], "vnfr-id");
+        break;
+    }
+    let mgmt_interface = cardData["dashboard-url"];
+    let mgmtHTML;
+    let metricsAndParams = [];
+
+
+    let nfviMetrics = <LpCardNfviMetrics data={cardData["nfvi-metrics"]} />;
+    metricsAndParams.push(<div className="monitoringParams" key="mp">
+                          {components.sort().map(function(c, k) {
+                            return <div key={k} className="mpSlide">{c.title}{c.component}</div>
+                          })}
+                          </div>)
+    metricsAndParams.push((<div key="nvfi" className="nfvi-metrics">
+      { nfviMetrics }
+      <EpaParams data={cardData["epa-params"]} />
+    </div>))
+
+
+
+    if(mgmt_interface) {
+      mgmtHTML = <a href={mgmt_interface} target="_blank">Open Application Dashboard</a>;
+    }
+      if(this.props.isLoading) {
+        html = <DashboardCard className="loading" showHeader={true} title={cardData["short-name"]}><LoadingIndicator size={10} show={true} /></DashboardCard>
+      } else {
+        let glyphValue = (this.props.mmmrecordDetailsToggleValue) ? "chevron-left" : "chevron-right";
+
+        if (this.props.type == 'nsr') {
+          tabList.push(
+            <Tab key={cardData.id}>NS Data</Tab>
+          )
+        } else if (this.props.type == 'vnfr') {
+          tabList.push(
+            <Tab key={cardData.id}>VNF Data</Tab>
+          )
+        }
+
+        tabPanels.push(
+          <TabPanel key={cardData.id + '-panel'}>
+
+              <div className="launchpadCard_title" style={{textAlign:'right'}}><span style={{float:'left'}}>MONITORING PARAMETERS</span>
+                {mgmtHTML}
+              </div>
+              {metricsAndParams}
+              <div className="cardSectionFooter">
+              </div>
+          </TabPanel>
+        )
+
+
+        if (this.props.type == 'nsr') {
+          if (scalingGroupComponent) {
+            tabList.push(
+            <Tab key={cardData.id + '-sg'}>Scaling Groups</Tab>
+          );
+
+          tabPanels.push(
+              <TabPanel key={cardData.id + '-sg-panel'}>
+                  <div>
+                    {scalingGroupComponent}
+                  </div>
+                  <div className="cardSectionFooter">
+                  </div>
+              </TabPanel>
+            );
+          }
+          if(cardData.hasOwnProperty('vnfd-placement-group-maps')
+             || cardData.hasOwnProperty('nsd-placement-group-maps')) {
+            tabList.push(
+               <Tab key='placement_groups'>
+                Placement
+               </Tab>
+             );
+            tabPanels.push(
+               <TabPanel key='placement_groups_panel'>
+                  <div>
+                    <PlacementGroupsInfo nsr={cardData} navRef={this.props.navRef} />
+                  </div>
+              </TabPanel>
+             );
+          }
+        }
+
+        if (configPrimitiveComponent) {
+          let primitivesTabTitle = '';
+          if (this.props.type == 'nsr') {
+            primitivesTabTitle = 'Service Primitive';
+          } else if (this.props.type == 'vnfr') {
+            primitivesTabTitle = 'Service Primitive'
+          }
+
+          tabList.push(
+            <Tab key={cardData.id + '-cp'}>{primitivesTabTitle}</Tab>
+          );
+
+          tabPanels.push(
+            <TabPanel key={cardData.id + '-cp-panel'}>
+              <div className="configPrimitives">
+                {configPrimitiveComponent}
+              </div>
+              <div className="cardSectionFooter">
+              </div>
+            </TabPanel>
+          )
+        }
+
+        if (nsVirtualLinksComponent) {
+          let nsVirtualLinksTabTitle = 'Virtual Links';
+          tabList.push(
+              <Tab key={cardData.id + '-nsvl'}>{nsVirtualLinksTabTitle}</Tab>
+          );
+
+          tabPanels.push(
+            <TabPanel key={cardData.id + '-nsvl-panel'}>
+              <div className='nsVirtualLinks'>
+                {nsVirtualLinksComponent}
+              </div>
+              <div className="cardSectionFooter">
+              </div>
+            </TabPanel>
+          );
+        }
+
+        if (consoleUrlsComponent) {
+          let consoleUrlsTabTitle = '';
+          consoleUrlsTabTitle = 'VDU Console Links';
+          
+          tabList.push(
+            <Tab key={cardData.id + '-cp'}>{consoleUrlsTabTitle}</Tab>
+          );
+
+          tabPanels.push(
+            <TabPanel key={cardData.id + '-cp-panel'}>
+              <div className="consoleUrls">
+                {consoleUrlsComponent}
+              </div>
+              <div className="cardSectionFooter">
+              </div>
+            </TabPanel>
+          )
+        }
+
+        html = (
+            <DashboardCard className="recordCard" showHeader={true} title={cardData["short-name"]}>
+              <a onClick={this.props.recordDetailsToggleFn} className={"recordViewToggle " + (this.props.recordDetailsToggleValue ? "on": null)}><span className="oi" data-glyph={glyphValue} title="Toggle Details Panel" aria-hidden="true"></span></a>
+              <Tabs onSelect={this.handleSelect}>
+                <TabList>
+                    {tabList}
+                </TabList>
+                {tabPanels}
+              </Tabs>
+            </DashboardCard>
+        );
+      }
+    return html;
+  }
+}
+RecordCard.defaultProps = {
+  type: "default",
+  data: {},
+  isLoading: true,
+  jobData: []
+}
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordDetails.jsx b/skyquake/plugins/launchpad/src/recordViewer/recordDetails.jsx
new file mode 100644 (file)
index 0000000..0a3e35e
--- /dev/null
@@ -0,0 +1,44 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import LoadingIndicator from 'widgets/loading-indicator/loadingIndicator.jsx';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import Prism from 'prismjs';
+import 'prismjs/themes/prism.css';
+export default class RecordDetails extends React.Component{
+  constructor(props) {
+    super(props)
+  }
+  render(){
+    let html;
+    let text = JSON.stringify(this.props.data, undefined, 2);
+    // html = this.props.isLoading ? <LoadingIndicator size={10} show={true} /> : <pre className="json">{JSON.stringify(this.props.data, undefined, 2)}</pre>;
+    html = this.props.isLoading ? <LoadingIndicator size={10} show={true} /> : Prism.highlight(text, Prism.languages.javascript, 'javascript');
+    return (
+            <DashboardCard showHeader={true} title="Record Details" className={this.props.isLoading ? 'loading' : 'recordDetails'}>
+              <pre className="language-js">
+              <code dangerouslySetInnerHTML={{__html: html}} />
+              </pre>
+            </DashboardCard>
+            );
+  }
+}
+RecordDetails.defaultProps = {
+  data: {}
+}
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordNavigator.jsx b/skyquake/plugins/launchpad/src/recordViewer/recordNavigator.jsx
new file mode 100644 (file)
index 0000000..d7a86d4
--- /dev/null
@@ -0,0 +1,107 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import RecordViewActions from './recordViewActions.js';
+import LoadingIndicator from 'widgets/loading-indicator/loadingIndicator.jsx';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import './recordNavigator.scss';
+import nsdImg from 'style/img/catalog-default.svg';
+
+export default class RecordNavigator extends React.Component{
+  constructor(props) {
+    super(props)
+  }
+  render(){
+    let navClass = 'catalogItems';
+
+    let self = this;
+    let html;
+    let className = this.props.isLoading ? 'loading' : '';
+    let nav = [];
+
+    this.props.nav.map(function(n, k) {
+      let itemClassName = navClass + '_item';
+      let catalog_name = (n.type == 'nsr' ? <span>({n.nsd_name})</span> : '');
+      let scalingGroupClass = '';
+      let scalingGroupTitleClass = '';
+      let scalingGroupTitle = '';
+      let navObj = [];
+      if (n.scalingGroupName) {
+        scalingGroupClass = navClass + ' -is-scaled';
+        scalingGroupTitleClass = scalingGroupClass + '_title';
+        scalingGroupTitle = n.scalingGroupName + '_' + n.scalingGroupInstanceId;
+        n.vnfr && n.vnfr.map((vnfr, vnfrIndex) => {
+          let iClassName = itemClassName;
+          if(vnfr.id == self.props.activeNavID) {
+            iClassName += ' -is-selected';
+          }
+          navObj.push(
+            <div key={'id' + k + '-' + vnfr.id}  onClick={self.props.loadRecord.bind(self,vnfr)} className={iClassName}>
+              <img src={nsdImg} />
+              <section id={vnfr.id}>
+              <h1 title={vnfr.name}>{vnfr.name}</h1>
+                <h2>{vnfr.type}</h2>
+              </section>
+            </div>
+          )
+        });
+      } else {
+        if(n.id == self.props.activeNavID) {
+          itemClassName += ' -is-selected';
+        }
+        navObj.push(
+          <div key={'id' + k + '-' + n.id}  onClick={self.props.loadRecord.bind(self,n)} className={itemClassName}>
+            <img src={nsdImg} />
+            <section id={n.id}>
+            <h1 title={n.name}>{n.name}</h1>
+              <h2>{n.type}</h2>
+            </section>
+          </div>
+        );
+      }
+      nav.push(
+        <li className={scalingGroupClass} key={"scalingGroupTile-" + k}>
+          <div className={scalingGroupTitleClass}>
+            {scalingGroupTitle}
+          </div>
+          {navObj}
+        </li>
+      )
+    })
+    if(this.props.isLoading) {
+        html = <DashboardCard className="loading" showHeader={true} title="Loading..."><LoadingIndicator size={10} show={true} /></DashboardCard>
+    } else {
+        html = (
+          <DashboardCard showHeader={true} title="Select Record" className={"recordNavigator" + className}>
+            <ul className="catalogItems">
+              {
+                nav
+              }
+            </ul>
+          </DashboardCard>
+        );
+    }
+    return html;
+  }
+}
+RecordNavigator.defaultProps = {
+  nav: []
+}
+
+
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordNavigator.scss b/skyquake/plugins/launchpad/src/recordViewer/recordNavigator.scss
new file mode 100644 (file)
index 0000000..dfc993c
--- /dev/null
@@ -0,0 +1,130 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+
+.recordNavigator{
+  .catalogItems {
+    display:flex;
+    flex-wrap:wrap;
+    justify-content:flex-start;
+    flex-direction:row;
+    font-family: Roboto, Helvetica, Arial, sans-serif;
+
+    &.-is-scaled {
+      margin: 0.25rem 0;
+      background: $gray;
+      border-radius: 8px;
+      padding: 0 0 0.25rem 0;
+      color: $black !important;
+      &_title {
+        padding: 0.5rem;
+        &:hover {
+          font-style: normal;
+        }
+      }
+    }
+
+    &_item {
+      flex: 1 1 100%;
+      // background-color:$darker-gray;
+      background-color: #fff;
+      margin: 0.3rem 1rem;
+      // flex: 0 1 49%;
+      position: relative;
+      height: 4pc;
+      overflow: hidden;
+      border-radius: 8px;
+      padding:0.5rem;
+      color: #d9d9d9;
+      font-weight: 100;
+      font-style: normal;
+      -webkit-user-select: none;
+      display:flex;
+      cursor:pointer;
+
+      h1 {
+        font-size: 1.125rem;
+        max-width: 260px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+
+      &:hover{
+          background-color: #7e9bc1;
+          cursor: pointer;
+          color: white;
+          h2 {
+              color: #000;
+          }
+          abbr, span {
+            color: white;
+          }
+        }
+
+      >div {
+        display:flex;
+        flex-direction:column;
+      }
+      &.-is-selected {
+        outline: 2px dashed $brand-blue;
+        outline-offset: 2px;
+
+        background-color: #7e9bc1;
+        cursor: pointer;
+        color: white;
+        span, abbr {
+          color:white;
+        }
+      }
+      img {
+        width: 50px;
+        height: 50px;
+        align-self: center;
+      }
+      section {
+        padding-left:0.5rem;
+        display:flex;
+        flex-direction:column;
+        flex: 1 1 95%;
+        justify-content: center;
+        padding: 0.125rem 0.75rem;
+        abbr {
+          font-weight:bold;
+        }
+        abbr,span {
+              display: block;
+      color: $gray-dark;
+      border: 0;
+      // color: #ef8354;
+      font-family: monospace,serif;
+      font-size: .7rem;
+      white-space: nowrap;
+        }
+      }
+      section, h2 {
+        margin: 0 0 4px;
+        font-weight: normal;
+        font-size: .8125rem;
+        color:black;
+        white-space: nowrap;
+      }
+    }
+  }
+
+}
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordView.jsx b/skyquake/plugins/launchpad/src/recordViewer/recordView.jsx
new file mode 100644 (file)
index 0000000..224bad5
--- /dev/null
@@ -0,0 +1,115 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import RecordNavigator from './recordNavigator.jsx';
+import RecordCard from './recordCard.jsx';
+import RecordDetails from './recordDetails.jsx';
+import RecordViewStore from './recordViewStore.js';
+import RecordViewActions from './recordViewActions.js';
+import LaunchpadBreadcrumbs from '../launchpadBreadcrumbs.jsx';
+import Utils from 'utils/utils.js';
+import AppHeader from 'widgets/header/header.jsx';
+import './recordViewer.scss';
+export default class RecordView extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = RecordViewStore.getState();
+    this.state.showRecordDetails = false;
+    this.state.jobData = [];
+    RecordViewStore.listen(this.storeListener);
+  }
+  storeListener = (state) => {
+    this.setState(state);
+  }
+  componentWillUnmount = () => {
+    RecordViewStore.handleCloseSocket();
+    RecordViewStore.handleCloseJobSocket();
+    RecordViewStore.unlisten(this.storeListener);
+  }
+  componentDidMount() {
+    let nsrRegEx = new RegExp("([0-9a-zA-Z-]+)\/detail");
+    let nsr_id;
+    try {
+      console.log('NSR ID in url is', this.props.location.query);
+      console.log(this.props)
+      nsr_id =  this.props.location.query.id;
+    } catch (e) {
+
+    }
+    RecordViewStore.getNSR(nsr_id);
+    RecordViewStore.getRawNSR(nsr_id);
+    RecordViewStore.getNSRSocket(nsr_id);
+    RecordViewStore.getConfigJobSocket(nsr_id);
+  }
+  loadRecord = (record) => {
+    RecordViewActions.loadRecord(record);
+    RecordViewStore['getRaw' + record.type.toUpperCase()](record.id)
+    RecordViewStore['get' + record.type.toUpperCase() + 'Socket'](record.id)
+  }
+  recordDetailsToggle = () => {
+    this.setState({
+      showRecordDetails: !this.state.showRecordDetails
+    })
+  }
+  render() {
+    let {location} = this.props;
+    let html;
+    let mgmtDomainName = window.location.hash.split('/')[2];
+    let recordDetails = this.state.showRecordDetails || null;
+    let nsrId = 0;
+    let navItems = [{
+      name: 'Viewport'
+    },{
+      name: 'COMPUTE TOPOLOGY',
+      onClick: this.context.router.push.bind(this, {pathname:'/compute-topology', query: {id: location.query.id, sdnpresent: location.query.sdnpresent}})
+    }];
+
+    if (location.query.sdnpresent == 'true') {
+      navItems.push({
+         name: 'NETWORK TOPOLOGY',
+               onClick: this.context.router.push.bind(this, {pathname:'/network-topology', query: {id: location.query.id, sdnpresent: location.query.sdnpresent}})
+      });
+    }
+
+    let nav = <AppHeader nav={navItems} />
+    if (this.state.showRecordDetails) {
+      recordDetails = <RecordDetails isLoading={this.state.detailLoading} data={this.state.rawData} />
+    }
+    html = (
+      <div className="app-body recordView">
+      {nav}
+        <div className="recordViewer">
+          <i className="corner-accent top left"></i>
+          <i className="corner-accent top right"></i>
+          <div className="dashboardCard_wrapper recordPanels">
+            <RecordNavigator activeNavID={this.state.recordID} nav={this.state.nav} loadRecord={this.loadRecord} isLoading={this.state.isLoading} />
+            <RecordCard jobData={this.state.jobData} isLoading={this.state.cardLoading} type={this.state.recordType} data={this.state.recordData} recordDetailsToggleValue={this.state.showRecordDetails} vnfrs={this.state.vnfrs} navRef={this.state.nav} recordDetailsToggleFn={this.recordDetailsToggle} />
+            {recordDetails}
+          </div>
+          <i className="corner-accent bottom left"></i>
+          <i className="corner-accent bottom right"></i>
+        </div>
+      </div>
+    );
+    return html;
+  }
+}
+RecordView.contextTypes = {
+    router: React.PropTypes.object
+};
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordViewActions.js b/skyquake/plugins/launchpad/src/recordViewer/recordViewActions.js
new file mode 100644 (file)
index 0000000..a9d5250
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from '../alt';
+
+export default Alt.generateActions(
+                                   'getNSRSuccess','getNSRError','getNSRLoading',
+                                   'getVNFRSocketLoading','getVNFRSocketError','getVNFRSocketSuccess',
+                                   'getNSRSocketSuccess','getNSRSocketError','getNSRSocketLoading',
+                                   'getRawSuccess','getRawError','getRawLoading',
+                                   'loadRecord',
+                                   'constructAndTriggerConfigPrimitive',
+                                   'execNsConfigPrimitiveLoading', 'execNsConfigPrimitiveSuccess', 'execNsConfigPrimitiveError',
+                                   'createScalingGroupInstanceLoading', 'createScalingGroupInstanceSuccess', 'createScalingGroupInstanceError',
+                                   'deleteScalingGroupInstanceLoading', 'deleteScalingGroupInstanceSuccess', 'deleteScalingGroupInstanceError',
+                                   'getConfigSocketJobSuccess',
+                                   'getConfigSocketJobLoading',
+                                   'getConfigSocketJobError',
+                                   'createVirtualLinkLoading', 'createVirtualLinkSuccess', 'createVirtualLinkError',
+                                   'editVirtualLinkLoading', 'editVirtualLinkSuccess', 'editVirtualLinkError',
+                                   'deleteVirtualLinkLoading', 'deleteVirtualLinkSuccess', 'deleteVirtualLinkError',
+                                   );
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordViewSource.js b/skyquake/plugins/launchpad/src/recordViewer/recordViewSource.js
new file mode 100644 (file)
index 0000000..97c7bc1
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import RecordViewActions from './recordViewActions.js';
+let Utils = require('utils/utils.js');
+import $ from 'jquery';
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = require('utils/rw.js').getSearchParams(window.location).dev_mode || false;
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+export default {
+    getNSR() {
+        return {
+            remote: function(state, recordID) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + recordID + '?api_server=' + API_SERVER,
+                        type: 'GET',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    }).fail(function(xhr) {
+                        //Authentication and the handling of fail states should be wrapped up into a connection class.
+                        Utils.checkAuthentication(xhr.status);
+                    });;
+                });
+            },
+            loading: RecordViewActions.getNSRLoading,
+            success: RecordViewActions.getNSRSuccess,
+            error: RecordViewActions.getNSRError
+        };
+    },
+    getRawVNFR() {
+        return {
+            remote: function(state, vnfrID) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'passthrough/data/api/operational/vnfr-catalog/vnfr/' + vnfrID + '?api_server=' + API_SERVER,
+                        type: 'GET',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.getRawLoading,
+            success: RecordViewActions.getRawSuccess,
+            error: RecordViewActions.getRawError
+        }
+    },
+    getRawNSR() {
+        return {
+            remote: function(state, nsrID) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'passthrough/data/api/operational/ns-instance-opdata/nsr/' + nsrID + '?api_server=' + API_SERVER,
+                        type: 'GET',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.getRawLoading,
+            success: RecordViewActions.getRawSuccess,
+            error: RecordViewActions.getRawError
+        }
+    },
+    getNSRSocket() {
+        return {
+            remote(state, recordID) {
+                return new Promise(function(resolve, reject) {
+                    console.log('Getting NSR Socket');
+                    $.ajax({
+                        url: '/socket-polling?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        data: {
+                            url: '/launchpad/api/nsr/' + recordID + '?api_server=' + API_SERVER,
+                        },
+                        success: function(data) {
+                            Utils.checkAndResolveSocketRequest(data, resolve, reject);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.getNSRSocketLoading,
+            success: RecordViewActions.getNSRSocketSuccess,
+            error: RecordViewActions.getNSRSocketError
+        }
+    },
+    getConfigJobSocket() {
+        return {
+            remote(state, recordID) {
+                return new Promise(function(resolve, reject) {
+                    console.log('Getting Job Socket');
+                    $.ajax({
+                        url: '/socket-polling?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        data: {
+                            url: '/launchpad/api/nsr/' + recordID + '?api_server=' + API_SERVER,
+                        },
+                        success: function(data) {
+                            Utils.checkAndResolveSocketRequest(data, resolve, reject);
+                        }
+                    });
+                })
+            },
+            success: RecordViewActions.getConfigSocketJobSuccess,
+            error: RecordViewActions.getConfigSocketJobError
+        }
+    },
+    getVNFRSocket() {
+        return {
+            remote(state) {
+                return new Promise(function(resolve, reject) {
+                    console.log('Getting VNFR Socket for: ' + state.recordID);
+                    $.ajax({
+                        url: '/socket-polling?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        data: {
+                            url: '/launchpad/api/vnfr/' + state.recordID + '?api_server=' + API_SERVER,
+                        },
+                        success: function(data) {
+                            Utils.checkAndResolveSocketRequest(data, resolve, reject);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.getVNFRSocketLoading,
+            success: RecordViewActions.getVNFRSocketSuccess,
+            error: RecordViewActions.getVNFRSocketError
+        }
+    },
+    execNsConfigPrimitive() {
+        return {
+            remote(state, payload) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/exec-ns-service-primitive?api_server=' + API_SERVER,
+                        type: 'POST',
+                        data: payload,
+                        dataType: 'json',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.execNsConfigPrimitiveLoading,
+            success: RecordViewActions.execNsConfigPrimitiveSuccess,
+            error: RecordViewActions.execNsConfigPrimitiveError
+        }
+    },
+    createScalingGroupInstance() {
+        return {
+            remote(state, params) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + params.nsr_id + '/' + params.scaling_group_id + '/instance' + '?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.createScalingGroupInstanceLoading,
+            success: RecordViewActions.createScalingGroupInstanceSuccess,
+            error: RecordViewActions.createScalingGroupInstanceError
+        }
+    },
+    deleteScalingGroupInstance() {
+        return {
+            remote(state, params) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + params.nsr_id + '/' + params.scaling_group_id + '/instance/' + params.scaling_instance_index + '?api_server=' + API_SERVER,
+                        type: 'DELETE',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.deleteScalingGroupInstanceLoading,
+            success: RecordViewActions.deleteScalingGroupInstanceSuccess,
+            error: RecordViewActions.deleteScalingGroupInstanceError
+        }
+    },
+    createVirtualLink() {
+        return {
+            remote(state, params) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + params.nsr_id + '/vld' + '?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.createVirtualLinkLoading,
+            success: RecordViewActions.createVirtualLinkSuccess,
+            error: RecordViewActions.createVirtualLinkError
+        }
+    },
+    deleteVirtualLink() {
+        return {
+            remote(state, params) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + params.nsr_id + '/vld/' + params.vldId + '?api_server=' + API_SERVER,
+                        type: 'DELETE',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.deleteVirtualLinkLoading,
+            success: RecordViewActions.deleteVirtualLinkSuccess,
+            error: RecordViewActions.deleteVirtualLinkError
+        }
+    },
+    editVirtualLink() {
+        return {
+            remote(state, params) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + params.nsr_id + '/vld/' + params.vldId + '?api_server=' + API_SERVER,
+                        type: 'PUT',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    });
+                })
+            },
+            loading: RecordViewActions.editVirtualLinkLoading,
+            success: RecordViewActions.editVirtualLinkSuccess,
+            error: RecordViewActions.editVirtualLinkError
+        }
+    }
+
+}
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordViewStore.js b/skyquake/plugins/launchpad/src/recordViewer/recordViewStore.js
new file mode 100644 (file)
index 0000000..fbdae39
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import RecordViewActions from './recordViewActions.js';
+import RecordViewSource from './recordViewSource.js';
+// import source
+// import AppHeaderActions from 'widgets/header/headerActions.js';
+import Alt from '../alt';
+import _ from 'underscore';
+
+class RecordViewStore {
+    constructor() {
+        this.isLoading = true;
+        this.cardLoading = true;
+        this.detailLoading = true;
+        //Reference to current socket
+        this.socket = null;
+        //Reference to current record type
+        //"vnfr", "nsr", "default"
+        this.recordType = "default";
+        //Reference to current record ID
+        //uuid or null
+        this.recordID = null;
+        //Record data
+        //object or null
+        this.recordData = null;
+        this.nav = [];
+        this.vnfrs = {};
+        this.configPrimitives = [];
+        this.jobData = [];
+        this.bindActions(RecordViewActions);
+        this.exportPublicMethods({
+            constructAndTriggerVnfConfigPrimitive: this.constructAndTriggerVnfConfigPrimitive,
+            constructAndTriggerNsConfigPrimitive: this.constructAndTriggerNsConfigPrimitive,
+            triggerCreateScalingGroupInstance: this.triggerCreateScalingGroupInstance,
+            triggerDeleteScalingGroupInstance: this.triggerDeleteScalingGroupInstance,
+            validateInputs: this.validateInputs,
+            handleCloseSocket: this.handleCloseSocket,
+            handleCloseJobSocket: this.handleCloseJobSocket,
+            triggerCreateVirtualLink: this.triggerCreateVirtualLink,
+            triggerEditVirtualLink: this.triggerEditVirtualLink,
+            triggerDeleteVirtualLink: this.triggerDeleteVirtualLink
+        })
+        this.exportAsync(RecordViewSource);
+    }
+    handleLogout = () => {
+
+    }
+    handleCloseSocket = () => {
+        if (this.socket) {
+            window.multiplexer.channel(this.channelId).close();
+        }
+    }
+    handleCloseJobSocket = () => {
+        if (this.jobSocket) {
+            window.multiplexer.channel(this.jobSocketChannelId).close();
+        }
+    }
+    loadRecord(record) {
+        this.setState({
+            cardLoading: true,
+            recordID: record.id
+        });
+    }
+    getNSRSocketLoading() {
+        this.setState({
+            cardLoading: true
+        })
+    }
+    getVNFRSocketLoading() {
+        this.setState({
+            cardLoading: true
+        })
+    }
+    getConfigSocketJobSuccess(connection) {
+        let self = this;
+        let ws = window.multiplexer.channel(connection);
+        if (!connection) {
+            console.warn('There was an issue connecting to the Config Job socket');
+            return;
+        }
+        if (self.socket) {
+            self.handleCloseJobSocket();
+        }
+
+        self.setState({
+            jobSocket: ws.ws,
+            jobSocketChannelId: connection
+        });
+        ws.onmessage = function(data) {
+            let jobData = JSON.parse(data.data);
+            jobData = jobData.nsrs[0]["config-agent-job"] || [];
+            self.setState({jobData:jobData});
+        };
+        ws.onerror = function(data) {
+            console.log('err', data)
+        }
+    }
+    getVNFRSocketSuccess(connection) {
+        // debugger;
+        connectionManager.call(this, 'vnfr', connection);
+    }
+    getNSRSocketSuccess(connection) {
+        connectionManager.call(this, 'nsr', connection);
+    }
+    getRawLoading() {
+        this.setState({
+            detailLoading: true
+        })
+    }
+    getRawSuccess(data) {
+        this.setState({
+            rawData: data,
+            detailLoading: false
+        })
+    }
+    getNSRSuccess(data) {
+
+    }
+    constructAndTriggerVnfConfigPrimitive(data) {
+        let vnfrs = data.vnfrs;
+        let vnfrIndex = data.vnfrIndex;
+        let configPrimitiveIndex = data.configPrimitiveIndex;
+        let payload = {};
+        let isValid = false;
+        let configPrimitive = vnfrs[vnfrIndex]['vnf-configuration']['service-primitive'][configPrimitiveIndex];
+
+        payload['name'] = '';
+        payload['nsr_id_ref'] = vnfrs[vnfrIndex]['nsr-id-ref'];
+        payload['vnf-list'] = [];
+        payload['triggered-by'] = 'vnf-primitive';
+        let parameters = [];
+        configPrimitive['parameter'].map((parameter) => {
+            if(!isValid) {
+                isValid = validateParameter(parameter);
+            }
+            parameters.push({
+                name: parameter['name'],
+                value: parameter['value'] || parameter['default-value']
+            });
+        });
+
+        let vnfPrimitive = [];
+        vnfPrimitive[0] = {
+            name: configPrimitive['name'],
+            index: configPrimitiveIndex,
+            parameter: parameters
+        }
+
+        payload['vnf-list'].push({
+            'member_vnf_index_ref': vnfrs[vnfrIndex]['member-vnf-index-ref'],
+            'vnfr-id-ref': vnfrs[vnfrIndex]['id'],
+            'vnf-primitive': vnfPrimitive
+        })
+        if (isValid) {
+            this.execNsConfigPrimitive(payload);
+        }
+        return isValid;
+    }
+    constructAndTriggerNsConfigPrimitive(data) {
+        let nsConfigPrimitiveIndexToExecute = data.nsConfigPrimitiveIndex;
+        let nsConfigPrimitives = data.nsConfigPrimitives;
+        let nsConfigPrimitive = data.nsConfigPrimitives[nsConfigPrimitiveIndexToExecute];
+
+        let payload = {
+            name: nsConfigPrimitive['name'],
+            nsr_id_ref: nsConfigPrimitive['nsr_id_ref'],
+            'vnf-list': [],
+            'parameter': [],
+            'parameter-group': [],
+        };
+        let vnfList = [];
+        nsConfigPrimitive['vnf-primitive-group'].map((vnf) => {
+
+            let vnfPrimitiveList = []
+            vnf['inputs'].map((vnfPrimitive) => {
+
+                let parameterList = [];
+
+                const filterAndAddByValue = (paramObj) => {
+                    if (paramObj['value'] != undefined) {
+                        parameterList.push({
+                            name: paramObj.name,
+                            value: paramObj.value
+                        });
+                    }
+                    return paramObj['value'] != undefined;
+                }
+
+                vnfPrimitive['parameter'].filter(filterAndAddByValue);
+
+                if (parameterList.length > 0) {
+                    vnfPrimitiveList.push({
+                        name: vnfPrimitive['name'],
+                        index: vnfPrimitive['index'],
+                        parameter: parameterList
+                    });
+                }
+            });
+
+            vnfList.push({
+                'member_vnf_index_ref': vnf['member-vnf-index-ref'],
+                'vnfr-id-ref': vnf['vnfr-id-ref'],
+                'vnf-primitive': vnfPrimitiveList
+            });
+        });
+
+        payload['vnf-list'] = vnfList;
+
+        let nsConfigPrimitiveParameterGroupParameters = [];
+        nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((nsConfigPrimitiveParameterGroup) => {
+            let nsConfigPrimitiveParameters = [];
+            nsConfigPrimitiveParameterGroup['parameter'] && nsConfigPrimitiveParameterGroup['parameter'].map((nsConfigPrimitiveParameterGroupParameter) => {
+                if (nsConfigPrimitiveParameterGroupParameter['value'] != undefined) {
+                    nsConfigPrimitiveParameters.push({
+                        'name': nsConfigPrimitiveParameterGroupParameter.name,
+                        'value': nsConfigPrimitiveParameterGroupParameter.value
+                    });
+                }
+            });
+            nsConfigPrimitiveParameterGroupParameters.push({
+                'name': nsConfigPrimitiveParameterGroup.name,
+                'parameter': nsConfigPrimitiveParameters
+            });
+        });
+
+        payload['parameter-group'] = nsConfigPrimitiveParameterGroupParameters;
+
+        let nsConfigPrimitiveParameters = [];
+        nsConfigPrimitive['parameter'] && nsConfigPrimitive['parameter'].map((nsConfigPrimitiveParameter) => {
+            if (nsConfigPrimitiveParameter['value'] != undefined && nsConfigPrimitiveParameter['value'] != ""
+                )
+            {
+                nsConfigPrimitiveParameters.push({
+                    'name': nsConfigPrimitiveParameter.name,
+                    'value': nsConfigPrimitiveParameter.value
+                });
+            } else {
+                if ( (nsConfigPrimitiveParameter['value'] == undefined)
+                   && nsConfigPrimitiveParameter['default-value']) {
+                    nsConfigPrimitiveParameters.push({
+                        'name': nsConfigPrimitiveParameter.name,
+                        'value': nsConfigPrimitiveParameter['default-value']
+                    });
+                }
+            }
+        });
+
+        payload['parameter'] = nsConfigPrimitiveParameters;
+
+        this.execNsConfigPrimitive(payload);
+    }
+    execNsConfigPrimitiveSuccess(data) {}
+    createScalingGroupInstanceSuccess(data) {}
+    deleteScalingGroupInstanceSuccess(data) {}
+    triggerCreateScalingGroupInstance(params) {
+        this.createScalingGroupInstance(params);
+    }
+    triggerDeleteScalingGroupInstance(params) {
+        this.deleteScalingGroupInstance(params);
+    }
+    validateInputs(data) {
+        let nsConfigPrimitiveIndexToExecute = data.nsConfigPrimitiveIndex;
+        let nsConfigPrimitives = data.nsConfigPrimitives;
+        let nsConfigPrimitive = data.nsConfigPrimitives[nsConfigPrimitiveIndexToExecute];
+        let isValid = true;
+        //Check parameter groups for required fields
+        nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup, parameterGroupIndex) => {
+            let isMandatory = parameterGroup.mandatory != 'false';
+            let optionalChecked = parameterGroup.optionalChecked;
+            let isActiveOptional = (optionalChecked && !isMandatory);
+            if (isActiveOptional || isMandatory) {
+                parameterGroup['parameter'] && parameterGroup['parameter'].map((parameter, parameterIndex) => {
+                    let msg = 'Parameter Group: ' + parameterGroup.name + ' is not valid';
+                    if (isValid) {
+                        isValid = validateParameter(parameter);
+                    }
+                });
+            }
+        });
+
+        //Check top level parameters for required fields
+        nsConfigPrimitive['parameter'] && nsConfigPrimitive['parameter'].map((parameter, parameterIndex) => {
+                if (isValid) {
+                    isValid = validateParameter(parameter);
+                }
+        });
+
+        nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfPrimitiveGroup, vnfPrimitiveGroupIndex) => {
+            vnfPrimitiveGroup['inputs'] && vnfPrimitiveGroup['inputs'].map((input, inputIndex) => {
+                input['parameter'] && input['parameter'].map((param) => {
+                    if (isValid) {
+                        isValid = validateParameter(param);
+                    }
+                })
+            })
+        });
+
+        return isValid;
+    }
+
+    createVirtualLinkSuccess(data) {}
+    editVirtualLinkSuccess(data) {}
+    deleteVirtualLinkSuccess(data) {}
+
+    triggerCreateVirtualLink(params) {
+        this.createVirtualLink(params);
+    }
+
+    triggerDeleteVirtualLink(params) {
+        this.deleteVirtualLink(params);
+    }
+
+    triggerEditVirtualLink(params) {
+        this.editVirtualLink(params);
+    }
+
+}
+
+
+
+function validateParameter(parameter, msg) {
+    if ((parameter['hidden'] == 'true') || (parameter['read-only'] == 'true')) {
+        if (!parameter['default-value']) {
+            var errorMsg = 'Your descriptor has hidden or read-only parameters with no default-values. Please rectify this.';
+            console.log(errorMsg);
+            return false;
+        } else {
+            parameter.value = parameter['default-value'];
+        }
+    }
+
+    if (parameter.mandatory == "true") {
+        if(parameter.hasOwnProperty('value')){
+            if (!parameter.value) {
+                return false;
+            }
+        } else {
+            if (!parameter['default-value']) {
+                return false;
+            } else {
+                parameter.value = parameter['default-value'];
+            }
+        }
+    };
+
+    // if (parameter.value == '' || !parameter.value) {
+    //     if (parameter['default-value']) {
+    //         parameter.value = parameter['default-value'];
+    //     }
+    // };
+
+    return true;
+};
+
+function connectionManager(type, connection) {
+    let self = this;
+    let ws = window.multiplexer.channel(connection);
+    if (!connection) {
+        console.warn('There was an issue connecting to the ' + type + ' socket');
+        return;
+    }
+    if (self.socket) {
+        self.handleCloseSocket();
+    }
+
+    self.setState({
+        socket: ws.ws,
+        channelId: connection
+    });
+    ws.onmessage = function(data) {
+
+        let recordData = JSON.parse(data.data);
+
+        let nsrsData = recordData['nsrs'] || null;
+
+        let navigatorState = {};
+
+        if (nsrsData) {
+            let nav = [];
+            let nsrs = nsrsData[0];
+            nav.push({
+                name: nsrs.name,
+                id: nsrs.id,
+                nsd_name: nsrs.nsd_name,
+                type: 'nsr'
+            });
+
+            // Scaled VNFRs
+            let scaledVnfrs = [];
+
+            nsrs['scaling-group-record'] && nsrs['scaling-group-record'].map((sgr, sgrIndex) => {
+                sgr['instance'] && sgr['instance'].map((sgInstance, sgInstanceIndex) => {
+                    let scaledVnfNav = {
+                        type: 'sgr',
+                        scalingGroupName: sgr['scaling-group-name-ref'],
+                        scalingGroupInstanceId: sgInstance['instance-id'],
+                        vnfr: []
+                    }
+
+                    sgInstance['vnfrs'] && sgInstance['vnfrs'].map((vnfr, vnfrIndex) => {
+                        scaledVnfrs.push(vnfr);
+                        scaledVnfNav.vnfr.push({
+                            name: _.findWhere(nsrs.vnfrs, {id: vnfr})['short-name'],
+                            id: vnfr,
+                            type: 'vnfr'
+                        });
+                    });
+                    nav.push(scaledVnfNav);
+                });
+            });
+
+            // Non-scaled VNFRs
+            nsrs.vnfrs.map(function(vnfr, vnfrIndex) {
+                if (_.indexOf(scaledVnfrs, vnfr.id) == -1) {
+                    nav.push({
+                        name: vnfr["short-name"],
+                        id: vnfr.id,
+                        type: 'vnfr'
+                    });
+                }
+            });
+            navigatorState = {
+                nav: nav,
+                recordID: nsrs.id,
+                isLoading: false,
+            };
+        }
+
+        navigatorState = _.extend(navigatorState, {
+            recordData: recordData,
+            recordType: type,
+            cardLoading: false,
+            // ,isLoading: false
+        });
+
+        self.setState(navigatorState);
+    };
+}
+
+export default Alt.createStore(RecordViewStore);
diff --git a/skyquake/plugins/launchpad/src/recordViewer/recordViewer.scss b/skyquake/plugins/launchpad/src/recordViewer/recordViewer.scss
new file mode 100644 (file)
index 0000000..2f3fa75
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+@import '../../node_modules/open-iconic/font/css/open-iconic.css';
+.app-body {
+  >header {
+    padding: 20px 0px;
+/*
+    h1 {
+      background: url('../../../assets/img/header-logo.png') no-repeat;
+      height: 51px;
+      line-height: 51px;
+      margin-left: 80px;
+      padding-left: 118px;
+      left: 0;
+      text-transform: uppercase;
+      font-size: 1.625rem;
+      font-weight: 400;
+    }
+    */
+  }
+  &.recordView{
+    -ms-flex:1;
+        flex:1;
+  }
+  .header-nav {
+    margin: 0rem 1.25rem 1.25rem;
+
+    a {
+      cursor: pointer;
+      margin-left: 0.5rem;
+      font-weight: normal;
+      color: black;
+    }
+    .spacer {
+      padding: 0 0.5rem;
+    }
+    .current {
+      font-weight: bold;
+    }
+  }
+  .recordViewer {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-direction: row;
+        flex-direction: row;
+    -ms-flex-pack: start;
+        justify-content: flex-start; /* align items in Main Axis */
+    -ms-flex-align: stretch;
+        align-items: stretch; /* align items in Cross Axis */
+    -ms-flex-line-pack: stretch;
+        align-content: stretch;
+    -ms-flex: 1;
+        flex: 1;
+    position: relative;
+    margin: 0.5rem;
+    min-width: 900px;
+
+    .recordPanels {
+      display: -ms-flexbox;
+      display: flex;
+      -ms-flex: 1;
+          flex: 1;
+      -ms-flex-direction: row;
+          flex-direction: row;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+      -ms-flex-align: stretch;
+          align-items: stretch;
+      -ms-flex-wrap: nowrap;
+          flex-wrap: nowrap;
+      -ms-flex-line-pack: stretch;
+          align-content: stretch;
+      padding: 0;
+      margin-top: 0.0725rem;
+    }
+    >div {
+      -ms-flex: 1 1 auto;
+          flex: 1 1 auto;
+    }
+    pre.json {
+      white-space: pre-wrap;
+    }
+    header {
+      background-color: white;
+    }
+    .monitoringParams {
+      display: -ms-flexbox;
+      display: flex;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+      -ms-flex:1 0 auto;
+          flex:1 0 auto;
+      span {
+        text-align: center;
+        -ms-flex: 1 1 100%;
+            flex: 1 1 100%;
+        padding: 1rem;
+        font-size: 2rem;
+        display:block;
+      }
+      .mpSlide {
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-flow: row wrap;
+            flex-flow: row wrap;
+        -ms-flex: 1 1 100%;
+            flex: 1 1 100%;
+      }
+    }
+    .recordNavigator.dashboardCard {
+      -ms-flex: 0 1;
+          flex: 0 1;
+      /* min-width: 300px;*/
+      /* max-width: 300px;*/
+      .nsr:before {
+        content: 'NSR: '
+      }
+      .vnfr:before {
+        content: 'VNFR: '
+      }
+      li {
+        cursor: pointer;
+        -ms-flex: 1 1 100%;
+            flex: 1 1 100%;
+      }
+      li:hover {
+        color: $brand-blue;
+      }
+    }
+    .recordCard.dashboardCard {
+      -ms-flex: 1 1 auto;
+          flex: 1 1 auto;
+      min-width: 600px;
+      a {
+          cursor: pointer;
+          margin-left: 0.5rem;
+          font-weight: normal;
+          color: black;
+      }
+      .recordCard_content {
+        padding: 0rem 0;
+      }
+    }
+    .dashboardCard {
+      margin: 0;
+      height: auto;
+      width: auto;
+      -ms-flex: 1;
+          flex: 1;
+
+      .corner-accent {
+        display: none;
+      }
+      &_content {
+        border-right: $gray-dark 1px solid;
+        padding: 1rem 0.5rem;
+        overflow: auto;
+
+        &-body {
+        }
+        .empty {
+          min-height: 50px;
+          max-width:100%;
+          display: -ms-flexbox;
+          display: flex;
+          -ms-flex-pack: center;
+              justify-content: center;
+          -ms-flex-align: center;
+              align-items: center;
+        }
+      }
+      &:last-child {
+        .dashboardCard_content {
+          border-right: none;
+        }
+      }
+      .recordViewToggle {
+        position:absolute;
+        top:1.5rem;
+        right:0.5rem;
+        cursor:pointer;
+        display:-ms-flexbox;
+        display:flex;
+
+        &:before {
+        }
+        &.on:before{
+        }
+      }
+    }
+    .loading_content {
+      -ms-flex-pack: center;
+          justify-content: center;
+      -ms-flex-align: center;
+          -ms-grid-row-align: center;
+          align-items: center;
+    }
+    .recordDetails {
+      -ms-flex: 1 1 20%;
+          flex: 1 1 20%;
+      max-width:600px;
+      &-body{
+          background:#f5f2f0;
+          max-width: 600px;
+      }
+      &_content {
+        padding: 0;
+
+        pre {
+          margin: 0;
+        }
+      }
+    }
+    .launchpadCard_data-list.EPA-PARAMS {
+      height: auto;
+      width: auto;
+      overflow: visible;
+
+      h1 {
+        margin: 0 0 0 0.5rem;
+      }
+    }
+    .launchpadCard_title {
+          -ms-flex: 0 1 auto;
+              flex: 0 1 auto;
+          min-height: 1.25rem;
+    }
+    .nfvi-metrics {
+      -ms-flex:1 0 auto;
+          flex:1 0 auto;
+    }
+    .nfvi-metrics-tray {
+      height: auto;
+      min-height: 150px;
+    }
+    .line-scale-pulse-out-rapid {
+      -ms-flex-item-align: center;
+          align-self: center;
+    }
+    .configPrimitives {
+      display:-ms-flexbox;
+      display:flex;
+      -ms-flex-direction:column;
+          flex-direction:column;
+      -ms-flex: 1 0 auto;
+          flex: 1 0 auto;
+    }
+    .consoleUrls {
+      display:-ms-flexbox;
+      display:flex;
+      -ms-flex-direction:column;
+          flex-direction:column;
+      -ms-flex: 1 0 auto;
+          flex: 1 0 auto;
+    }
+    .consoleUrlsComponent {
+      display: flex;
+      flex: 1 1 auto;
+      .consoleUrlsList {
+        display: flex;
+        flex: 1 1 auto;
+        li {
+          display: flex;
+          flex: 1 1 auto;
+          h3 {
+            align-self: flex-start;
+            flex: 1 1 auto;
+          }
+          a {
+            align-self: flex-end;
+            flex: 1 1 auto;
+          }
+        }
+      }
+    }
+    .cardSectionFooter {
+      -ms-flex: 1 1 100%;
+          flex: 1 1 100%;
+    }
+    .metricBars {
+      display:-ms-flexbox;
+      display:flex;
+      -ms-flex-direction:row;
+          flex-direction:row;
+      -ms-flex-wrap:wrap;
+          flex-wrap:wrap;
+      -ms-flex-pack: distribute;
+          justify-content: space-around;
+      h3 {
+        text-align:center;
+      }
+      .bar {
+        fill: $brand-blue-light;
+        stroke: black;
+      }
+      .y.axis {
+        .domain {
+          transform:scaleX(0.25);
+        }
+      }
+      .x.axis {
+        .domain {
+          transform:scaleY(0.25);
+        }
+      }
+    }
+    .placementGroups {
+      display:-ms-flexbox;
+      display:flex;
+      .sectionHeader {
+        width: 100%;
+        text-transform: uppercase;
+        padding-right: 0;
+        color: #000;
+        background: lightgray;
+        padding: 0.5rem;
+        border-top: 1px solid #f1f1f1;
+        border-bottom: 1px solid #f1f1f1;
+      }
+      .panel{
+        -ms-flex:1 1;
+            flex:1 1;
+        border-right: #999 1px solid;
+        &:last-child {
+          border-right:0px;
+        }
+        &-5{
+          -ms-flex-preferred-size:50%;
+              flex-basis:50%;
+        }
+      }
+      .vdupTable{
+        >div,>dl {
+          display:-ms-flexbox;
+          display:flex;
+          h4, dt, dd{
+            padding:0.5rem 0;
+            -ms-flex:1 1 50%;
+                flex:1 1 50%;
+          }
+          dd {
+            padding-left:1rem;
+            li {
+              cursor:pointer;
+              text-decoration:underline;
+            }
+          }
+        }
+        dl:nth-child(even) {
+          background:$white;
+        }
+        .vdup-title {
+          background: $gray-dark;
+          padding:0 0.5rem;
+        }
+        .nsrType dt, .vnfrType dt, .vduType dt{
+          border-right:1px solid $gray-dark;
+          display: -ms-flexbox;
+          display: flex;
+          -ms-flex-direction: column;
+              flex-direction: column;
+          -ms-flex-pack: center;
+              justify-content: center;
+        }
+        .nsrType{
+          dt>div:first-child{
+            padding-left:0.5rem;
+          }
+        }
+        .vnfrType{
+          dt>div:first-child{
+            padding-left:1rem;
+          }
+        }
+        .vduType{
+          dt>div:first-child{
+            padding-left:1.5rem;
+          }
+        }
+      }
+      .placementGroupDetails {
+          margin:0.5rem;
+        dt {
+          text-transform:uppercase;
+          color:$gray-dark;
+        }
+        dt, dd {
+          margin-bottom:0.5rem;
+        }
+      }
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/settings.js b/skyquake/plugins/launchpad/src/settings.js
new file mode 100644 (file)
index 0000000..e56148c
--- /dev/null
@@ -0,0 +1,102 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+function storageAvailable(type) {
+       try {
+               var storage = window[type];
+               var x = '__storage_test_DEADBEEF__';
+               storage.setItem(x, x);
+               storage.removeItem(x);
+               return true;
+       } catch (e) {
+               return false;
+       }
+}
+
+export class LaunchpadSettings {
+
+  constructor(args) {
+    this.openedNsrsStorageKey = "openedNsrList";
+    this.debug = (args && args.debug);
+
+    if (!storageAvailable('localStorage')) {
+       this.canUseStorage = false;
+       console.log("Unable to use window.localStorage");
+       //throw "Unable to use window.localStorage";
+
+    } else {
+       this.canUseStorage = true;
+    }
+  }    
+  openedNSRs() {
+       if(this.debug) {
+         console.log("LaunchpadSettings.openedNSRs called");   
+       }
+       var nsrs = null;
+       if (this.canUseStorage) {
+               let nsrStr = window.localStorage.getItem(this.openedNsrsStorageKey);
+               if (nsrStr) {
+                       nsrs = nsrStr.split(',');
+               }
+               if (this.debug) {
+                 console.log("got nsr ids=", nsrs);
+               }
+       }
+    return (nsrs) ? nsrs : [];
+  }
+
+  addOpenNSR(nsrId) {
+       let nsrs = this.openedNSRs();
+       if (this.debug) {
+         console.log("LaunchpadSettings.addOpenNSR. nsrs=", nsrs);     
+       }
+       
+       if (!nsrs.includes(nsrId)) {
+               if (this.debug) {
+                 console.log("adding nsr id=", nsrId); 
+               }
+               nsrs.unshift(nsrId);
+               window.localStorage.setItem(this.openedNsrsStorageKey, nsrs);
+       }
+       return this;
+
+  }
+
+  removeOpenNSR(nsrId) {
+       if (this.debug) {
+         console.log("LaunchpadSettings.removeOpenNSR called with id:", nsrId);        
+       }
+       if (this.canUseStorage) {
+               let nsrs = this.openedNSRs().filter(nsr_id => nsr_id != nsrId);
+               window.localStorage.setItem(this.openedNsrsStorageKey, nsrs);
+       }
+       return this;
+  }
+       
+  removeAllOpenNSRs() {
+       if (this.canUseStorage) {
+               window.localStorage.removeItem(this.openedNsrsStorageKey);
+       }
+  }
+}
+
+/*
+module.exports = {
+       LaunchpadSettings: LaunchpadSettings
+}
+*/
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/ssh_keys/sshKeyActions.js b/skyquake/plugins/launchpad/src/ssh_keys/sshKeyActions.js
new file mode 100644 (file)
index 0000000..af43dd3
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from '../alt';
+export default Alt.generateActions(
+                                   'getSshKeySuccess',
+                                   'getSshKeyError',
+                                   'getSshKeyLoading',
+                                   'saveSshKeySuccess',
+                                   'saveSshKeyError',
+                                   'saveSshKeyLoading',
+                                   'UpdateSshKeyPair',
+                                   'deleteSshKeySuccess',
+                                   'updateSshKeySuccess',
+                                   'cancelEditSshKeyPair'
+                                   )
diff --git a/skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.jsx b/skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.jsx
new file mode 100644 (file)
index 0000000..b431b8c
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import './sshKeyCard.scss';
+import React, {Component} from 'react';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import SshKeyActions from './sshKeyActions.js';
+import Button from 'widgets/button/rw.button.js';
+
+export default class SshKeyCard extends Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.isExpanded = false;
+    }
+    cancelEdit(name) {
+            SshKeyActions.cancelEditSshKeyPair(name)
+    }
+    render() {
+        let {className, ...props} = this.props;
+        let editMode = props.editMode.toString().toUpperCase();
+        let editToolsHTML = null;
+        let isInEditMode = null;
+        let isInCreateMode = null;
+        className = "sshKeyCard " + className;
+        isInEditMode = editMode == "TRUE" ? true : false;
+        isInCreateMode = editMode == "CREATE" ? true : false;
+        if(isInEditMode) {
+            editToolsHTML = (
+                <div className="flex">
+                    <span className="oi sshKeyCard-button" data-glyph="circle-check" onClick={props.updateEditSshKeyPair(props.name)}></span>
+                    <span className="oi sshKeyCard-button" data-glyph="circle-x" onClick={props.cancelEditSshKeyPair(props.name)}></span>
+                </div>
+            )
+        } else {
+            if(isInCreateMode) {
+                editToolsHTML = (
+                    <div className="flex">
+                    <Button className="dark" label="Add Key" onClick={props.saveEditSshKeyPair({name: props.name, key: props.value})}></Button>
+                    </div>
+                );
+            } else {
+                editToolsHTML = (
+                    <div className="flex">
+                        <span className="oi sshKeyCard-button" data-glyph="pencil" title="Edit SSH Key" onClick={props.editKey}></span>
+                        <span className="oi sshKeyCard-button" data-glyph="trash" title="Delete SSH Key"  onClick={props.deleteKey}></span>
+                    </div>
+                );
+            }
+        }
+        return (
+            <div className={className}>
+                <TextInput className="sshKeyCard-thumbnail " value={props.name} readonly={true && !isInCreateMode} label="name"
+                 onChange={props.updateSshKeyPair(props.name, 'name')}
+                />
+                <div className="sshKeyCard-body">
+                    <TextInput type="textarea"
+                        className="sshKeyCard-key"
+                        value={props.value}
+                        readonly={!isInEditMode && !isInCreateMode} label="key"
+                        onChange={props.updateSshKeyPair(props.name, 'key')}
+                    />
+                </div>
+                <div className="sshKeyCard-controls">
+                    {
+                        editToolsHTML
+                    }
+                </div>
+            </div>
+        )
+    }
+}
+SshKeyCard.defaultProps = {
+    className: null,
+    editMode: false,
+    saveKey: function(e) {
+        console.log('saving key');
+    },
+    cancelEdit: function(e) {
+        console.log('canceling edit');
+    },
+    editKey: function(e) {
+        console.log('Starting edit')
+    },
+    deleteKey: function(e) {
+        console.log('deleting key')
+    }
+
+
+}
diff --git a/skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.scss b/skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.scss
new file mode 100644 (file)
index 0000000..f72af71
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+
+.sshKeyCard {
+    display:-ms-flexbox;
+    display:flex;
+    -ms-flex-align: start;
+        align-items: flex-start;
+    height:250px;
+    border-top: 1px solid $neutral-white;
+    &:nth-child(odd) {
+        background:$gray-lighter;
+    }
+    &-thumbnail.sqTextInput {
+        -ms-flex:1 1;
+            flex:1 1;
+        width:auto;
+        margin:1rem;
+        > .readonly {
+            background:none !important;
+        }
+    }
+    &-button {
+        font-size:1.25rem;
+        cursor:pointer;
+    }
+    &-body {
+        -ms-flex:1;
+            flex:1;
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-direction:column;
+            flex-direction:column;
+        -ms-flex-pack:justify;
+            justify-content:space-between;
+            flex:1;
+        padding: 1rem;
+        margin-left:0;
+        height:-webkit-fit-content;
+        height:-moz-fit-content;
+        height:fit-content;
+    }
+    &-key.sqTextInput {
+        font-size:1rem;
+        -ms-flex-align: stretch;
+            -ms-grid-row-align: stretch;
+            align-items: stretch;
+            -ms-flex:1;
+                flex:1;
+        > textarea {
+            padding:0.5rem;
+            min-height:190px;
+        }
+        > .readonly {
+            -ms-flex: 1;
+                flex: 1;
+            background: none !important;
+            word-break: break-all;
+        }
+    }
+    &-name {
+        font-weight:bold;
+    }
+    &-subtitle {
+        margin-top:0.25rem;
+    }
+    &-key {
+        width:100%;
+    }
+    &-controls {
+        -ms-flex:0 1 15%;
+            flex:0 1 15%;
+        display:-ms-flexbox;
+        display:flex;
+        -ms-flex-direction:column;
+            flex-direction:column;
+        -ms-flex-pack:center;
+            justify-content:center;
+        -ms-flex-align: center;
+        -ms-grid-row-align: center;
+    align-items: center;
+        height: 100%;
+        border-left: 1px solid $neutral-white;
+        >div {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-pack:justify;
+                justify-content:space-between;
+                >span {
+                    margin:0 1rem;
+                }
+        }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/ssh_keys/sshKeySource.js b/skyquake/plugins/launchpad/src/ssh_keys/sshKeySource.js
new file mode 100644 (file)
index 0000000..2e08b7b
--- /dev/null
@@ -0,0 +1,130 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import $ from 'jquery';
+let Utils = require('utils/utils.js');
+let rw = require('utils/rw.js');
+const API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+const API_PORT = require('utils/rw.js').getSearchParams(window.location).api_port;
+export default function(Alt){
+  const Actions = Alt.actions.global;
+  return {
+  getSshKey: {
+      remote (state) {
+        return new Promise((resolve,reject) => {
+          $.ajax({
+            url: 'api/ssh-key?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function (data) {
+              resolve(data);
+            }
+          }).fail(function(xhr){
+            console.log(xhr)
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });
+        });
+      },
+      loading: Actions.getSshKeyLoading,
+      success: Actions.getSshKeySuccess,
+      error: Actions.getSshKeyError
+  },
+  saveSshKey: {
+      remote (state, pair) {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/ssh-key?api_server=' + API_SERVER,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              "key-pair": [pair]
+            },
+            success: function (data) {
+              resolve(pair);
+            },
+            error: function (err) {
+              console.log('There was an error saving the ssh key')
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+            reject();
+          });
+        })
+      },
+      loading: Actions.saveSshKeyLoading,
+      success: Actions.saveSshKeySuccess,
+      error: Actions.saveSshKeyError
+  },
+  updateSshKey: {
+      remote (state, pair) {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/ssh-key?api_server=' + API_SERVER,
+            type: 'PUT',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              "key-pair": [pair]
+            },
+            success: function (data) {
+              resolve(pair);
+            },
+            error: function (err) {
+              console.log('There was an error updating the ssh key')
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+            reject();
+          });
+        })
+      },
+      loading: Actions.saveSshKeyLoading,
+      success: Actions.updateSshKeySuccess,
+      error: Actions.saveSshKeyError
+  },
+  deleteSshKey: {
+      remote (state, name) {
+        return new Promise((resolve, reject) => {
+          $.ajax({
+            url: 'api/ssh-key/'+ encodeURI(name) + '?api_server=' + API_SERVER,
+            type: 'DELETE',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function (data) {
+              resolve({
+                'status':'success',
+                name: name
+            });
+            },
+            error: function (err) {
+              console.log('There was an error updating the ssh key')
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+            reject();
+          });
+        })
+      },
+      loading: Actions.saveSshKeyLoading,
+      success: Actions.deleteSshKeySuccess,
+      error: Actions.saveSshKeyError
+  }
+}
+}
diff --git a/skyquake/plugins/launchpad/src/ssh_keys/sshKeyStore.js b/skyquake/plugins/launchpad/src/ssh_keys/sshKeyStore.js
new file mode 100644 (file)
index 0000000..400c096
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import SshKeyActions from './sshKeyActions.js';
+import SshKeySource from './sshKeySource.js';
+import GUID from 'utils/guid.js';
+import AppHeaderActions from 'widgets/header/headerActions.js';
+import Alt from '../alt';
+import _ from 'lodash';
+
+
+export default class SshKeyStore {
+    constructor() {
+        this.data = {
+            keys: [],
+            entities: {}
+        };
+        this.dataCache = _.cloneDeep(this.data);
+        this.newKey = {
+          name: '',
+          key: ''
+        };
+        this.bindActions(SshKeyActions);
+        this.registerAsync(SshKeySource);
+        this.exportPublicMethods({
+            updateNewKeyValue: this.updateNewKeyValue,
+            updateSshKeyPair: this.updateSshKeyPair,
+            editSshKeyPair: this.editSshKeyPair,
+            cancelEditSshKeyPair: this.cancelEditSshKeyPair,
+            saveEditSshKeyPair: this.saveEditSshKeyPair,
+            deleteSshKeyPair: this.deleteSshKeyPair,
+            updateEditSshKeyPair: this.updateEditSshKeyPair
+        });
+    }
+    updateNewKeyValue = (k, field) => {
+        let self = this;
+        return function(e) {
+            let value = e.target.value;
+            let ref = self.newKey;
+            ref[field] = value;
+            self.setState({newKey: ref});
+        }
+    }
+    editSshKeyPair = (k) => {
+        let self = this;
+        return function(e) {
+            let data = self.data;
+            let ref = data.entities[k];
+            ref.isEditable = true;
+            self.setState({data:data});
+        }
+    }
+    cancelEditSshKeyPair = (k) => {
+        let self = this;
+        return function(e) {
+            let data = _.cloneDeep(self.data);
+            data.entities[k].key = self.dataCache.entities[k].key;
+            data.entities[k].isEditable = false;
+            self.setState({data:data});
+        }
+    }
+    saveEditSshKeyPair = (data) => {
+        let self = this;
+            return function(e) {
+                if(self.validate(data)) {
+                    self.getInstance().saveSshKey(self.trimName(data)).then(function() {})
+                } else {
+                    self.alt.actions.global.showNotification('Make sure all fields are filled in and that you are using only alphanumeric characters for the name');
+                }
+            }
+    }
+    updateEditSshKeyPair = (k) => {
+        let self = this;
+        return function(e) {
+            self.getInstance().updateSshKey(self.cleanUpKeyPayload(self.data.entities[k]))
+        }
+    }
+    deleteSshKeyPair = (k) => {
+        let self = this;
+        return function(e) {
+            if(window.confirm('Are you sure you want to delete this key?')) {
+                self.getInstance().deleteSshKey(k);
+            }
+        }
+    }
+    saveSshKeySuccess = (data) => {
+        let keys = this.data;
+        keys.keys.push(data.name);
+        keys.entities[data.name] = {
+            name: data.name,
+            key: data.key,
+            isEditable: false
+        };
+        this.setState({
+            dataCache: _.cloneDeep(keys),
+            data: keys,
+            newKey: {
+              name: '',
+              key: ''
+            }
+        })
+    }
+    updateSshKeySuccess = (data) => {
+        let keys = this.data;
+        keys.entities[data.name] = {
+            name: data.name,
+            key: data.key,
+            isEditable: false
+        };
+        this.setState({
+            dataCache: _.cloneDeep(keys),
+            data: keys,
+            newKey: {
+              name: '',
+              key: ''
+            }
+        })
+    }
+    deleteSshKeySuccess = (data) => {
+        let keys = this.data;
+        keys.keys.splice(keys.keys.indexOf(data.name), 1);
+        delete keys.entities[data.name];
+        this.setState({
+            dataCache: _.cloneDeep(keys),
+            data: keys
+        })
+    }
+    saveEditSshKeyPairSuccess = () => {
+
+    }
+    getSshKeySuccess = (data) => {
+        let flattened = this.flattenKeys(data);
+        this.setState({
+            data: flattened,
+            dataCache: _.cloneDeep(flattened)
+        })
+    }
+    updateSshKeyPair = (k, field) => {
+        let self = this;
+        return function(e) {
+            let value = e.target.value;
+            let data = self.data;
+            let ref = data.entities[k];
+            ref[field] = value;
+            self.setState({data:data});
+        }
+    }
+    flattenKeys(data) {
+        var fd = {
+            keys:[],
+            entities: {}
+        };
+        data && data.map(function(d){
+            fd.keys.push(d.name);
+            fd.entities[d.name] = _.merge({isEditable: false}, d)
+        });
+        return fd;
+    }
+    cleanUpKeyPayload(payload) {
+        return {key: payload.key, name: payload.name};
+    }
+    validate(data) {
+        for (let k in data) {
+            if((data[k].trim() == '') || ((/[^\w _-]/).test(data[k]))) {
+                return false;
+            }
+        }
+        return true;
+    }
+    trimName(data) {
+        data.name = data.name.trim();
+        return data;
+    }
+
+}
diff --git a/skyquake/plugins/launchpad/src/ssh_keys/sshKeys.jsx b/skyquake/plugins/launchpad/src/ssh_keys/sshKeys.jsx
new file mode 100644 (file)
index 0000000..1676cff
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React, {Component} from 'react';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx'
+import SshKeyCard from './sshKeyCard.jsx';
+import SshKeyStore from './sshKeyStore.js';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import '../../node_modules/open-iconic/font/css/open-iconic.css';
+import 'style/base.scss';
+
+
+class SshKeys extends Component {
+    constructor(props) {
+        super(props);
+        this.Store = this.props.flux.stores.hasOwnProperty('SshKeyStore') ? this.props.flux.stores.SshKeyStore : this.props.flux.createStore(SshKeyStore);
+        this.state = this.Store.getState();
+        this.Store.listen(this.handleUpdate);
+    }
+    componentWillMount() {
+        this.Store.getSshKey();
+    }
+    componentWillUnmount() {
+      this.Store.unlisten(this.handleUpdate);
+    }
+    handleUpdate = (state) => {
+        this.setState(state)
+    }
+    render() {
+        let self = this;
+        let Store = self.Store;
+        // return <div>test</div>
+        return (
+          <div>
+            {
+              self.state.data && self.state.data.keys.map(function(k, i) {
+                let sshKey = self.state.data.entities[k];
+                return (
+                  <SshKeyCard key={i}  name={sshKey.name} value={sshKey.key}
+                  editMode={sshKey.isEditable}
+                  editKey= {Store.editSshKeyPair(sshKey.name)}
+                  updateSshKeyPair={Store.updateSshKeyPair}
+                  cancelEditSshKeyPair={Store.cancelEditSshKeyPair}
+                  saveEditSshKeyPair={Store.saveEditSshKeyPair}
+                  updateEditSshKeyPair={Store.updateEditSshKeyPair}
+                  deleteKey={Store.deleteSshKeyPair(sshKey.name)}
+                  />
+                )
+              })
+            }
+            <SshKeyCard  name={this.state.newKey.name} value={ this.state.newKey.key}
+                  editMode={"create"}
+                  updateSshKeyPair={Store.updateNewKeyValue}
+                  saveEditSshKeyPair={Store.saveEditSshKeyPair}
+                  />
+          </div>
+        )
+  }
+}
+
+export default SkyquakeComponent(SshKeys);
diff --git a/skyquake/plugins/launchpad/src/topologyL2View/detailView.jsx b/skyquake/plugins/launchpad/src/topologyL2View/detailView.jsx
new file mode 100644 (file)
index 0000000..9436671
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import LoadingIndicator from 'widgets/loading-indicator/loadingIndicator.jsx';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import Listy from 'widgets/listy/listy.js';
+
+import _ from 'underscore';
+
+export default class TopologyDetail extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+
+    detailData(data) {
+        if (_.isEmpty(data)) {
+            return {};
+        } else {
+            return {
+                name: data['name'],
+                full_name: data['full_name'],
+                network: data['network'],
+                attr: data['attr']
+            }
+        }
+    }
+
+    rawDetails(data) {
+        let text = JSON.stringify(data, undefined, 2);
+        if (text == "{}") {
+            return false;
+        } else {
+            return (
+                <div className="topologyDebugRawJSON">
+                    <h2>Raw JSON</h2>
+                    <pre className="language.js">{text}</pre>
+                </div>
+            );
+        }
+    }
+
+    render() {
+        return (
+            <DashboardCard showHeader={true} title="Record Details" className={'recordDetails'}>
+              <div className="nodeAttr">
+                <Listy data={this.detailData(this.props.data)}
+                       noDataMessage={"Select a node"}
+                       debugMode={this.props.debugMode}
+                />
+              </div>
+              {
+                (this.props.debugMode)
+                    ? this.rawDetails(this.props.data)
+                    : false
+              }
+            </DashboardCard>
+        );
+    }
+}
+
+TopologyDetail.propTypes = {
+    debugMode: React.PropTypes.bool
+}
+
+TopologyDetail.defaultProps = {
+    data: {},
+    debugMode: false
+}
diff --git a/skyquake/plugins/launchpad/src/topologyL2View/topologyL2Actions.js b/skyquake/plugins/launchpad/src/topologyL2View/topologyL2Actions.js
new file mode 100644 (file)
index 0000000..1cb4a47
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import Alt  from '../alt';
+
+module.exports = Alt.generateActions(
+       'openTopologyApiSocketLoading',
+       'openTopologyApiSocketSuccess',
+       'openTopologyApiSocketError',
+       'getTopologyApiLoading',
+       'getTopologyApiSuccess',
+       'getTopologyApiError',
+       'nodeClicked'
+);
diff --git a/skyquake/plugins/launchpad/src/topologyL2View/topologyL2Source.js b/skyquake/plugins/launchpad/src/topologyL2View/topologyL2Source.js
new file mode 100644 (file)
index 0000000..e927984
--- /dev/null
@@ -0,0 +1,91 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+let getSearchParams = require('utils/rw.js').getSearchParams;
+
+var API_SERVER = getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = getSearchParams(window.location).dev_mode || false;
+var TopologyL2Actions = require('./topologyL2Actions.js');
+var Utils = require('utils/utils.js');
+import $ from 'jquery';
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+export default {
+  openTopologyApiSocket: function() {
+    return {
+      remote: function(state, id) {
+        // TODO: add topology type to the parameter
+        return new Promise(function(resolve, reject) {
+          //If socket connection already exists, eat the request.
+          if(state.socket) {
+            return resolve(false);
+          }
+           $.ajax({
+            url: '/socket-polling?api_server=' + API_SERVER ,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              url: '/launchpad/api/network-topology?api_server=' + API_SERVER
+            },
+            success: function(data, textStatus, jqXHR) {
+              Utils.checkAndResolveSocketRequest(data, resolve, reject);
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });;
+        });
+      },
+      loading: TopologyL2Actions.openTopologyApiSocketLoading,
+      success: TopologyL2Actions.openTopologyApiSocketSuccess,
+      error: TopologyL2Actions.openTopologyApiSocketError
+    };
+  },
+  fetchTopology() {
+    return {
+      remote() {
+        return new Promise(function (resolve, reject) {
+          $.ajax({
+            url: '/launchpad/api/network-topology?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            contentType: "application/json",
+            success: function(data) {
+              resolve(data);
+            },
+            error: function(error) {
+              console.log("There was an error getting the network topology data", error);
+              reject(error);
+            }
+          });
+        })
+      },
+      local() {
+        return null;
+      },
+      success: TopologyL2Actions.getTopologyApiSuccess,
+      error: TopologyL2Actions.getTopologyApiError,
+      loading: TopologyL2Actions.getTopologyApiLoading
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/topologyL2View/topologyL2Store.js b/skyquake/plugins/launchpad/src/topologyL2View/topologyL2Store.js
new file mode 100644 (file)
index 0000000..2d14952
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import TopologyL2Actions from './topologyL2Actions.js';
+import TopologyL2Source from './topologyL2Source.js';
+import Alt from '../alt';
+let rw = require('utils/rw.js');
+class TopologyL2Store {
+    constructor() {
+        var self = this;
+        // initial state
+        this.isLoading = true;
+        this.topologyData = {
+            nodes: [],
+            links: [],
+            network_ids: []
+        };
+        this.errorMessage = null;
+        this.socket = null;
+        this.detailView = null;
+
+        this.bindActions(TopologyL2Actions);
+        // bind source listeners
+        this.exportAsync(TopologyL2Source);
+        this.exportPublicMethods({
+            closeSocket: this.closeSocket,
+            getTopologyData: this.getTopologyData
+        });
+        this.ajax_mode = rw.getSearchParams(window.location).ajax_mode || false;
+    }
+
+    getTopologyData = (id) => {
+        if (this.ajax_mode) {
+            this.getInstance().fetchTopology();
+        } else {
+            this.getInstance().openTopologyApiSocket(id);
+        }
+    }
+    openTopologyApiSocketLoading() {}
+    openTopologyApiSocketSuccess = (connection) => {
+        let self = this;
+
+        let connectionManager = (type, connection) => {
+            let ws = window.multiplexer.channel(connection);
+            if (!connection) {
+                console.warn('There was an issue connecting to the ' + type + ' socket');
+                return;
+            }
+            if (self.socket) {
+                self.closeSocket();
+            }
+            self.setState({
+                socket: ws.ws,
+                channelId: connection
+            });
+            ws.onmessage = function(data) {
+                self.setState({
+                    topologyData: JSON.parse(data.data),
+                    isLoading: false,
+                });
+            };
+        }
+
+        connectionManager('foo-type', connection);
+
+    }
+    openTopologyApiSocketError() {}
+
+    handleLogout = () => {
+        this.closeSocket();
+    }
+
+    closeSocket = () => {
+        if (this.socket) {
+            window.multiplexer.channel(this.channelId).close();
+        }
+        this.setState({
+            socket: null
+        });
+
+        this.detailView = null;
+        this.hasSelected = false;
+
+        this.bindListeners({
+            getTopologyApiSuccess: TopologyL2Actions.GET_TOPOLOGY_API_SUCCESS,
+            getTopologyApiLoading: TopologyL2Actions.GET_TOPOLOGY_API_LOADING,
+            getTopologyApiError: TopologyL2Actions.GET_TOPOLOGY_API_ERROR
+        });
+        // bind source listeners
+        this.exportAsync(TopologyL2Source);
+    }
+
+    getTopologyApiSuccess = (data) => {
+        this.setState({
+            topologyData: data,
+            errorMessage: null
+        });
+    }
+
+    getTopologyApiLoading = () => {}
+
+    getTopologyApiError = (errorMessage) => {
+        this.errorMessage = errorMessage;
+    }
+
+    getNodeData = (node_id) => {
+        // find node in thisa.topologyData.nodes
+        var node_data = this.topologyData.nodes.find(
+            function(element, index, array) {
+                return (element.id == node_id);
+            });
+        return node_data;
+    }
+
+    nodeClicked = (node_id) => {
+        this.setState({
+            detailData: this.getNodeData(node_id)
+        });
+    }
+}
+    export default Alt.createStore(TopologyL2Store);
diff --git a/skyquake/plugins/launchpad/src/topologyL2View/topologyL2View.jsx b/skyquake/plugins/launchpad/src/topologyL2View/topologyL2View.jsx
new file mode 100644 (file)
index 0000000..25db983
--- /dev/null
@@ -0,0 +1,128 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import TopologyL2Store from './topologyL2Store.js';
+import TopologyL2Actions from './topologyL2Actions.js';
+import RecordDetail from '../recordViewer/recordDetails.jsx';
+import './topologyL2View.scss';
+import TopologyDetail from './detailView.jsx';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import AppHeader from 'widgets/header/header.jsx';
+import TopologyL2Graph from 'widgets/topology/topologyL2Graph.jsx';
+import Button from 'widgets/button/rw.button.js';
+
+export default class TopologyL2view extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = TopologyL2Store.getState();
+        TopologyL2Store.listen(this.storeListener);
+    }
+    openAbout = () => {
+        this.componentWillUnmount();
+        let loc = window.location.hash.split('/');
+        loc.pop();
+        loc.pop();
+        loc.push('lp-about');
+        window.location.hash = loc.join('/');
+    }
+    openDebug = () => {
+        this.compoentWillUnmount();
+        let loc = window.location.hash.split('/');
+        loc.pop();
+        loc.pop();
+        loc.push('lp-debug');
+        window.location.hash = loc.join('/');
+    }
+    storeListener = (state) => {
+        this.setState(state);
+    }
+
+    componentWillUnmount() {
+        TopologyL2Store.closeSocket();
+        TopologyL2Store.unlisten(this.storeListener);
+    }
+    componentDidMount() {
+        TopologyL2Store.getTopologyData('dummy-id');
+    }
+
+    onNodeEvent = (node_id) => {
+        TopologyL2Actions.nodeClicked(node_id);
+    }
+
+    handleReloadData = () => {
+        console.log("TopologyView.handleReloadData");
+        this.componentDidMount();
+    }
+
+    render() {
+        let html;
+         let location = this.props.location;
+              let navItems = [{
+          name: 'Viewport',
+          onClick: this.context.router.push.bind(this, {pathname:'/viewport', query: {id: location.query.id, sdnpresent: location.query.sdnpresent}})
+        },{
+          name: 'COMPUTE TOPOLOGY',
+          onClick: this.context.router.push.bind(this, {pathname:'/compute-topology', query: {id: location.query.id, sdnpresent: location.query.sdnpresent}})
+        },{
+             name: 'NETWORK TOPOLOGY'
+        }
+        ];
+
+        let nav = <AppHeader title="Launchpad: Viewport: Network Topology" nav={navItems} />
+        let reloadButton = null;
+        if (this.state.ajax_mode) {
+            reloadButton = <Button label="Reload data" className="reloadButton"
+                onClick={this.handleReloadData} />
+        }
+
+        html = (
+            <div className="app-body topologyL2ViewAppBody">
+                {nav}
+                {reloadButton}
+                <div className="topologyL2View">
+                    <i className="corner-accent top left"></i>
+                    <i className="corner-accent top right"></i>
+                    <TopologyL2Graph data={this.state.topologyData}
+                                     nodeEvent={this.onNodeEvent}
+                                     debugMode={this.props.debugMode}
+                                     headerExtras={reloadButton}
+                    />
+                    <TopologyDetail data={this.state.detailData || {}}
+                                    isLoading={this.state.isLoading}
+                                    debugMode={this.props.debugMode}
+                    />
+                    <i className="corner-accent bottom left"></i>
+                    <i className="corner-accent bottom right"></i>
+                </div>
+            </div>
+        );
+
+        return html;
+    }
+}
+
+TopologyL2view.contextTypes = {
+    router: React.PropTypes.object
+};
+TopologyL2view.propTypes = {
+    debugMode: React.PropTypes.bool
+}
+TopologyL2view.defaultProps = {
+    debugMode: false
+}
diff --git a/skyquake/plugins/launchpad/src/topologyL2View/topologyL2View.scss b/skyquake/plugins/launchpad/src/topologyL2View/topologyL2View.scss
new file mode 100644 (file)
index 0000000..026cd1d
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+
+.app-body.topologyL2ViewAppBody {
+       flex:1;
+}
+.topologyL2View {
+       display: flex;
+       flex-direction: row;
+       justify-content: flex-start;
+       align-items: stretch;
+       align-content: stretch;
+       flex: 1;
+       position: relative;
+       margin: 0.5rem;
+       min-width: 1340px;
+
+       .dashboardCard {
+               flex: 0 1 auto;
+               width: auto;
+               height: auto;
+               margin: 0px;
+
+               .corner-accent {
+                       display: none;
+               }
+               header {
+                       background-color: white;
+               }
+               &.recordDetails {
+                       flex: 1 1 auto;
+                       width: 400px;
+
+                       pre {
+                               margin: 0;
+                               white-space: pre-wrap;
+                       }
+               }
+               .nodeAttr {
+                       overflow: auto;
+                       margin-top: 10px;
+                       margin-left: 5px;
+
+                       .listy {
+                               //border: 1px solid red;
+                               flex: 1 1 auto;
+                               //max-height: 400px;
+
+                               //.listyGroup {
+                               }
+                               .listyGroup .listyGroup {
+                                       margin-left: 15px;
+                               }
+                               .listyItem {
+                                       padding-top: 5px;
+                                       list-style-type: none;
+                               }
+                               .listyGroupHeader {
+                                       font-size: 1em;
+                               }
+                               .listyNoDataMessage {
+                                       text-align: center;
+                                       margin-top: 40px;
+                                       color: gray;
+                                       font-size: 2em;
+                                       font-style: italic;
+                               }
+                       }
+                       .debugDetailBox {
+                               margin-top: 20px;
+                       }
+               }
+       }
+       .topologyGraphDebugPanel {
+               margin: 5px;
+               background-color: #ECF1EF;
+       }
+       .topologyDebugRawJSON {
+               margin: 5px;
+               padding: 5px;
+               border: 1px dashed gray;
+       }
+       svg {
+               .gnode {
+                       cursor: pointer;
+
+                       circle {
+                               stroke: steelblue;
+                               stroke-width: 1.5px;
+                       }
+               }
+               .link {
+                       fill: none;
+                       stroke: gray;
+                       stroke-width: 1.5px;
+
+               }
+       }
+       svg.topology {
+               .gnode {
+                       cursor: pointer;
+
+                       circle {
+                               fill: white;
+                               stroke: steelblue;
+                               stroke-width: 1.5px;
+                       }
+               }
+               .node-group-1 {
+                       circle {
+                               fill: green;
+                       }
+               }
+               .node-group-2 {
+                       circle {
+                               fill: yellow;
+                       }
+               }
+               .node-group-3 {
+                       circle {
+                               fill: red;
+                       }
+               }
+               .node-group-4 {
+                       circle {
+                               fill: blue;
+                       }
+               }
+               .node-group-5 {
+                       circle {
+                               fill: orange;
+                       }
+               }
+               .link {
+                       fill: none;
+                       stroke: gray;
+                       stroke-width: 1.5px;
+               }
+               .legend {
+
+               }
+       }
+       .reloadButton {
+               //TODO: Style this button
+       }
diff --git a/skyquake/plugins/launchpad/src/topologyView/topologyActions.js b/skyquake/plugins/launchpad/src/topologyView/topologyActions.js
new file mode 100644 (file)
index 0000000..887b6d0
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import Alt from '../alt';
+
+module.exports = Alt.generateActions(
+   'openNSRTopologySocketSuccess',
+   'openNSRTopologySocketError',
+   'openNSRTopologySocketLoading',
+   'getNSRTopologySuccess',
+   'getNSRTopologyError',
+   'getNSRTopologyLoading',
+   'getRawLoading',
+   'getRawSuccess',
+   'getRawError'
+);
diff --git a/skyquake/plugins/launchpad/src/topologyView/topologySource.js b/skyquake/plugins/launchpad/src/topologyView/topologySource.js
new file mode 100644 (file)
index 0000000..23db982
--- /dev/null
@@ -0,0 +1,150 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+let getSearchParams = require('utils/rw.js').getSearchParams;
+
+var API_SERVER = getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = getSearchParams(window.location).dev_mode || false;
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+
+var TopologyActions = require('./topologyActions.js');
+var Utils = require('utils/utils.js');
+import $ from 'jquery';
+
+export default {
+  openNSRTopologySocket: function() {
+    return {
+      remote: function(state, id) {
+        return new Promise(function(resolve, reject) {
+          //If socket connection already exists, eat the request.
+          if(state.socket) {
+            return resolve(false);
+          }
+           $.ajax({
+            url: '/socket-polling?api_server=' + API_SERVER ,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              url: '/launchpad/api/nsr/' + id + '/compute-topology?api_server=' + API_SERVER
+            },
+            success: function(data, textStatus, jqXHR) {
+              Utils.checkAndResolveSocketRequest(data, resolve, reject);
+            }
+          }).fail(function(xhr){
+            //Authentication and the handling of fail states should be wrapped up into a connection class.
+            Utils.checkAuthentication(xhr.status);
+          });;
+        });
+      },
+      loading: TopologyActions.openNSRTopologySocketLoading,
+      success: TopologyActions.openNSRTopologySocketSuccess,
+      error: TopologyActions.openNSRTopologySocketError
+    };
+  },
+  getNSRTopology() {
+    return {
+        remote: function(state, id) {
+        id = 0;
+        return new Promise(function (resolve, reject) {
+          $.ajax({
+            url: '/launchpad/api/nsr/' + id + '/compute-topology?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            contentType: "application/json",
+            success: function(data) {
+              resolve(data);
+            },
+            error: function(error) {
+              console.log("There was an error getting the compute topology data", error);
+              reject(error);
+            }
+          });
+        });
+      },
+      local() {
+        return null;
+      },
+      success: TopologyActions.getNSRTopologySuccess,
+      error: TopologyActions.getNSRTopologyError,
+      loading: TopologyActions.getNSRTopologyLoading
+    }
+  },
+  getRawVNFR() {
+    return {
+      remote: function(state, vnfrID) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'passthrough/data/api/operational/vnfr-catalog/vnfr/' + vnfrID + '?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          });
+        })
+      },
+      loading: TopologyActions.getRawLoading,
+      success: TopologyActions.getRawSuccess,
+      error: TopologyActions.getRawError
+    }
+  },
+  getRawNSR() {
+    return {
+      remote: function(state, nsrID) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'passthrough/data/api/operational/ns-instance-opdata/nsr/' + nsrID + '?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          });
+        })
+      },
+      loading: TopologyActions.getRawLoading,
+      success: TopologyActions.getRawSuccess,
+      error: TopologyActions.getRawError
+    }
+  },
+  getRawVDUR() {
+    return {
+      remote: function(state, vdurID, vnfrID) {
+        return new Promise(function(resolve, reject) {
+          $.ajax({
+            url: 'passthrough/data/api/operational/vnfr-catalog/vnfr/' + vnfrID + '/vdur/' + vdurID + '?api_server=' + API_SERVER,
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              resolve(data);
+            }
+          });
+        })
+      },
+      loading: TopologyActions.getRawLoading,
+      success: TopologyActions.getRawSuccess,
+      error: TopologyActions.getRawError
+    }
+  },
+}
diff --git a/skyquake/plugins/launchpad/src/topologyView/topologyStore.js b/skyquake/plugins/launchpad/src/topologyView/topologyStore.js
new file mode 100644 (file)
index 0000000..10c5005
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import TopologyActions from './topologyActions.js';
+import TopologySource from './topologySource.js';
+// import source
+import Alt from '../alt';
+let rw = require('utils/rw.js');
+class TopologyStore {
+    constructor() {
+        var self = this;
+        // initial state
+        this.isLoading = true;
+        this.topologyData = {};
+        this.socket = null;
+        this.detailView = null;
+        this.hasSelected = false;
+        // bind action listeners
+        this.bindActions(TopologyActions);
+
+        // bind source listeners
+        this.exportAsync(TopologySource);
+        this.exportPublicMethods({
+            selectNode: this.selectNode,
+            closeSocket: this.closeSocket,
+            getTopologyData: this.getTopologyData
+        })
+        this.ajax_mode = rw.getSearchParams(window.location).ajax_mode || false;
+    }
+    selectNode = (node) => {
+        var apiType = {
+            'nsr' : 'getRawNSR',
+            'vdur' : 'getRawVDUR',
+            'vnfr': 'getRawVNFR'
+        }
+        // TODO: VISIT
+       apiType[node.type] && this.getInstance()[apiType[node.type]](node.id, node.parent ? node.parent.id : undefined);
+    }
+    getRawSuccess = (data) => {
+        this.setState({
+            detailView: data
+        });
+    }
+    getRawLoading = () => {
+
+    }
+    getRawError = () => {
+
+    }
+
+    getTopologyData = (nsr_id) => {
+        if (this.ajax_mode) {
+            this.getInstance().getNSRTopology(nsr_id);
+        } else {
+            this.getInstance().openNSRTopologySocket(nsr_id);
+        }
+    }
+
+    openNSRTopologySocketLoading = () => {
+         console.log('loading')
+    }
+    openNSRTopologySocketSuccess = (connection) => {
+        let self = this;
+
+        let connectionManager = (type, connection) => {
+            let ws = window.multiplexer.channel(connection);
+            if (!connection) {
+                console.warn('There was an issue connecting to the ' + type + ' socket');
+                return;
+            }
+            if (self.socket) {
+                self.closeSocket();
+            }
+
+            self.setState({
+                socket: ws.ws,
+                channelId: connection
+            });
+            ws.onmessage = function(data) {
+                var tData = JSON.parse(data.data);
+                var newState = {
+                    topologyData: tData,
+                    isLoading: false
+                };
+                if(!self.hasSelected) {
+                    newState.hasSelected = true;
+                    self.selectNode(tData);
+                }
+                self.setState(newState);
+
+            };
+        }
+
+        connectionManager('nsr', connection);
+    }
+    openNSRTopologySocketError = () => {
+        console.log('error')
+    }
+    handleLogout = () => {
+        this.closeSocket();
+    }
+    closeSocket = () => {
+        if (this.socket) {
+            window.multiplexer.channel(this.channelId).close();
+        }
+        this.setState({
+            socket: null
+        })
+    }
+    getNSRTopologySuccess = (data) => {
+        this.setState({
+            topologyData: data,
+            errorMessage: null,
+            isLoading: false
+        });
+    }
+    getNSRTopologyLoading = () => {}
+    getNSRTopologyError = (errorMessage) => {
+        console.log('error', errorMessage)
+        //this.errorMessage = errorMessage;
+    }
+
+}
+export default Alt.createStore(TopologyStore);
diff --git a/skyquake/plugins/launchpad/src/topologyView/topologyView.jsx b/skyquake/plugins/launchpad/src/topologyView/topologyView.jsx
new file mode 100644 (file)
index 0000000..6db1938
--- /dev/null
@@ -0,0 +1,118 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import TopologyStore from './topologyStore.js';
+import RecordDetail from '../recordViewer/recordDetails.jsx';
+import './topologyView.scss';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import AppHeader from 'widgets/header/header.jsx';
+import TopologyTree from 'widgets/topology/topologyTree.jsx';
+import LaunchpadBreadcrumbs from '../launchpadBreadcrumbs.jsx';
+import Button from 'widgets/button/rw.button.js';
+
+export default class Topologyview extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = TopologyStore.getState();
+        TopologyStore.listen(this.storeListener);
+    }
+    openAbout = () => {
+        this.componentWillUnmount();
+        let loc = window.location.hash.split('/');
+        loc.pop();
+        loc.pop();
+        loc.push('lp-about');
+        window.location.hash = loc.join('/');
+    }
+    openDebug = () =>  {
+        this.componentWillUnmount();
+        let loc = window.location.hash.split('/');
+        loc.pop();
+        loc.pop();
+        loc.push('lp-debug');
+        window.location.hash = loc.join('/');
+    }
+    storeListener = (state) => {
+        this.setState(state);
+    }
+
+    componentWillUnmount = () => {
+        TopologyStore.closeSocket();
+        TopologyStore.unlisten(this.storeListener);
+    }
+    componentDidMount() {
+        let nsrRegEx = new RegExp("([0-9a-zA-Z-]+)\/compute-topology");
+        let nsr_id;
+
+        try {
+            nsr_id =  this.props.location.query.id;
+        } catch (e) {
+            console.log("TopologyView.componentDidMount exception: ", e);
+        }
+        TopologyStore.getTopologyData(nsr_id);
+    }
+    selectNode = (node) => {
+        TopologyStore.selectNode(node);
+    }
+
+    handleReloadData = () => {
+        this.componentDidMount();
+    }
+
+    render() {
+        let location = this.props.location;
+        let html;
+        let navItems = [{
+          name: 'Viewport',
+          onClick: this.context.router.push.bind(this, {pathname:'/viewport', query: {id: location.query.id, sdnpresent: location.query.sdnpresent}})
+        },{
+          name: 'COMPUTE TOPOLOGY'
+        }];
+
+
+        if (location.query.sdnpresent == 'true') {
+            navItems.push({
+             name: 'NETWORK TOPOLOGY',
+              onClick: this.context.router.push.bind(this, {pathname:'/network-topology', query: {id: location.query.id, sdnpresent: location.query.sdnpresent}})
+            });
+        }
+        let nav = <AppHeader nav={navItems} />
+        html = (
+            <div className="app-body topologyAppBody">
+            {nav}
+                <div className="topologyView">
+                    <i className="corner-accent top left"></i>
+                    <i className="corner-accent top right"></i>
+                    <TopologyTree
+                        data={this.state.topologyData}
+                        selectNode={this.selectNode}
+                        hasSelected={this.state.hasSelected}
+                    />
+                    <RecordDetail data={this.state.detailView || {}} isLoading={this.state.detailsLoading} />
+                    <i className="corner-accent bottom left"></i>
+                    <i className="corner-accent bottom right"></i>
+                </div>
+            </div>
+        );
+        return html;
+    }
+}
+Topologyview.contextTypes = {
+    router: React.PropTypes.object
+};
diff --git a/skyquake/plugins/launchpad/src/topologyView/topologyView.scss b/skyquake/plugins/launchpad/src/topologyView/topologyView.scss
new file mode 100644 (file)
index 0000000..02b6c43
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import 'style/_colors.scss';
+@import 'style/layout.scss';
+.app-body {
+       display: flex;
+       height: 100%;
+       &.topologyAppBody {
+               flex: 1;
+       }
+}
+.topologyView {
+
+       display: flex;
+       flex-direction: row;
+       justify-content: flex-start;
+       align-items: stretch;
+       align-content: stretch;
+       flex: 1;
+       position: relative;
+       margin: 0.5rem;
+       min-width: 1340px;
+  height: auto;
+       .dashboardCard {
+               display: flex;
+               //flex: 0 1 auto;
+               flex: 1;
+               width: auto;
+               height: auto;
+               margin: 0;
+               max-height: none;
+               .corner-accent {
+                       display: none;
+               }
+               header {
+                       background-color: white;
+                       display: block;
+               }
+       }
+       .topologyTreeGraph {
+               flex-grow: 2;
+       }
+  .recordDetails {
+         flex: 1 1 auto;
+
+               pre {
+                       flex: 1;
+                       margin: 0;
+                       white-space: pre-wrap;
+               }
+               &-body {
+                       display: flex;
+                       flex: 1;
+                       min-width: 0;
+                       min-height: 0;
+                       overflow: auto;
+               }
+       }
+
+
+       svg {
+               .node {
+                       cursor: pointer;
+
+                       circle {
+                               stroke: steelblue;
+                               stroke-width: 1.5px;
+                       }
+               }
+               .link {
+                       fill: none;
+                       stroke: gray;
+                       stroke-width: 1.5px;
+               }
+       }
+}
+.reloadButton {
+    // TODO: Style this button
+}
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreate.jsx b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreate.jsx
new file mode 100644 (file)
index 0000000..30f7694
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import Utils from 'utils/utils.js';
+import _ from 'lodash';
+import './nsVirtualLinks.scss';
+import NSVirtualLinkCreateStore from './nsVirtualLinkCreateStore.js';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
+import Button from 'widgets/button/rw.button.js';
+import SelectOption from 'widgets/form_controls/selectOption.jsx';
+
+
+
+class NsVirtualLinkCreate extends React.Component {
+       constructor(props) {
+               super(props);
+           this.Store = this.props.flux.stores.hasOwnProperty('NSVirtualLinkCreateStore') ? this.props.flux.stores.NSVirtualLinkCreateStore : this.props.flux.createStore(NSVirtualLinkCreateStore);
+               this.state = this.Store.getState();
+               this.Store.listen(this.handleUpdate);
+       }
+
+       componentWillMount() {
+               (!this.state.nsrId && this.props.nsrId) && this.Store.saveNSRId(this.props.nsrId);
+               this.Store.saveMode(this.props.mode);
+               switch (this.props.mode) {
+                       case 'creating':
+                               if (!this.state.vld) {
+                                       this.Store.saveVld({});
+                               }
+                               break;
+                       case 'editing':
+                               this.Store.saveVld(this.props.vld);
+                               break;
+               }
+               if (this.props.nsd && this.props.nsd['constituent-vnfd']) {
+                       let memberVnfIndexRefs = [];
+                       let vnfdIdRefs = [];
+                       this.props.nsd['constituent-vnfd'].map((cVNFD, cVNFDI) => {
+                               memberVnfIndexRefs.push({
+                                       label: cVNFD['member-vnf-index'],
+                                       value: cVNFD['member-vnf-index']
+                               });
+                               vnfdIdRefs.push({
+                                       label: cVNFD['vnfd-id-ref'],
+                                       value: cVNFD['vnfd-id-ref']
+                               });
+                       });
+
+                       let ipProfileNames = [];
+                       this.props.nsd['ip-profiles'] && this.props.nsd['ip-profiles'].map((ipProfile, ipProfileIndex) => {
+                               ipProfileNames.push({
+                                       label: ipProfile['name'],
+                                       value: ipProfile['name']
+                               });
+                       })
+
+                       this.Store.saveMemberVnfIndexRefs(memberVnfIndexRefs);
+                       this.Store.saveVnfdIdRefs(vnfdIdRefs);
+                       this.Store.saveIpProfileNames(ipProfileNames);
+               }
+       }
+
+       componentWillReceiveProps(nextProps) {
+               if (nextProps != this.props) {
+                       if (nextProps.mode != this.props.mode) {
+                               // mode change
+                               this.Store.saveMode(nextProps.mode);
+                               switch (nextProps.mode) {
+                                       case 'creating':
+                                               // switching from editing to creating
+                                               this.Store.saveVld({});
+                                               break;
+                                       case 'editing':
+                                               // switching from creating to editing
+                                               this.Store.saveVld(nextProps.vld);
+                                               break;
+                               }
+                       } else {
+                               // no mode change, but props changed
+                               switch (nextProps.mode) {
+                                       case 'creating':
+                                               // switching from creating to creating
+                                               // TODO: can't figure out how to empty out without affecting create being erased
+                                               break;
+                                       case 'editing':
+                                               // switching from editing to editing
+                                               if ((nextProps.vld && nextProps.vld.id) != (this.props.vld && this.props.vld.id)) {
+                                                       this.Store.saveVld(nextProps.vld);
+                                               }
+                                               break;
+                               }
+                       }
+               }
+       }
+
+       componentWillUnmount() {
+               this.Store.saveVld({});
+               this.Store.unlisten(this.handleUpdate);
+       }
+
+       handleUpdate = (storeState) => {
+               this.setState(storeState);
+       }
+
+       handleSubmit = (mode, e) => {
+               e.preventDefault();
+               this.Store.persistVirtualLink(mode);
+       }
+
+       handleCancel = (e) => {
+               e.preventDefault();
+               this.props.onCancel && this.props.onCancel();
+       }
+
+       transformValue(field, value) {
+               let transformedValue = (field.transform && field.transform(value)) || value;
+               if (typeof transformedValue == 'object') {
+                       transformedValue = JSON.stringify(transformedValue);
+               }
+               return transformedValue;
+       }
+
+       handleFirstLevelKeyChange = (key, e) => {
+               this.Store.updateFirstLevelKey(key, e);
+       }
+
+       handleSecondLevelKeyChange = (firstLevelKey, secondLevelKey, e) => {
+               this.Store.updateSecondLevelKey(firstLevelKey, secondLevelKey, e);
+       }
+
+       handleFirstLevelListKeyChange = (listName, index, keyName, e) => {
+               this.Store.updateFirstLevelListKeyChange(listName, index, keyName, e);
+       }
+
+       handleAddConnectionPointRef = () => {
+               this.Store.addConnectionPointRef();
+       }
+
+       handleRemoveConnectionPoint = (vCPRI, e) => {
+               this.Store.removeConnectionPointRef(vCPRI);
+       }
+
+
+       updateVLDInitParamsType = (type) => {
+               this.Store.updateVLDInitParamsType(type);
+       }
+
+       updateVLDInitParamsValue = (currentVLDInitParamsType, e) => {
+               this.Store.updateVLDInitParamsValue(currentVLDInitParamsType, e);
+       }
+
+       render() {
+               let self = this;
+
+               let typeOptions = this.state.typeOptions;
+               let overlayTypeOptions = this.state.overlayTypeOptions;
+               let currentVLDInitParamsType = this.state.currentVLDInitParamsType;
+               let memberVnfIndexRefs = this.state.memberVnfIndexRefs;
+               let vnfdIdRefs = this.state.vnfdIdRefs;
+               let vnfdConnectionPointRefs = this.state.vnfdConnectionPointRefs;
+               let ipProfileNames = this.state.ipProfileNames;
+
+               let connectionPointsHtml = [];
+
+               this.state.vld && this.state.vld['vnfd-connection-point-ref'] && this.state.vld['vnfd-connection-point-ref'].map((vCPR, vCPRI) => {
+                       connectionPointsHtml.push(
+                               <li className='vnfd-connection-points-list-item'>
+                                       <div>
+                                               <span>
+                                                       VNFD CONNECTION POINT REF - {vCPRI}
+                                               </span>
+                                               <a key={'vnfd-connection-point-delete-' + vCPRI} onClick={this.handleRemoveConnectionPoint.bind(self, vCPRI)} title="Delete">
+                                       <span key={'trash-' + vCPRI} className="oi" data-glyph="trash" aria-hidden="true"></span>
+                               </a>
+                       </div>
+                       <SelectOption key={'vnfd-connection-point-ref-member-vnfd-index-ref-' + vCPRI} label={'MEMBER VNF INDEX REF'} initial={memberVnfIndexRefs[0].value} options={memberVnfIndexRefs} onChange={this.handleFirstLevelListKeyChange.bind(self, 'vnfd-connection-point-ref', vCPRI, 'member-vnf-index-ref')} defaultValue={this.state.vld['vnfd-connection-point-ref'] && this.state.vld['vnfd-connection-point-ref'][vCPRI] && this.state.vld['vnfd-connection-point-ref'][vCPRI]['member-vnf-index-ref']}/>
+                       <SelectOption key={'vnfd-connection-point-ref-vnfd-id-ref-' + vCPRI} label={'VNFD ID REF'} initial={vnfdIdRefs[0].value} options={vnfdIdRefs} onChange={this.handleFirstLevelListKeyChange.bind(self, 'vnfd-connection-point-ref', vCPRI, 'vnfd-id-ref')} defaultValue={this.state.vld['vnfd-connection-point-ref'] && this.state.vld['vnfd-connection-point-ref'][vCPRI] && this.state.vld['vnfd-connection-point-ref'][vCPRI]['vnfd-id-ref']}/>
+                       <TextInput key={'vnfd-connection-point-ref-vnfd-connection-point-ref-' + vCPRI} label='VNFD CONNECTION POINT REF' className='value' type='text' value={this.state.vld['vnfd-connection-point-ref'] && this.state.vld['vnfd-connection-point-ref'][vCPRI] && this.state.vld['vnfd-connection-point-ref'][vCPRI]['vnfd-connection-point-ref']} onChange={this.handleFirstLevelListKeyChange.bind(self, 'vnfd-connection-point-ref', vCPRI, 'vnfd-connection-point-ref')} />
+                               </li>
+                       );
+               });
+
+               
+               let vldHTML = this.state.vld && (
+                       <div>
+                               <h3>DETAILS</h3>
+                               <TextInput key={'id'} className='value' label={'ID'} type='text' value={this.state.vld.id} onChange={this.handleFirstLevelKeyChange.bind(self, 'id')} readonly={this.state.mode == 'editing' ? true:false} />
+                               <TextInput key={'name'} className='value' label={'NAME'} type='text' value={this.state.vld.name} onChange={this.handleFirstLevelKeyChange.bind(self, 'name')} />
+                               <TextInput key={'short-name'} className='value' label={'SHORT NAME'} type='text' value={this.state.vld['short-name']} onChange={this.handleFirstLevelKeyChange.bind(self, 'short-name')} />
+                               <TextInput key={'vendor'} className='value' label={'VENDOR'} type='text' value={this.state.vld.vendor} onChange={this.handleFirstLevelKeyChange.bind(self, 'vendor')} />
+                               <TextInput key={'description'} className='value' label={'DESCRIPTION'} type='text' value={this.state.vld.description} onChange={this.handleFirstLevelKeyChange.bind(self, 'description')} />
+                               <TextInput key={'version'} className='value' label={'VERSION'} type='text' value={this.state.vld.version} onChange={this.handleFirstLevelKeyChange.bind(self, 'version')} />
+                               <SelectOption label={'TYPE'} initial={typeOptions[0].value} options={typeOptions} onChange={this.handleFirstLevelKeyChange.bind(self, 'type')} defaultValue={this.state.vld['type']} />
+                               <TextInput key={'root-bandwidth'} className='value' label={'ROOT BANDWIDTH'} type='text' value={this.state.vld['root-bandwidth']} onChange={this.handleFirstLevelKeyChange.bind(self, 'root-bandwidth')} />
+                               <TextInput key={'leaf-bandwidth'} className='value' label={'LEAF BANDWIDTH'} type='text' value={this.state.vld['leaf-bandwidth']} onChange={this.handleFirstLevelKeyChange.bind(self, 'leaf-bandwidth')} />
+                               <h3>PROVIDER NETWORK</h3>
+                               <TextInput key={'physical-network'} className='value' label={'PHYSICAL NETWORK'} type='text' value={this.state.vld['provider-network'] && this.state.vld['provider-network']['physical-network']} onChange={this.handleSecondLevelKeyChange.bind(self, 'provider-network', 'physical-network')} />
+                               <SelectOption label={'OVERLAY TYPE'} initial={overlayTypeOptions[0].value} options={overlayTypeOptions} onChange={this.handleSecondLevelKeyChange.bind(self, 'provider-network', 'overlay-type')} defaultValue={this.state.vld['provider-network'] && this.state.vld['provider-network']['overlay-type']}/>
+                               <TextInput key={'segmentation_id'} className='value' label={'SEGMENTATION ID'} type='text' value={this.state.vld['provider-network'] && this.state.vld['provider-network']['segmentation_id']} onChange={this.handleSecondLevelKeyChange.bind(self, 'provider-network', 'segmentation_id')} />
+                               <h3>VNF CONNECTION POINTS
+                                       <a className="plusButton" onClick={this.handleAddConnectionPointRef}>
+                               <span className="oi" data-glyph="plus"
+                                     title="Add connection point ref" aria-hidden="true"></span>
+                               </a>
+                               </h3>
+                       <ul className='vnfd-connection-points-list'>
+                                       {connectionPointsHtml}
+                               </ul>
+                               <h3>INIT PARAMS</h3>
+                               <div className="inputControls-radioGroup">
+                                       <label className="inputControls-radio">
+                                               <input type="radio" name={'ip-profile-ref'} onChange={this.updateVLDInitParamsType.bind(self, 'ip-profile-ref')} checked={currentVLDInitParamsType == 'ip-profile-ref'} value='ip-profile-ref' />
+                                               IP Profile
+                                       </label>
+                                       <label className="inputControls-radio">
+                                               <input type="radio" name={'vim-network-name'} onChange={this.updateVLDInitParamsType.bind(self, 'vim-network-name')} checked={currentVLDInitParamsType == 'vim-network-name'} value='vim-network-name' />
+                                               VIM Network Name
+                                       </label>
+                                       <label className="inputControls-radio">
+                                               <input type="radio" name={'unknown'} onChange={this.updateVLDInitParamsType.bind(self, 'unknown')} checked={currentVLDInitParamsType == 'unknown'} value='unknown' />
+                                               Unknown
+                                       </label>
+                               </div>
+                               {
+                                       (currentVLDInitParamsType == 'unknown') ? 
+                                               null
+                                       :
+                                               (currentVLDInitParamsType == 'vim-network-name') ?
+                                                       <TextInput label='NETWORK NAME' onChange={this.updateVLDInitParamsValue.bind(self, currentVLDInitParamsType)} value={this.state.vld[currentVLDInitParamsType]} />
+                                               :
+                                                       <SelectOption label={'IP PROFILE NAME'} initial={ipProfileNames[0].value} options={ipProfileNames} onChange={this.updateVLDInitParamsValue.bind(self, currentVLDInitParamsType)} />
+                               }
+                       </div>
+               );
+
+               return (
+                       <form className={'createVirtualLink'} onKeyDown={this.evaluateCreateVirtualLink}>
+                               {vldHTML}
+                               <div className='buttonGroup'>
+                                       <Button label='Submit' onClick={this.handleSubmit.bind(self, this.state.mode)} className='dark' type='submit' />
+                                       <Button label='Cancel' onClick={this.handleCancel.bind(self)} className='dark' type='reset' />
+                               </div>
+                       </form>
+               );
+       }
+}
+
+export default SkyquakeComponent(NsVirtualLinkCreate);
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateActions.js b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateActions.js
new file mode 100644 (file)
index 0000000..e737f01
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import Alt from '../alt.js';
+
+class NSVirtualLinkCreateActions {
+       constructor() {
+               this.generateActions(
+               'createVirtualLinkLoading', 'createVirtualLinkSuccess', 'createVirtualLinkError',
+                       'editVirtualLinkLoading', 'editVirtualLinkSuccess', 'editVirtualLinkError',
+                       'deleteVirtualLinkLoading', 'deleteVirtualLinkSuccess', 'deleteVirtualLinkError'
+               );
+       }
+}
+
+export default Alt.createActions(NSVirtualLinkCreateActions);
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateSource.js b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateSource.js
new file mode 100644 (file)
index 0000000..f4f8eab
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import NSVirtualLinkCreateActions from './nsVirtualLinkCreateActions.js';
+import $ from 'jquery';
+var Utils = require('utils/utils.js');
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = require('utils/rw.js').getSearchParams(window.location).dev_mode || false;
+
+if (DEV_MODE) {
+    HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+
+export default {
+    createVirtualLink() {
+        return {
+            remote(state, nsrId, payload) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + nsrId + '/vld' + '?api_server=' + API_SERVER,
+                        type: 'POST',
+                        beforeSend: Utils.addAuthorizationStub,
+                        dataType:'json',
+                        data: payload,
+                        success: function(data) {
+                            resolve(data);
+                        },
+                        error: function(error) {
+                            console.log("There was an error creating the virtual link: ", error);
+                            return reject();
+                        }
+                    });
+                })
+            },
+            loading: NSVirtualLinkCreateActions.createVirtualLinkLoading,
+            success: NSVirtualLinkCreateActions.createVirtualLinkSuccess,
+            error: NSVirtualLinkCreateActions.createVirtualLinkError
+        }
+    },
+    deleteVirtualLink() {
+        return {
+            remote(state, nsrId, vldId) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + nsrId + '/vld/' + vldId + '?api_server=' + API_SERVER,
+                        type: 'DELETE',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        },
+                        error: function(error) {
+                            console.log("There was an error deleting the virtual link: ", error);
+                            return reject();
+                        }
+                    });
+                })
+            },
+            loading: NSVirtualLinkCreateActions.deleteVirtualLinkLoading,
+            success: NSVirtualLinkCreateActions.deleteVirtualLinkSuccess,
+            error: NSVirtualLinkCreateActions.deleteVirtualLinkError
+        }
+    },
+    editVirtualLink() {
+        return {
+            remote(state, nsrId, vldId, vld) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: 'api/nsr/' + nsrId + '/vld/' + vldId + '?api_server=' + API_SERVER,
+                        type: 'PUT',
+                        beforeSend: Utils.addAuthorizationStub,
+                        dataType:'json',
+                        data: vld,
+                        success: function(data) {
+                            resolve(data);
+                        },
+                        error: function(error) {
+                            console.log("There was an error editing the virtual link: ", error);
+                            return reject();
+                        }
+                    });
+                })
+            },
+            loading: NSVirtualLinkCreateActions.editVirtualLinkLoading,
+            success: NSVirtualLinkCreateActions.editVirtualLinkSuccess,
+            error: NSVirtualLinkCreateActions.editVirtualLinkError
+        }
+    }
+
+}
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateStore.js b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkCreateStore.js
new file mode 100644 (file)
index 0000000..a3708fe
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import NSVirtualLinkCreateActions from './nsVirtualLinkCreateActions.js';
+import NSVirtualLinkCreateSource from './nsVirtualLinkCreateSource.js';
+import Alt from '../alt';
+import _ from 'lodash';
+
+class NSVirtualLinkCreateStore {
+       constructor() {
+
+               this.vld = null;
+               this.typeOptions = [{
+                       label: 'ELAN',
+                       value: 'ELAN'
+               }];
+               this.overlayTypeOptions = [{
+                       label: 'LOCAL',
+                       value: 'LOCAL'
+               }, {
+                       label: 'FLAT',
+                       value: 'FLAT'
+               }, {
+                       label: 'VLAN',
+                       value: 'VLAN'
+               }, {
+                       label: 'VXLAN',
+                       value: 'VXLAN'
+               }, {
+                       label: 'GRE',
+                       value: 'GRE'
+               }];
+
+               /* TODO: Move this to be populated from props */
+               this.vnfdConnectionPointRefs = [{
+                       label: 'ping_vnfd/cp0',
+                       value: 'ping_vnfd/cp0'
+               }, {
+                       label: 'pong_vnfd/cp0',
+                       value: 'pong_vnfd/cp0'
+               }];
+
+               /* end TODO */
+
+               this.vldInitParamsTypes = [
+                       'vim-network-name',
+                       'ip-profile-ref',
+                       'unknown'
+               ];
+
+               this.currentVLDInitParamsType = 'unknown';
+               this.registerAsync(NSVirtualLinkCreateSource);
+               this.bindAction(NSVirtualLinkCreateActions.EDIT_VIRTUAL_LINK_ERROR, this.editVirtualLinkError);
+               this.bindAction(NSVirtualLinkCreateActions.DELETE_VIRTUAL_LINK_ERROR, this.deleteVirtualLinkError);
+               this.bindAction(NSVirtualLinkCreateActions.CREATE_VIRTUAL_LINK_SUCCESS, this.createVirtualLinkSuccess);
+               this.bindAction(NSVirtualLinkCreateActions.EDIT_VIRTUAL_LINK_SUCCESS, this.editVirtualLinkSuccess);
+               this.bindAction(NSVirtualLinkCreateActions.DELETE_VIRTUAL_LINK_SUCCESS, this.deleteVirtualLinkSuccess);
+               this.exportPublicMethods({
+            persistVirtualLink: this.persistVirtualLink,
+            updateFirstLevelKey: this.updateFirstLevelKey,
+            updateSecondLevelKey: this.updateSecondLevelKey,
+            updateVLDInitParamsType: this.updateVLDInitParamsType,
+            updateVLDInitParamsValue: this.updateVLDInitParamsValue,
+            saveNSRId: this.saveNSRId,
+            saveVld: this.saveVld,
+            addConnectionPointRef: this.addConnectionPointRef,
+            removeConnectionPointRef: this.removeConnectionPointRef,
+            updateFirstLevelListKeyChange: this.updateFirstLevelListKeyChange,
+            saveMemberVnfIndexRefs: this.saveMemberVnfIndexRefs,
+            saveVnfdIdRefs: this.saveVnfdIdRefs,
+            saveIpProfileNames: this.saveIpProfileNames,
+            removeVirtualLink: this.removeVirtualLink,
+            saveMode: this.saveMode
+        });
+       }
+
+       resetState = () => {
+               delete this.vld;
+               let vld = {};
+
+               this.setState({
+
+               });
+       }
+
+       saveMode = (mode) => {
+               this.setState({
+                       mode: mode
+               })
+       }
+
+       saveVnfdIdRefs = (vnfdIdRefs) => {
+               this.setState({
+                       vnfdIdRefs: vnfdIdRefs
+               });
+       }
+
+       saveMemberVnfIndexRefs = (memberVnfIndexRefs) => {
+               this.setState({
+                       memberVnfIndexRefs: memberVnfIndexRefs
+               });
+       }
+
+       saveIpProfileNames = (ipProfileNames) => {
+               this.setState({
+                       ipProfileNames: ipProfileNames
+               });
+       }
+
+       saveNSRId = (nsrId) => {
+               this.setState({
+                       nsrId: nsrId
+               })
+       }
+
+       saveVld = (vld) => {
+               this.setState({
+                       vld:vld
+               })
+       }
+
+       updateFirstLevelKey = (key, e) => {
+               let vld = _.cloneDeep(this.vld);
+               let value = e.target.nodeName == "SELECT" ? JSON.parse(e.target.value) : e.target.value;
+               vld[key] = value;
+               this.setState({
+                       vld: vld
+               });
+       }
+
+       updateSecondLevelKey = (firstLevelKey, secondLevelKey, e) => {
+               let vld = _.cloneDeep(this.vld);
+               if (!vld[firstLevelKey]) {
+                       vld[firstLevelKey] = {};
+               }
+               let value = e.target.nodeName == "SELECT" ? JSON.parse(e.target.value) : e.target.value;
+               vld[firstLevelKey][secondLevelKey] = value;
+               this.setState({
+                       vld: vld
+               });
+       }
+
+       updateVLDInitParamsType = (value) => {
+               let vld = this.vld;
+
+               // Reset init param types
+               this.vldInitParamsTypes.map((vldInitParamType) => {
+                       vld[vldInitParamType] && delete vld[vldInitParamType];
+               });
+
+               this.setState({
+                       currentVLDInitParamsType: value,
+                       vld: vld
+               })
+       }
+
+       updateVLDInitParamsValue = (currentVLDInitParamsType, e) => {
+               let vld = _.cloneDeep(this.vld);
+               this.vldInitParamsTypes.map((vldInitParamType) => {
+                       if (currentVLDInitParamsType == vldInitParamType) {
+                               vld[currentVLDInitParamsType] = e.target.value;
+                       } else {
+                               vld[vldInitParamType] && delete vld[vldInitParamType];
+                       }
+               });
+
+               this.setState({
+                       vld: vld
+               })
+       }
+
+       updateFirstLevelListKeyChange = (listName, index, keyName, e) => {
+               let vld = _.cloneDeep(this.vld);
+               
+
+               !vld[listName] && (vld[listName] = []);
+               !vld[listName][index] && (vld[listName][index] = {});
+               vld[listName][index][keyName] = e.target.value;
+               
+               this.setState({
+                       vld: vld
+               })
+       }
+
+       addConnectionPointRef = () => {
+               let vld = {};
+               if (this.vld) {
+                       vld = _.cloneDeep(this.vld);
+                       if (!vld['vnfd-connection-point-ref']) {
+                               vld['vnfd-connection-point-ref'] = [];
+                       }
+                       vld['vnfd-connection-point-ref'].push({
+                               'member-vnf-index-ref': '',
+                               'vnfd-id-ref': '',
+                               'vnfd-connection-point-ref': ''
+                       });
+
+                       this.setState({
+                               vld: vld
+                       });
+               }
+       }
+
+       removeConnectionPointRef = (vnfdConnectionPointRefIndex) => {
+               let vld = _.cloneDeep(this.vld);
+               vld['vnfd-connection-point-ref'].splice(vnfdConnectionPointRefIndex, 1);
+               this.setState({
+                       vld: vld
+               });
+       }
+
+       createVirtualLinkError(data) {
+               this.alt.actions.global.showError.defer('Something went wrong while trying to create the virtual link. Check the error logs for more information');
+       }
+
+       editVirtualLinkError(data) {
+               this.alt.actions.global.showError.defer('Something went wrong while trying to save the virtual link. Check the error logs for more information');
+       }
+
+       deleteVirtualLinkError(data) {
+               this.alt.actions.global.showError.defer('Something went wrong while trying to delete the virtual link. Check the error logs for more information');
+               this.setState({
+                       deleteState: 'error'
+               })
+       }
+
+       createVirtualLinkSuccess(data) {
+               this.setState({
+                       // vld: this.vld,
+                       mode: 'editing',
+                       isLoading: false
+               });
+       }
+       editVirtualLinkSuccess(data) {
+               this.setState({
+                       mode: 'editing',
+                       isLoading: false
+               });
+       }
+       deleteVirtualLinkSuccess(data) {
+               this.setState({
+                       deleteState: 'success'
+               });
+       }
+
+       cleanupPayload = (mode, vld) => {
+               // Do necessary cleanup here
+               let cleanVld = _.pickBy(vld, _.identity);
+               return cleanVld;
+       }
+
+       setLoadingState = (state = false) => {
+               this.setState({
+                       isLoading: state
+               })
+       }
+
+       setLoaded = () => {
+               this.setLoadingState(true);
+       }
+
+       persistVirtualLink = (mode) => {
+               let self = this;
+
+               let payload = this.cleanupPayload(mode, this.vld);
+
+               if (mode == 'creating') {
+                       this.getInstance().createVirtualLink(this.nsrId, payload);
+               } else {
+                       this.getInstance().editVirtualLink(this.nsrId, this.vld.id, payload);
+               }
+       }
+
+       removeVirtualLink = (nsrId, vldId) => {
+               this.getInstance().deleteVirtualLink(nsrId, vldId);
+       }
+
+}
+
+export default NSVirtualLinkCreateStore;
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkDetails.jsx b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinkDetails.jsx
new file mode 100644 (file)
index 0000000..33404e0
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import RecordViewStore from '../recordViewer/recordViewStore.js';
+import Utils from 'utils/utils.js';
+import _ from 'lodash';
+import './nsVirtualLinks.scss';
+import UpTime from 'widgets/uptime/uptime.jsx';
+import NSVirtualLinksStore from './nsVirtualLinksStore.js';
+import NSVirtualLinksActions from './nsVirtualLinksActions.js';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+
+class NsVirtualLinkDetails extends React.Component {
+       constructor(props) {
+               super(props);
+               this.state = NSVirtualLinksStore.getState();
+       }
+
+       resolvePath = (obj, path) => {
+               // supports a.b, a[1] and foo[bar], etc.
+               // where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]
+               // then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;
+               path = path.split(/[\.\[\]]/).filter(d => d);
+               return path.reduce((r, p) => {
+                       if (r) {
+                               return r[p];
+                       }
+               }, obj);
+       }
+
+       transformValue(field, value) {
+               let transformedValue = (field.transform && field.transform(value)) || value;
+               if (typeof transformedValue == 'object') {
+                       transformedValue = JSON.stringify(transformedValue);
+               }
+               return transformedValue;
+       }
+
+       render() {
+
+               let self = this;
+               let column = [];
+               
+               this.state.column.categories.map((category) => {
+                       let fields = [];
+
+                       category.fields && category.fields.map((field) => {
+                               let value = this.resolvePath(this.props.virtualLink, field.key);
+                               let textFields = [];
+
+                               if (_.isArray(value)) {
+                                       value.map((v, idx) => {
+                                               let transformedValue = this.transformValue(field, v);
+                                               textFields.push(
+                                                       <TextInput key={field.key + idx} className='value' type='text' value={transformedValue} readonly='true' defaultValue='--' />
+                                               );
+                                       })
+                               } else {
+                                       let transformedValue = this.transformValue(field, value);
+                                       textFields.push(
+                                               <TextInput key={field.key} className='value' label={field.label} type='text' value={transformedValue} readonly='true' defaultValue='--' />
+                                       );
+                               }
+                               fields.push(
+                                       <div key={field.key}>
+                                               {textFields}
+                                       </div>
+                               );
+                       });
+
+                       column.push(
+                               <div key={category.key}>
+                                       <h3>
+                                               {category.label}
+                                       </h3>
+                                       {fields}
+                               </div>
+                       );
+               });
+
+               
+               return this.props.virtualLink ? (
+                       <div className='nsVirtualLinkDetails'>
+                               <div className='column'>
+                                       {column}
+                               </div>
+                       </div>
+               ) : null
+       }
+}
+
+export default SkyquakeComponent(NsVirtualLinkDetails);
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinks.jsx b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinks.jsx
new file mode 100644 (file)
index 0000000..8870dfc
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import NSVirtualLinkCreateStore from './nsVirtualLinkCreateStore.js';
+import Button from 'widgets/button/rw.button.js';
+import Utils from 'utils/utils.js';
+import _ from 'lodash';
+import './nsVirtualLinks.scss';
+import UpTime from 'widgets/uptime/uptime.jsx';
+import NSVirtualLinkDetails from './nsVirtualLinkDetails.jsx';
+import NSVirtualLinkCreate from './nsVirtualLinkCreate.jsx';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+
+class NsVirtualLinks extends React.Component {
+       constructor(props) {
+               super(props);
+           this.Store = this.props.flux.stores.hasOwnProperty('NSVirtualLinkCreateStore') ? this.props.flux.stores.NSVirtualLinkCreateStore : this.props.flux.createStore(NSVirtualLinkCreateStore);
+               this.state = {};
+               this.state.mode = 'viewing';    // Can be 'viewing'/'creating'/'editing'/'deleting'. Default is 'viewing'
+               this.selectedVirtualLink = null;
+               this.editingVirtualLink = null;
+               this.Store.listen(this.handleUpdate);
+       }
+
+       handleUpdate = (storeState) => {
+               // all we care about is if delete succeeded
+               if (storeState.deleteState == 'success') {
+                       this.setState({
+                               mode: 'viewing',
+                               selectedVirtualLink: this.props.data && this.props.data['decorated-vlrs'] && this.props.data['decorated-vlrs'][0],
+                               editingVirtualLink: null
+                       });
+               }
+       }
+
+       componentWillMount() {
+               if (this.state.mode == 'viewing' && !this.state.selectedVirtualLink) {
+                       this.setState({
+                               selectedVirtualLink: this.props.data && this.props.data['decorated-vlrs'] && this.props.data['decorated-vlrs'][0]
+                       });
+               }
+
+               if (!this.state.nsd) {
+                       this.setState({
+                               nsd: this.props.data.nsd
+                       });     
+               }
+
+               if (!this.state.nsrId) {
+                       this.setState({
+                               nsrId: this.props.data.id
+                       });
+               }
+
+       }
+
+       componentWillUnmount() {
+               this.Store.unlisten(this.handleUpdate)
+       }
+
+       componentWillReceiveProps(nextProps) {
+               if (!this.state.nsd) {
+                       this.setState({
+                               nsd: nextProps.data.nsd
+                       });     
+               }
+
+               if (!this.state.nsrId) {
+                       this.setState({
+                               nsrId: nextProps.data.id
+                       });
+               }
+       }
+
+
+       handleCreateVirtualLinkClick = (nsrId, event) => {
+               this.setState({
+                       mode: 'creating'
+               });
+       }
+
+       resetState = () => {
+               let self = this;
+               this.setState({
+                       mode: 'viewing',
+                       selectedVirtualLink: self.props.data && self.props.data['decorated-vlrs'] && self.props.data['decorated-vlrs'][0],
+                       editingVirtualLink: null
+               })
+       }
+
+       handleDeleteVirtualLinkClick = (nsrId, virtualLinkId, event) => {
+               let self = this;
+               event.preventDefault();
+               event.stopPropagation();
+               this.Store.removeVirtualLink(nsrId, virtualLinkId);
+       }
+
+       handleSelectVirtualLinkClick = (virtualLinkId, event) => {
+               this.setState({
+                       mode: 'viewing',
+                       selectedVirtualLink: this.props.data && this.props.data['decorated-vlrs'] && _.find(this.props.data['decorated-vlrs'], {id: virtualLinkId}),
+                       editingVirtualLink: null
+               });
+       }
+       handleEditVirtualLinkClick = (nsrId, vlrId, vldId, event) => {
+               event.stopPropagation();
+               this.setState({
+                       mode: 'editing',
+                       editingVirtualLink: this.props.data && this.props.data['nsd'] && this.props.data['nsd']['vld'] && _.find(this.props.data['nsd']['vld'], {id: vldId}),
+                       selectedVirtualLink: this.props.data && this.props.data['decorated-vlrs'] && _.find(this.props.data['decorated-vlrs'], {id: vlrId})
+               });
+       }
+
+       handleCancelCreate = () => {
+               this.resetState();
+       }
+
+       createVirtualLinksTable = () => {
+               let trows = [];
+
+               let nsr = this.props.data && this.props.data;
+               let nsd = nsr.nsd && nsr.nsd;
+
+               nsr['decorated-vlrs'] && nsr['decorated-vlrs'].map((vlr, vlrIndex) => {
+                       let name = vlr.name || 'New virtual link being created';
+                       let operationalStatus = vlr['operational-status'];
+                       let vlrId = vlr['id'];
+                       let vldId = vlr['vld-ref'];
+
+                       let selectedClassName = (!(this.state.mode == 'creating') && ((this.state.selectedVirtualLink && this.state.selectedVirtualLink.id) == vlrId)) ? 'selectedVirtualLink' : ''
+
+                       trows.push(
+                               <tr key={vlrIndex} className={selectedClassName} onClick={this.handleSelectVirtualLinkClick.bind(this, vlrId)}>
+                                       <td>{name}</td>
+                                       <td>{operationalStatus}</td>
+                                       <td>
+                                               <a onClick={this.handleEditVirtualLinkClick.bind(this, this.props.data.id, vlrId, vldId)}>
+                                                       <span className="oi" data-glyph="pencil" aria-hidden="true"></span>
+                                               </a>
+                                               <a onClick={this.handleDeleteVirtualLinkClick.bind(this, this.props.data.id, vldId)}>
+                                                       <span className="oi" data-glyph="trash" aria-hidden="true"></span>
+                                               </a>
+                                       </td>
+                               </tr>
+                       );
+               });
+
+               let tbody = (
+                       <tbody>
+                               {trows}
+                       </tbody>
+               );
+
+               return (
+                       <table className="nsVirtualLinksTable">
+                           <thead>
+                               <tr>
+                                       <th style={{width: '50%'}}>Name</th>
+                                   <th style={{width: '35%'}}>Status</th>
+                                   <th style={{width: '15%'}}> </th>
+                               </tr>
+                           </thead>
+                           {tbody}
+                       </table>
+               );
+
+               return (
+                       <div>
+                               {JSON.stringify(nsd)}
+                       </div>
+               );
+       }
+
+       render() {
+               let nsVirtualLinksTable = this.createVirtualLinksTable();
+
+               let nsVirtualLinkCreateButton = (
+                       <Button label='Create Virtual Link' className="dark" isLoading={false} onClick={this.handleCreateVirtualLinkClick.bind(this, this.props.data.id)} />
+               );
+
+               let nsVirtualLinkDetails = null;
+               if (this.state.mode == 'viewing') {
+                       nsVirtualLinkDetails = (
+                               <div className='nsVirtualLinkDetailsWrapper'>
+                       <div className="launchpadCard_title" style={{textAlign:'right'}}><span style={{float:'left'}}>VLR DETAILS</span>
+                                       </div>
+                       <NSVirtualLinkDetails virtualLink={this.state.selectedVirtualLink} mode={this.state.mode} nsd={this.props.data}/>
+                </div>
+                       );
+               } else {
+                       nsVirtualLinkDetails = (
+                               <div className='nsVirtualLinkDetailsWrapper'>
+                       <div className="launchpadCard_title" style={{textAlign:'right'}}><span style={{float:'left'}}>VLD DETAILS</span>
+                                       </div>
+                       {
+                               <NSVirtualLinkCreate vld={this.state.editingVirtualLink} mode={this.state.mode} nsd={this.state.nsd} nsrId={this.state.nsrId} onCancel={this.handleCancelCreate}/>
+                       }
+                </div>
+            );
+               }
+
+               return (
+                       <div className='nsVirtualLinks'>
+                <div className='nsVirtualLinksListWrapper'>
+                       <div className="launchpadCard_title" style={{textAlign:'right'}}><span style={{float:'left'}}>VIRTUAL LINKS</span>
+                                       </div>
+                       <div className='nsVirtualLinksTableWrapper'>
+                               {nsVirtualLinksTable}
+                       </div>
+                       <div className='nsVirtualLinksCreateButtonWrapper'>
+                               {nsVirtualLinkCreateButton}
+                       </div>
+                </div>
+                {nsVirtualLinkDetails}
+            </div>
+               );
+       }
+}
+export default SkyquakeComponent(NsVirtualLinks);
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinks.scss b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinks.scss
new file mode 100644 (file)
index 0000000..57cf0a9
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+@import "style/_colors.scss";
+
+@mixin optional() {
+    // height: 1.25rem;
+    // margin-left: 0.5rem;
+    // margin-top: 0.5rem;
+    flex: 0 1 auto;
+}
+.nsVirtualLinksContainer {
+    flex: 1 0 100%;
+}
+.nsVirtualLinks {
+    display: flex;
+    flex: 1 1 100%;
+    flex-direction: row;
+
+    .nsVirtualLinksListWrapper {
+        display: flex;
+        flex: 1 1 100%;
+        flex-direction: column;
+        margin-right: 0.5rem;
+        min-width: 50%;
+        max-width: 50%;
+        
+        .nsVirtualLinksTableWrapper {
+            padding: 1rem;
+
+            .nsVirtualLinksTable {
+                background: white;
+                border-collapse: collapse;
+                border: 1px solid black;
+                text-transform: capitalize;
+                width: 100%;
+
+                tr {
+                    cursor: pointer;
+                    a {
+                        cursor: pointer;
+                        margin-left: 0.5rem;
+                        font-weight: normal;
+                        color: $black;
+                    }
+                    &.selectedVirtualLink {
+                        background: $gray-darkest !important;
+                        color: $white !important;
+                        a {
+                            color: $white;
+                        }
+                    }
+                }
+                th {
+                    text-align: left;
+                    padding: 0.5rem;
+                    background: $gray-dark;
+                    border: 1px solid black;
+                }
+                tr:nth-child(odd) {
+                    background: $gray-lighter;
+                    td {
+                        border: 1px solid black;
+                        padding: 0.5rem;
+                    }
+                }
+                tr:nth-child(even) {
+                    background: $white;
+                    td {
+                        border: 1px solid black;
+                        padding: 0.5rem;
+                    }
+                }
+            }
+        }
+    }
+
+    .nsVirtualLinkDetailsWrapper {
+        display: flex;
+        flex: 1 1 100%;
+        flex-direction: column;
+        min-width: 50%;
+        max-width: 50%;
+
+        .nsVirtualLinkDetails {
+            padding: 1rem;
+            display: flex;
+            flex-direction: row;
+
+            h3 {
+                display: flex;
+                text-decoration: underline;
+                margin-bottom: 1rem;
+            }
+
+            .column {
+                flex: 1 1 100%;
+                .title {
+                    opacity: 0.5;
+                }
+                .value {
+                    display: flex;
+                    margin-bottom: 0.5rem;
+                    .readonly {
+                        background: none !important;
+                    }
+                }
+            }
+        }
+
+        .createVirtualLink {
+            padding: 1rem;
+            display: flex;
+            flex-direction: column;
+
+            label {
+                display: flex;
+                flex-direction: column;
+                width: 100%;
+                margin-bottom: 1rem;
+                align-items: flex-start;
+                justify-content: flex-start;
+                span {
+                    margin-bottom: 0.5rem;
+                }
+                select {
+                    font-size: 1rem;
+                    min-width: 75%;
+                }
+            }
+
+            h3 {
+                display: flex;
+                text-decoration: underline;
+                margin-bottom: 1rem;
+            }
+
+            .readonly {
+                background: none !important;
+            }
+
+            .inputControls-radioGroup {
+                display: flex;
+                .inputControls-radio {
+                    display: flex;
+                    flex-direction: row;
+                    width: inherit;
+                    margin-right: 1rem;
+                }
+            }
+
+            .vnfd-connection-points-list {
+                .vnfd-connection-points-list-item {
+                    padding: 1rem;
+                    background: $gray;
+
+                    &:nth-child(odd) {
+                        background: $gray-dark;
+                    }
+
+                    &:last-child {
+                        margin-bottom: 1rem;
+                    }
+
+                    input {
+                        min-width: 75%;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinksActions.js b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinksActions.js
new file mode 100644 (file)
index 0000000..05e9e51
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+module.exports = function(Alt) {
+   return Alt.generateActions();
+}
diff --git a/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinksStore.js b/skyquake/plugins/launchpad/src/virtual_links/nsVirtualLinksStore.js
new file mode 100644 (file)
index 0000000..1c0fc14
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import NSVirtualLinksActions from './nsVirtualLinksActions.js';
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+
+class NSVirtualLinksStore {
+       constructor() {
+               this.column = {
+                       categories: [{
+                               key: 'details',
+                               label: 'DETAILS',
+                               fields: [{
+                                       key: 'id',
+                                       label: 'ID'
+                               }, {
+                                       key: 'name',
+                                       label: 'NAME'
+                               }, {
+                                       key: 'short-name',
+                                       label: 'SHORT NAME'
+                               }, {
+                                       key: 'vendor',
+                                       label: 'VENDOR'
+                               }, {
+                                       key: 'description',
+                                       label: 'DESCRIPTION'
+                               }, {
+                                       key: 'version',
+                                       label: 'VERSION'
+                               }, {
+                                       key: 'type',
+                                       label: 'TYPE'
+                               }, {
+                                       key: 'root-bandwidth',
+                                       label: 'ROOT BANDWIDTH'
+                               }, {
+                                       key: 'leaf-bandwidth',
+                                       label: 'LEAF BANDWIDTH'
+                               }, {
+                                       key: 'res-id',
+                                       label: 'RESOURCE MANAGER ID'
+                               }, {
+                                       key: 'network-id',
+                                       label: 'NETWORK ID'
+                               }]
+                       }, {
+                               key: 'provider-network',
+                               label: 'PROVIDER NETWORK',
+                               fields: [{
+                                       key: 'provider-network.physical-network',
+                                       label: 'PHYSICAL NETWORK'
+                               }, {
+                                       key: 'provider-network.overlay-type',
+                                       label: 'OVERLAY TYPE'
+                               }, {
+                                       key: 'provider-network.segmentation_id',
+                                       label: 'SEGMENTATION ID'
+                               }]
+                       }, {
+                               key: 'status',
+                               label: 'STATUS',
+                               fields: [{
+                                       key: 'status',
+                                       label: 'STATUS'
+                               }, {
+                                       key: 'operational-status',
+                                       label: 'OPERATIONAL STATUS'
+                               }, {
+                                       key: 'create-time',
+                                       label: 'CREATE TIME',
+                                       transform: (value) => {
+                                               if (!value) {
+                                                       return null;
+                                               }
+                                               return new Date(value);
+                                       }
+                               }]
+                       }, {
+                               key: 'vim',
+                               label: 'VIMS',
+                       }, {
+                               key: 'vnfr-connection-point-ref',
+                               label: 'VNF CONNECTION POINTS',
+                               type: 'list',
+                               fields: [{
+                                       key: 'vnfr-connection-point-ref',
+                                       label: 'VNF Connection Point',
+                                       transform: (value) => {
+                                               return (value && (value['vnfr-name'] + ': ' + value['connection-point']));
+                                       }
+                               }]
+                       },  {
+                               key: 'ip-profile-params',
+                               label: 'IP PROFILE INFO',
+                               fields: [{
+                                       key: 'ip-profile-params.ip-version',
+                                       label: 'IP VERSION'
+                               }, {
+                                       key: 'ip-profile-params.subnet-address',
+                                       label: 'SUBNET ADDRESS'
+                               }, {
+                                       key: 'ip-profile-params.gateway-address',
+                                       label: 'GATEWAY ADDRESS'
+                               }, {
+                                       key: 'ip-profile-params.security-group',
+                                       label: 'SECURITY GROUP'
+                               }, {
+                                       key: 'ip-profile-params.subnet-prefix-pool',
+                                       label: 'SUBNET PREFIX POOL'
+                               }, {
+                                       key: 'ip-profile-params.dns-server',
+                                       label: 'DNS SERVERS',
+                                       type: 'list'
+                               }, {
+                                       key: 'ip-profile-params.dhcp-params.enabled',
+                                       label: 'ENABLED'
+                               }, {
+                                       key: 'ip-profile-params.dhcp-params.start-address',
+                                       label: 'START ADDRESS'
+                               }, {
+                                       key: 'ip-profile-params.dhcp-params.count',
+                                       label: 'COUNT'
+                               }]
+                       }]
+               };
+       }
+}
+
+export default Alt.createStore(NSVirtualLinksStore, 'NSVirtualLinksStore');
\ No newline at end of file
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrActions.js b/skyquake/plugins/launchpad/src/vnfr/vnfrActions.js
new file mode 100644 (file)
index 0000000..3e9d0dc
--- /dev/null
@@ -0,0 +1,20 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var alt = require('../alt');
+export default alt.generateActions('openVnfrSocketLoading','openVnfrSocketSuccess','openVnfrSocketError')
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrCard.jsx b/skyquake/plugins/launchpad/src/vnfr/vnfrCard.jsx
new file mode 100644 (file)
index 0000000..43c199e
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import MonitoringParamsCarousel from '../monitoring_params/monitoringParamsCarousel.jsx';
+import './vnfrCard.scss';
+import VnfrCardNfviMetrics from './vnfrCardNfviMetrics.jsx';
+class VnfrCard extends React.Component{
+  constructor(props) {
+    super(props);
+  }
+  render() {
+    let html;
+    let monitoring_params = <MonitoringParamsCarousel component_list={this.props.data["monitoring-param"]} slideno={this.props.slideno}/>;
+    let nfviMetrics = this.props.data["nfvi-metrics"] ? <VnfrCardNfviMetrics metrics={this.props.data["nfvi-metrics"]} /> : <div style={{textAlign:'center', paddingTop:'2rem'}}>No NFVI Metrics Configured</div>;
+    console.log(this.props.data)
+    html = (
+      <DashboardCard className="VNFRcard" showHeader={true} title={this.props.data["short-name"]}>
+        {monitoring_params}
+        {nfviMetrics}
+      </DashboardCard>
+    )
+    return html;
+  }
+}
+
+export default VnfrCard;
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrCard.scss b/skyquake/plugins/launchpad/src/vnfr/vnfrCard.scss
new file mode 100644 (file)
index 0000000..08a3bc4
--- /dev/null
@@ -0,0 +1,36 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+.VNFRcard {
+  width:400px;
+  &_header{
+    background:white;
+  }
+  &_content {
+    &>div:not(:last-child) {
+      border-bottom:0.125rem solid white;
+    }
+  }
+  .nfviMetrics {
+    display:flex;
+    &>div{
+      padding: 1rem;
+      text-align:center;
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrCardNfviMetrics.jsx b/skyquake/plugins/launchpad/src/vnfr/vnfrCardNfviMetrics.jsx
new file mode 100644 (file)
index 0000000..9efcbe7
--- /dev/null
@@ -0,0 +1,47 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import Bullet from 'widgets/bullet/bullet.js';
+class VnfrCardNfviMetrics extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  render() {
+    let height = 100;
+    let html = (
+       <div className="nfviMetrics">
+          <div>
+            <h3>{this.props.metrics[0].label}</h3>
+            <h3>{this.props.metrics[0].total}</h3>
+          </div>
+          <div>
+            <h3>{this.props.metrics[1].label}</h3>
+            <Bullet textMarginY={height - (height/2) + 15} fontSize={height / 2} height={height} value={Math.round(this.props.metrics[1].utilization * 100)} />
+          </div>
+          <div>
+            <h3>{this.props.metrics[2].label}</h3>
+            <Bullet textMarginY={height - (height/2) + 15} fontSize={height / 2}  height={height} value={Math.round(this.props.metrics[2].utilization * 100)} />
+          </div>
+        </div>
+    );
+    return html;
+  }
+}
+
+export default VnfrCardNfviMetrics;
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrSource.js b/skyquake/plugins/launchpad/src/vnfr/vnfrSource.js
new file mode 100644 (file)
index 0000000..bcb8252
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+let alt = require('../alt');
+import VnfrActions from './vnfrActions.js';
+let Utils = require('utils/utils.js');
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let isSocketOff = true;
+import $ from 'jquery';
+
+export default {
+  openVnfrSocket: function() {
+    return {
+      remote: function(state) {
+        let nsrRegEx = new RegExp("([0-9a-zA-Z-]+)\/vnfr$");
+        let nsr_id;
+        try {
+          console.log('NSR ID in url is', window.location.hash.match(nsrRegEx)[1]);
+          nsr_id = window.location.hash.match(nsrRegEx)[1];
+        } catch (e) {
+
+        }
+        return new Promise(function(resolve, reject) {
+          if (state.socket) {
+            resolve(false);
+          }
+          console.log(nsr_id)
+          $.ajax({
+            url: '//' + window.location.hostname + ':' + NODE_PORT + '/socket-polling?api_server=' + API_SERVER,
+            type: 'POST',
+            beforeSend: Utils.addAuthorizationStub,
+            data: {
+              url: API_SERVER + ':' + NODE_PORT + '/launchpad/nsr/' + nsr_id + '/vnfr?api_server=' + API_SERVER,
+            },
+            success: function(data) {
+              Utils.checkAndResolveSocketRequest(data, resolve, reject);
+            }
+          });
+        })
+      },
+      loading: VnfrActions.openVnfrSocketLoading,
+      success: VnfrActions.openVnfrSocketSuccess,
+      error: VnfrActions.openVnfrSocketError,
+    }
+  }
+}
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrStore.js b/skyquake/plugins/launchpad/src/vnfr/vnfrStore.js
new file mode 100644 (file)
index 0000000..9a64531
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import VnfrActions from './vnfrActions.js';
+import VnfrSource from './vnfrSource.js';
+
+let alt = require('../alt');
+class VnfrStore {
+  constructor() {
+    this.vnfrs = [];
+    this.socket;
+    this.isLoading = false;
+    this.bindActions(VnfrActions);
+    this.exportAsync(VnfrSource);
+
+
+
+  }
+  openVnfrSocketError() {
+
+  }
+  openVnfrSocketLoading() {
+
+  }
+  openVnfrSocketSuccess(connection) {
+    var self = this;
+    let ws = window.multiplexer.channel(connection);
+    if (!connection) return;
+    self.setState({
+      socket: ws.ws,
+      channelId: connection
+    });
+    ws.onmessage = function(data) {
+      try {
+        var data = JSON.parse(data.data);
+        if (!data) {
+          console.warn('NSRS property not present on the payload, check that the api server is functioning correct and that the LP is fully launched. Received: ', data);
+          data = [];
+        }
+        self.setState({
+          vnfrs: data,
+          isLoading: false
+        });
+      } catch (e) {
+
+      }
+    };
+  }
+};
+
+export default alt.createStore(VnfrStore)
diff --git a/skyquake/plugins/launchpad/src/vnfr/vnfrView.jsx b/skyquake/plugins/launchpad/src/vnfr/vnfrView.jsx
new file mode 100644 (file)
index 0000000..0e1a380
--- /dev/null
@@ -0,0 +1,64 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import VnfrActions from './vnfrActions.js';
+import VnfrSource from './vnfrSource.js';
+import VnfrStore from './vnfrStore.js';
+import VnfrCard from './vnfrCard.jsx';
+import Loader from 'widgets/loading-indicator/loadingIndicator.jsx';
+import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
+let ReactCSSTransitionGroup = require('react-addons-css-transition-group');
+class VnfrView extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = VnfrStore.getState();
+    this.state.vnfrs = [];
+  }
+  componentDidMount() {
+    VnfrStore.listen(this.handleUpdate);
+    console.log(VnfrStore)
+    setTimeout(function() {
+      VnfrStore.openVnfrSocket();
+      // VnfrStore.vnfrMock();
+    },100);
+  }
+  handleUpdate = (data) => {
+    this.setState(data);
+  }
+  render() {
+    let self = this;
+    let html;
+    let vnfrCards = [];
+    self.state.vnfrs.map(function(vnfr) {
+                 vnfrCards.push(<VnfrCard data={vnfr}></VnfrCard>)
+    })
+    html = (
+            <ReactCSSTransitionGroup
+            transitionName="loader-animation"
+            component="div"
+            className="dashboardCard_wrapper"
+
+            >
+              {vnfrCards}
+            </ReactCSSTransitionGroup>
+    );
+    return html;
+  }
+}
+export default VnfrView;
diff --git a/skyquake/plugins/launchpad/webpack.production.config.js b/skyquake/plugins/launchpad/webpack.production.config.js
new file mode 100644 (file)
index 0000000..3984a58
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+var CommonsPlugin = new require("webpack/lib/optimize/CommonsChunkPlugin")
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /react-treeview/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass?includePaths[]='+ path.resolve(frameworkPath)
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="app"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/logging/CMakeLists.txt b/skyquake/plugins/logging/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1bf2963
--- /dev/null
@@ -0,0 +1,51 @@
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# 
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+  logging
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+  CONFIGURE_COMMAND echo
+  BUILD_COMMAND
+    ${CMAKE_CURRENT_BINARY_DIR}/logging/logging-build/scripts/build.sh
+  INSTALL_COMMAND
+    ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+    ${CMAKE_CURRENT_BINARY_DIR}/logging/logging-build
+    ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+    ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+  BCACHE_COMMAND echo
+)
+
diff --git a/skyquake/plugins/logging/api/logging.js b/skyquake/plugins/logging/api/logging.js
new file mode 100644 (file)
index 0000000..086d864
--- /dev/null
@@ -0,0 +1,479 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Promise = require('bluebird');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var request = utils.request;
+var constants = require('../../../framework/core/api_utils/constants.js');
+var _ = require('lodash');
+var APIVersion = '/v1';
+var transforms = require('./transforms.js');
+
+var foreverOn = true;
+
+var Config = {};
+var Console = {};
+var Filter = {};
+var Operational = {};
+var Sink = {};
+var SysLogViewer = {};
+var Aggregate = {};
+
+var Test = {};
+
+// Helper functions
+// TODO: Consolidate the build functions, provide method type as arg
+
+function buildGetRequestOptions(req, endpoint) {
+  var headers = _.extend({},
+    constants.HTTP_HEADERS.accept.data, {
+    'Authorization': req.get('Authorization')
+  });
+  var api_server = req.query["api_server"];
+  var requestOptions = {
+    url: utils.confdPort(api_server) + endpoint,
+    method: 'GET',
+    headers: headers,
+    forever: constants.FOREVER_ON,
+    rejectUnauthorized: false
+  };
+  return requestOptions;
+}
+
+function buildPutRequestOptions(req, endpoint, jsonData) {
+  var headers = _.extend({},
+    constants.HTTP_HEADERS.accept.data,
+    constants.HTTP_HEADERS.content_type.data, {
+    'Authorization': req.get('Authorization')
+  });
+  var api_server = req.query["api_server"];
+  var requestOptions = {
+    url: utils.confdPort(api_server) + endpoint,
+    method: 'PUT',
+    headers: headers,
+    forever: constants.FOREVER_ON,
+    rejectUnauthorized: false,
+    json: jsonData
+  };
+  return requestOptions;
+}
+
+
+function buildDeleteRequestOptions(req, endpoint) {
+  var headers = _.extend({},
+    constants.HTTP_HEADERS.accept.data,
+    constants.HTTP_HEADERS.content_type.data, {
+    'Authorization': req.get('Authorization')
+  });
+  var api_server = req.query["api_server"];
+  var requestOptions = {
+    url: utils.confdPort(api_server) + endpoint,
+    method: 'DELETE',
+    headers: headers,
+    forever: constants.FOREVER_ON,
+    rejectUnauthorized: false
+  };
+  return requestOptions;
+}
+
+/**
+* Used for simulating latency
+*/
+function resolve_with_delay(resolve, data, delay) {
+  return setTimeout(function() {
+    resolve(data)
+  }, delay);
+}
+
+/**
+ * This function provides the default callback for requests
+ */
+function requestCallback(resolve, reject, transformFunc) {
+  return function(error, response, body) {
+    if (utils.validateResponse('', error, response, body, resolve, reject)) {
+      if (transformFunc) {
+        var data = transformFunc(response.body);
+      } else {
+        var data = JSON.stringify(response.body);
+      }
+      return resolve_with_delay(resolve, {
+        statusCode: response.statusCode,
+        data: data
+      }, 0);
+    };
+  };
+}
+
+function handleGetRequest(req, endpoint, responseTransform) {
+  return new Promise(function(resolve, reject) {
+    request(
+      buildGetRequestOptions(req, endpoint),
+      requestCallback(resolve, reject, responseTransform)
+    );
+  });
+}
+
+/**
+ *
+ */
+// TODO: Add arg for transform function to transfrm req.body to json data
+// Right now we'll just pass the request through, until we need to implement
+// a transformer
+function handlePutRequest(req, endpoint, body) {
+  return new Promise(function(resolve, reject) {
+    request(
+      buildPutRequestOptions(req, endpoint, body||req.body),
+      requestCallback(resolve, reject)
+    );
+  });
+}
+
+function handleDeleteRequest(req, endpoint, body) {
+  return new Promise(function(resolve, reject) {
+    request(
+      buildDeleteRequestOptions(req, endpoint),
+      requestCallback(resolve, reject)
+    );
+  });
+}
+
+function handleMockResponse(req, success, statusCode, data, delay) {
+  delay = delay || 0;
+  return new Promise(function(resolve, reject) {
+    if (success) {
+      resolve_with_delay(resolve, { statusCode: statusCode, data: data }, delay)
+    } else { reject({ statusCode: statusCode, data: data }); }
+  });
+}
+
+
+function handleReject(req, statusCode, message) {
+  return new Promise(function(resolve, reject) {
+    reject({ statusCode: statusCode, data: message});
+  })
+}
+
+/**
+* Calllback function to parse the response body into an object and
+* remove the restconf top level key if it is present.
+*/
+function transformLoggingRootResponseCallback(responseBody) {
+  var data = JSON.parse(responseBody);
+  if (data['rwlog-mgmt:logging']) {
+    data = data['rwlog-mgmt:logging'];
+  }
+  return data;
+}
+
+
+/**
+ * Debug function
+ */
+function dumpLoggingConfig(data) {
+  console.log("dumpLoggingconfig");
+  var logConfig = data['lwlog-mgmt:logging'] || data;
+
+  console.log("keys=", Object.keys(logConfig));
+  console.log("stringify=", JSON.stringify(logConfig));
+  if (logConfig['default-severity']) {
+    logConfig['default-severity'].forEach(function(obj) {
+      console.log(obj);
+    })
+  }
+  if (logConfig['sink']) {
+    console.log('sink=', JSON.stringify(logConfig['sink']));
+  }
+  if (logConfig['console']) {
+    console.log('console=', JSON.stringify(logConfig['console']));
+  }
+  if (logConfig['deny']) {
+    console.log('deny=', JSON.stringify(logConfig['deny']));
+  }
+}
+
+// Aggregate calls
+
+/**
+* This method should fill out the full data set
+*/
+Aggregate.get = function(req) {
+  // get config data
+  // get operational data
+  //massage them
+  var configData = Config.get(req);
+  var operationalData = Operational.get(req);
+
+  return new Promise(function(resolve, reject) {
+    Promise.all([configData, operationalData]).then(function(resolves) {
+      //console.log("Resolved all request promises (config, operational logging data)");
+      // TODO: Make sure the statusCodes for each resulves is 200
+      var decoder = new transforms.LoggingConfigDecoder();
+      resolve({
+        statusCode: 200,
+        data: decoder.decode(resolves[0], resolves[1])
+      });
+
+    }).catch(function(error) {
+      console.log("Logging: Aggregate.get error: ", error);
+      reject({
+        statusCode: 404,
+        errorMessage: error
+      })
+    })
+  });
+}
+
+/**
+* This method expects the full data set (keys and values) for the logging
+* config to replace the existing logging config
+*/
+Aggregate.set = function(req) {
+  // NOTE: Left some debugging code remarked out
+
+  //console.log("Logging Aggregate.set called");
+  //console.log("data=", req.body);
+
+  // Do nothing to test delay in response
+  var encoder = new transforms.LoggingConfigEncoder();
+  var data = encoder.encode(req.body);
+  //console.log("Aggregate.set. encoded data=");
+  //console.log(data);
+  // dumpLoggingConfig(data);
+
+  return handlePutRequest(req, APIVersion + '/api/config/logging', data);
+  // if (this.mockResponse['set']) {
+  //   return handleMockResponse(req, true, 201, data, delay=100);
+  // }
+}
+
+
+
+
+
+// Config calls
+
+/**
+ * Get all currently set logging config data
+ */
+Config.get = function(req) {
+  return handleGetRequest(req, APIVersion + '/api/config/logging?deep',
+    transformLoggingRootResponseCallback
+  );
+}
+
+/**
+ * Top level put method. Restconf cannot currently handle a global put on
+ * logging, so this method is currently for testing
+ */
+Config.set = function(req) {
+  return handlePutRequest(req, APIVersion + '/api/config/logging');
+}
+
+
+Config.setConsole = function(req) {
+  return handlePutRequest(req, APIVersion + '/api/config/logging/console');
+}
+
+Config.setFilter = function(req) {
+  return handlePutRequest(req, APIVersion + '/api/config/logging/console/filter');
+}
+
+Config.setDefaultSeverity = function(req) {
+  // TODO: verify there is one key at root of data: 'default-severity'
+  // OR just filter on the request body
+  return handlePutRequest(req, APIVersion + '/api/config/logging/');
+}
+
+Config.deleteDefaultSeverity = function(req) {
+  // TODO: verify there is one key at root of data: 'default-severity'
+  // OR just filter on the request body
+  var Categories = req.body['default-severity'];
+  return new Promise(function(resolve, reject) {
+    var promises = Categories.map(function(c) {
+      return handleDeleteRequest(req, APIVersion + '/api/config/logging/default-severity/' + c.category);
+    });
+    return Promise.all(promises).then(
+      function(data) {
+        resolve(data[0]);
+      },
+      function(data) {
+        reject(data);
+      }
+    )
+  })
+
+}
+
+/*
+  get body of forms
+
+{
+  "allowDuplicateEvents" : true
+}
+*/
+
+/**
+ * TODO: Repeat delete calls (when 'allowDuplicateEvents' value is false) cause
+ * a 404 error
+ * TODO: the call to handleDeleteRequest returns stringified data, but the PUT
+ * does not (This is the behavior we want)
+ *
+ * Improvement? Allos string representation of true/false
+ */
+Config.setAllowDuplicateEvents = function(req) {
+  // TODO: verify there is one key at root of data: 'default-severity'
+  // OR just filter on the request body
+
+  if (req.body.hasOwnProperty('allowDuplicateEvents') &&
+    typeof req.body.allowDuplicateEvents == 'boolean') {
+    if (req.body.allowDuplicateEvents) {
+      return handlePutRequest(req, APIVersion + '/api/config/logging/allow', {
+        "duplicate": "events"
+      });
+    } else { // false, remove entry from logging config
+      return handleDeleteRequest(req, APIVersion + '/api/config/logging/allow/duplicate');
+    }
+  } else {
+    return handleReject(statusCode=400,
+      data={
+        "message": 'Expected key, "allowDuplicateEvents" not found',
+        "original-request" : req.body
+      });
+  }
+}
+
+/*
+  "denyEvents": {
+    "eventIDs": [
+      1
+    ]
+  },
+*/
+
+/*
+      "deny": {
+        "event": [
+          {
+            "event-Id": 1
+          }
+        ]
+      },
+*/
+
+Config.setDenyEvents = function(req) {
+  var reqBody = {
+    deny: {
+      events: req.body.denyEvents.eventIDs.map(function(eventID) {
+        return { "event-Id": eventID };
+      })
+    }
+  };
+  return handlePutRequest(req, APIVersion + '/api/config/logging', reqBody);
+}
+
+Config.setSyslogViewer = function(req) {
+  // TODO: Verify structure of req.body
+  var reqBody = {
+    "syslog-viewer" : req.body['syslog-viewer']
+  }
+  return handlePutRequest(req, APIVersion + '/api/config/logging', reqBody);
+}
+
+
+// Operational calls
+
+Operational.get = function(req) {
+  return handleGetRequest(req, APIVersion + '/api/operational/logging?deep',
+    transformLoggingRootResponseCallback
+  );
+}
+
+
+/**
+ * Legacy call to get sys log viewer
+ */
+
+SysLogViewer.get = function(req) {
+  console.log("\n***\n SysLogViewer.get called");
+  var api_server = req.query['api_server'];
+  return new Promise(function(resolve, reject) {
+    request({
+      uri: utils.confdPort(api_server) + APIVersion + '/api/config/logging/syslog-viewer',
+      method: 'GET',
+      headers: _.extend({},
+        constants.HTTP_HEADERS.accept.data,
+        {
+          'Authorization': req.get('Authorization')
+        }),
+      forever: foreverOn,
+      rejectUnauthorized: false
+    },
+    function(error, response, body) {
+      if(error) {
+        console.log('Logging.get failed. Error:', error);
+        reject({
+          statusCode: response ? response.statusCode : 404,
+          errorMessage: 'Issue retrieving syslog-viewer url'
+        });
+      } else {
+        var data;
+        try {
+          data = JSON.parse(response.body);
+        } catch (e) {
+          console.log('Logging.get failed while parsing response.body. Error:', e);
+          reject({
+            statusCode: 500,
+            errorMessage: 'Error parsing response.body during Logging.get'
+          });
+        }
+        resolve(data);
+      }
+    });
+  });
+};
+
+/**
+ * Test methods
+ */
+Test.roundtrip = function(req) {
+  return new Promise(function(resolve, reject) {
+    Aggregate.get(req).then(function(result) {
+      var data = (new transforms.LoggingConfigEncoder()).encode(result.data);
+      resolve({
+        statusCode: 200,
+        data: {
+          'rwlog-mgmt:logging': data
+        }
+      });
+    }, function(err) {
+      console.log('Test.get error:', err);
+      reject({
+        statusCode: 500,
+        errorMessage: err
+      });
+    });
+  });
+}
+
+module.exports = {
+  aggregate: Aggregate,
+  config : Config,
+  operational: Operational,
+  sysLogViewer: SysLogViewer,
+  test: Test
+}
diff --git a/skyquake/plugins/logging/api/transforms.js b/skyquake/plugins/logging/api/transforms.js
new file mode 100644 (file)
index 0000000..eb17b7a
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var _ = require('lodash');
+
+var Support={};
+
+Support.globalDefaultSeverity = function() {
+  return 'error';
+}
+
+Support.severities = function() {
+      return [
+        null,
+        "emergency",
+        "alert",
+        "critical",
+        "error",
+        "warning",
+        "notice",
+        "info",
+        "debug"];
+}
+
+/**
+ * Class to convert RESTConf data to logging plugin
+ */
+
+
+
+LoggingConfigDecoder = function(debugMode) {
+  this.debugMode = debugMode || false
+}
+
+LoggingConfigDecoder.prototype.categories = function(data) {
+  if (data && data.categories && data.categories.category) {
+    return data.categories.category;
+  } else {
+    return [];
+  }
+}
+LoggingConfigDecoder.prototype.defaultSeverities = function (data) {
+  var globalDefaultSeverity = Support.globalDefaultSeverity();
+  if (data.categories && data.categories.category) {
+    var defaultSeverities = data["default-severity"] || [];
+    return data.categories.category.map(function(name) {
+      return  _.find(defaultSeverities, {category: name})
+       ||
+        { category: name, severity: null };
+    });
+  } else {
+    throw("Logging categories not available");
+  }
+}
+
+LoggingConfigDecoder.prototype.allowDuplicateEvents = function (data) {
+  // if the property does not exist, then value is false
+  // otherwise value is true
+  //return (data.hasOwnProperty('allow') && data.allow.duplicate == 'events');
+  return (data.allow && data.allow.duplicate == 'events');
+}
+
+// NOTE: confd can also set event ids in a range
+LoggingConfigDecoder.prototype.denyEventIDs = function(data) {
+  if (data.deny && data.deny.event) {
+    return data.deny.event.map(function(event, index) {
+      return event['event-Id'];
+    });
+  } else {
+    return [];
+  }
+}
+
+LoggingConfigDecoder.prototype.consoleData = function(data) {
+  //console.log("LoggingConfigDecoder.consoleData=", data.console);
+  // NOTE: We may need to fill in the data.console.on|off if that is not
+  // present when filters are present
+  if (data && data.console) {
+    return data.console;
+  } else {
+    return {
+      off: [ null ]
+    };
+  }
+}
+
+LoggingConfigDecoder.prototype.decode = function(loggingConfig, loggingOperational) {
+       // tack on raw retrieved config and operational data while we are in
+  // development
+
+  // TODO: robustify: check inputs if they have a 'data' property, then set
+  // local var to the data property, else just use the passed in param
+  // this means we don't have to pass 'loggingOperational.data' to the methods
+  // we call
+       if (loggingOperational.data) {
+    var results = {
+      categories: this.categories(loggingOperational.data),
+      defaultSeverities: this.defaultSeverities(loggingOperational.data),
+      severities: Support.severities(),
+      globalDefaultSeverity: Support.globalDefaultSeverity(),
+      syslogviewer: loggingOperational.data['syslog-viewer'],
+      sinks: loggingOperational.data.sink,
+      allowDuplicateEvents: this.allowDuplicateEvents(loggingOperational.data),
+      denyEventIDs: this.denyEventIDs(loggingOperational.data),
+      console: this.consoleData(loggingOperational.data)
+       }
+
+    if (this.debugMode) {
+      // carry-on original request data
+      results.loggingConfig = loggingConfig;
+      results.loggingOperational = loggingOperational;
+    }
+    return results;
+  } else {
+    return {};
+  }
+}
+
+// Logging encoding
+
+/**
+ * LoggingConfigEncoder transform the API logging configuration data to the
+ * format required to PUT to the restconf /api/config/logging endpoint
+ * The initial version is implemented in an imperative way: Explicit coding
+ * of specific fields. After this works, we can refactor to do a more
+ * declarative approach
+ */
+LoggingConfigEncoder = function() {
+
+}
+
+LoggingConfigEncoder.prototype.denyEvents = function(data) {
+
+  if (data.denyEventIDs) {
+    var events = [];
+    // TODO: sort keys and filter nulls out
+    data.denyEventIDs.forEach(function(eventID) {
+      if (eventID) {
+        events.push({ "event-Id": eventID })
+      }
+    });
+    if (events.length > 0) {
+      return { event: events };
+    } else {
+      return null;
+    }
+  } else {
+    return null;
+  }
+}
+
+/**
+ * in the Yang model, allow duplicate events flag is triggers by the presence
+ * or absence of the { "allow": { "duplicate": "events" }} key/value hierarchy
+ */
+LoggingConfigEncoder.prototype.allow = function(data) {
+  if (data.allowDuplicateEvents) {
+    return { duplicate: "events" };
+  } else {
+    return null;
+  }
+}
+LoggingConfigEncoder.prototype.consoleData = function(data) {
+  if (data.console && data.console.on) {
+    return data.console;
+  } else {
+    return null;
+  }
+}
+
+LoggingConfigEncoder.prototype.encode = function(apiData) {
+
+  var restConfData = {};
+  var n = 1;
+  // Only assign to the following keys if we have values
+  // NOTE: This may change with the implementation of the RIFT REST PUT
+  var denyData = this.denyEvents(apiData);
+  if (denyData) {
+    restConfData['deny'] = denyData;
+  }
+  console.log(n++);
+  var allowData = this.allow(apiData);
+  if (allowData) {
+    restConfData['allow'] = allowData;
+  }
+  var consoleData = this.consoleData(apiData);
+  if (consoleData) {
+    restConfData['console'] = consoleData;
+  }
+  restConfData['sink'] = apiData.sinks;
+  restConfData['syslog-viewer'] = apiData.syslogviewer;
+  restConfData['default-severity'] = apiData.defaultSeverities;
+
+  return restConfData;
+}
+
+module.exports = {
+  LoggingConfigDecoder: LoggingConfigDecoder,
+  LoggingConfigEncoder: LoggingConfigEncoder,
+  Support: Support
+}
diff --git a/skyquake/plugins/logging/config.json b/skyquake/plugins/logging/config.json
new file mode 100644 (file)
index 0000000..f68358d
--- /dev/null
@@ -0,0 +1,16 @@
+{
+    "root": "public",
+    "name": "Logging",
+    "dashboard": "./loggingGeneral.jsx",
+    "order": 101,
+    "priority":2,
+    "routes": [
+        {
+            "label": "Logging",
+            "route": "/",
+            "component": "./loggingGeneral.jsx",
+            "path": "",
+            "type": "internal"
+        }
+    ]
+}
diff --git a/skyquake/plugins/logging/package.json b/skyquake/plugins/logging/package.json
new file mode 100644 (file)
index 0000000..b6751e6
--- /dev/null
@@ -0,0 +1,54 @@
+{
+  "name": "logging",
+  "version": "1.0.0",
+  "description": "",
+  "main": "routes.js",
+  "scripts": {
+    "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "alt": "^0.18.3",
+    "bluebird": "^3.4.1",
+    "express": "^4.13.3",
+    "history": "^1.17.0",
+    "jquery": "^2.2.1",
+    "json-loader": "^0.5.4",
+    "lodash": "^4.10.0",
+    "normalizr": "^2.1.0",
+    "open-iconic": "^1.1.1",
+    "prismjs": "^1.4.1",
+    "react": "^0.14.8",
+    "react-breadcrumbs": "^1.3.9",
+    "react-crouton": "^0.2.7",
+    "react-dom": "^0.14.6",
+    "react-router": "^2.0.1",
+    "react-slick": "^0.11.1",
+    "react-tabs": "^0.5.3",
+    "react-treeview": "^0.4.2",
+    "request-promise": "^3.0.0",
+    "underscore": "^1.8.3"
+  },
+  "devDependencies": {
+    "babel-core": "^6.4.5",
+    "babel-loader": "^6.2.1",
+    "babel-polyfill": "^6.9.1",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "babel-preset-stage-0": "^6.3.13",
+    "babel-runtime": "^6.3.19",
+    "cors": "^2.7.1",
+    "css-loader": "^0.23.1",
+    "file-loader": "^0.8.5",
+    "html-webpack-plugin": "^2.9.0",
+    "http-proxy": "^1.12.0",
+    "loaders.css": "^0.1.2",
+    "node-sass": "^3.4.2",
+    "react-addons-css-transition-group": "^0.14.7",
+    "sass-loader": "^3.1.2",
+    "style-loader": "^0.13.0",
+    "webpack": "^1.3.0",
+    "webpack-dev-server": "^1.10.1"
+  }
+}
diff --git a/skyquake/plugins/logging/routes.js b/skyquake/plugins/logging/routes.js
new file mode 100644 (file)
index 0000000..af410c2
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var router = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js')
+
+var loggingAPI = require('./api/logging.js');
+
+var loggingRoutes = [
+    // Config methods
+    // config GET methods
+    {
+        method: 'GET',
+        endpoint: '/api/aggregate',
+        apiHandler: loggingAPI['aggregate'].get
+    },
+    {
+        method: 'GET',
+        endpoint: '/api/config',
+        apiHandler: loggingAPI['config'].get
+    },
+    // Config modify methods
+    {
+        method: 'PUT',
+        endpoint: '/api/config',
+        apiHandler: loggingAPI['config'].set
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/aggregate',
+        apiHandler: loggingAPI['aggregate'].set
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/console',
+        apiHandler: loggingAPI['config'].setConsole
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/filter',
+        apiHandler: loggingAPI['config'].setFilter
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/default-severity',
+        apiHandler: loggingAPI['config'].setDefaultSeverity
+    },{
+        method: 'DELETE',
+        endpoint: '/api/config/default-severity',
+        apiHandler: loggingAPI['config'].deleteDefaultSeverity
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/allow-duplicate-events',
+        apiHandler: loggingAPI['config'].setAllowDuplicateEvents
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/deny-events',
+        apiHandler: loggingAPI['config'].setAllowDuplicateEvents
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/sinks',
+        apiHandler: loggingAPI['config'].setSinks
+    },
+    {
+        method: 'PUT',
+        endpoint: '/api/config/syslog-viewer',
+        apiHandler: loggingAPI['config'].setSyslogViewer
+    },
+    // Operational methods
+    {
+        method: 'GET',
+        endpoint: '/api/operational',
+        apiHandler: loggingAPI['operational'].get
+    },
+
+    // Development/testing methods
+    {
+        method: 'GET',
+        endpoint: '/api/test/roundtrip',
+        apiHandler: loggingAPI['test'].roundtrip
+    }
+];
+
+// Logging routes. Initial refactoring pass at reducing code duplication
+loggingRoutes.forEach(function(route) {
+    registerRoute(router, route.method, route.endpoint, route.apiHandler);
+});
+
+module.exports = router;
+
+
+/**
+ * Default route callback function
+ */
+function routeCallback(apiHandler) {
+    return function(req, res) {
+        apiHandler(req).then(function(data) {
+            utils.sendSuccessResponse(data, res);
+        }, function(error) {
+            utils.sendErrorResponse(error, res);
+        });
+    };
+}
+
+
+/**
+ * register the route
+ */
+function registerRoute(app, method, endpoint, apiHandler) {
+    var methodUp = method.toUpperCase();
+    // This is the explict version that does not use reflection to cast the
+    // HTTP method to the corresponding express app function
+    if (methodUp === 'GET') {
+        app.get(endpoint, cors(), routeCallback(apiHandler));
+    } else if (methodUp === 'PUT') {
+        app.put(endpoint, cors(), routeCallback(apiHandler));
+    } else if (methodUp === 'POST') {
+        app.post(endpoint, cors(), routeCallback(apiHandler));
+    } else if (methodUp === 'DELETE') {
+        app.delete(endpoint, cors(), routeCallback(apiHandler));
+    } else {
+        console.log("ERROR: Unsupported HTTP method: %s", method);
+    }
+
+}
+
+
+
diff --git a/skyquake/plugins/logging/scripts/build.sh b/skyquake/plugins/logging/scripts/build.sh
new file mode 100755 (executable)
index 0000000..4b23c01
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+PLUGIN_NAME=logging
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
diff --git a/skyquake/plugins/logging/scripts/install.sh b/skyquake/plugins/logging/scripts/install.sh
new file mode 100755 (executable)
index 0000000..1eac1a1
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+plugin=logging
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
diff --git a/skyquake/plugins/logging/server.js b/skyquake/plugins/logging/server.js
new file mode 100644 (file)
index 0000000..03b53fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+  //Routes for local development
+  var lpRoutes = require('./routes.js');
+
+  app.use(express.static(publicPath));
+  app.use(session({
+    secret: 'ritio rocks',
+  }));
+  app.use(bodyParser.urlencoded({
+      extended: true
+  }));
+  app.use(bodyParser.json());
+  app.use(cors());
+  app.use('/', lpRoutes);
+  var bundle = require('./server/bundle.js');
+  bundle();
+
+  app.all('/build/*', function (req, res) {
+    proxy.web(req, res, {
+        target: 'http://localhost:8080'
+    });
+  });
+
+}
+proxy.on('error', function(e) {
+  console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+  console.log('Server running on port ' + port);
+});
diff --git a/skyquake/plugins/logging/src/categorySeverityGrid.jsx b/skyquake/plugins/logging/src/categorySeverityGrid.jsx
new file mode 100644 (file)
index 0000000..86a42c1
--- /dev/null
@@ -0,0 +1,68 @@
+ /*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+import {DropList, RadioButtonGroup, CardSection } from './loggingWidgets.jsx';
+import { Grid } from './gridWidgets.jsx';
+import LoggingStore from './loggingStore.js';
+
+
+export default class CategorySeverityGrid extends React.Component {
+
+  generateRows(defaultSeverities, severityOptions) {
+    let self = this;
+    return defaultSeverities.map(function(catsev) {
+      let dropList = (<DropList options={severityOptions}
+        selectedOption={catsev.severity}
+        onChange={self.onChangeSeverity(catsev.category)} />);
+      return [catsev.category, dropList];
+    });
+  }
+
+  onChangeSeverity (category) {
+    return function(e) {
+      LoggingStore.updateCategoryDefaultSeverity({
+        category: category,
+        severity: e
+      });
+    }
+  }
+
+  render() {
+    const {cellLabels, severityOptions, defaultSeverities, columnClasses,
+       ...props} = this.props;
+    let rows = null;
+    if (defaultSeverities) {
+      rows = this.generateRows(defaultSeverities, severityOptions);
+    }
+    return (<Grid className="categorySeverityGrid"
+      cellLabels={cellLabels}
+      rows={rows}
+      columnClasses={columnClasses}
+      />);
+  }
+}
+
+CategorySeverityGrid.defaultProps = {
+  cellLabels: [
+    'Category', 'Severity'
+  ],
+  columnClasses: [
+    'category', 'severity'
+  ]
+}
diff --git a/skyquake/plugins/logging/src/denyEventsEditGroup.jsx b/skyquake/plugins/logging/src/denyEventsEditGroup.jsx
new file mode 100644 (file)
index 0000000..cc28cc6
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+import LoggingStore from './loggingStore.js';
+
+class DenyEvent extends React.Component {
+
+  constructor(props) {
+    super(props);
+    this.state = {
+      eventID: props.eventID
+    };
+  }
+
+  componentWillReceiveProps(props) {
+    this.setState({
+      eventID: props.eventID
+    });
+  }
+
+  handleEventIdChange = (e) => {
+    //console.log("DenyEvent.handleEventIdChange called. value=", e.target.value);
+    // TODO: Save only if value is valid
+
+    this.setState({
+      eventID: e.target.value
+    });
+  }
+
+  isEventIdValid(eventID) {
+    // Return true if null, empty string or a number, else return false
+    if (!eventID || eventID.length == 0) {
+      return true;
+    } else {
+      return (isNaN(+eventID)) ? false : true;
+    }
+  }
+
+  render() {
+    const {className, onSave, onRemove, warnInvalidEventID, inputPattern,
+      ...props} = this.props;
+    let textBoxClassNames = "textBox";
+    if (warnInvalidEventID && !this.isEventIdValid(this.state.eventID)) {
+      //console.log("eventID is not valid: ", this.state.eventID);
+      textBoxClassNames += " invalidValue";
+    }
+    return (
+      <div className={className} >
+        <input className={textBoxClassNames} type="text"
+        value={this.state.eventID}
+        pattern={inputPattern}
+        onBlur={onSave}
+        onChange={this.handleEventIdChange.bind(this)}
+        placeholder="Event ID"
+        />
+        <div className="removeButton"
+          onClick={onRemove}>
+          <span className="oi" data-glyph="minus"
+          title="Remove event id" aria-hidden="true"></span>
+        </div>
+      </div>
+    );  
+  }
+}
+DenyEvent.defaultProps = {
+  eventID: "",
+  warnInvalidEventID: true,
+  inputPattern: "^\\d*$"
+}
+
+
+export default class DenyEventsEditGroup extends React.Component {
+
+  handleUpdateEvent = (index) => {
+    let enforceEventIdRules = this.props.enforceEventIdRules;
+    return function(e) {
+      if (e.target.value && e.target.value.trim().length > 0) {
+        if (enforceEventIdRules) {
+          console.log("attempting to set eventID[] to ", e.target.value)
+          let value = +e.target.value;
+          // long form:
+          //let value = parseInt(e.target.value, 10);
+          if (!isNaN(value)) {
+            LoggingStore.updateDenyEvent(index, value);
+          } else {
+            // Error. Show input error on screen
+          }
+        } else {
+          LoggingStore.updateDenyEvent(index, e.target.value);
+        }
+
+        
+      } else if (!e.target.value || e.target.value.trim().length == 0) {
+        LoggingStore.updateDenyEvent(index, null);
+      }
+    }
+  }
+
+  handleRemoveEvent(index) {
+    return function(e) {
+      //console.log("handleRemoveEvent called for eventID: ", eventID);
+      LoggingStore.removeDenyEvent(index);
+    }
+  }
+
+  render() {
+    let self = this;
+    const {className, eventIDs, warnInvalidEventID, ...props} = this.props;
+    let newRow = null;
+
+    return (
+      <div className={className}>
+        {
+          eventIDs.map(function(eventID, index) {
+            return (<DenyEvent className="eventEditRow"
+              key={index}
+              eventID={eventID}
+              index={index}
+              onRemove={self.handleRemoveEvent(index)}
+              onSave={self.handleUpdateEvent(index)}
+              warnInvalidEventID={warnInvalidEventID}
+              />);
+          })
+        }
+      </div>
+    );
+  }
+}
+DenyEventsEditGroup.defaultProps = {
+  eventIDs: [],
+  enforceEventIdRules: false,
+  warnInvalidEventID: false
+}
diff --git a/skyquake/plugins/logging/src/gridWidgets.jsx b/skyquake/plugins/logging/src/gridWidgets.jsx
new file mode 100644 (file)
index 0000000..74ee42f
--- /dev/null
@@ -0,0 +1,142 @@
+ /*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+/*
+ Simple helper to avoid 'undefined' in class name rendered in the html
+
+ * First incarnation expects additionalClassNames to be a string
+ * Later, we'll improve to take a string or array
+
+ * And move this into a different file/module, uiHelers.js maybe for now
+*/
+function buildClassName(baseClassName, additionalClassNames) {
+  if (additionalClassNames) {
+    return baseClassName + " " + additionalClassNames;
+  } else {
+   return baseClassName;
+  }
+}
+
+class GridCell extends React.Component {
+  render() {
+    const {baseClassName, className, children, ...props} = this.props;
+    return (
+      <div className={buildClassName(baseClassName, className)}>
+      {children}
+      </div>
+    );
+  }
+}
+GridCell.defaultProps = {
+  baseClassName: "gridCell"
+}
+
+class GridRow extends React.Component {
+
+  columnClass(columnClasses, index) {
+    // starting point for sanity check
+    if (columnClasses && index >= 0 && index < columnClasses.length) {
+      return columnClasses[index];
+    } else {
+      return null;
+    }
+  }
+  render() {
+    let self = this;
+    const {className, cells, columnClasses, ...props} = this.props;
+    return (
+      <div className={className} >
+        {
+          cells.map( (cell, index) =>
+            <GridCell key={index}
+              className={self.columnClass(columnClasses, index)}>{cell}</GridCell>)
+        }
+      </div>
+    );
+  }
+}
+
+/**
+* Maybe we can do without GridHead as it is a specialized version of GridRow
+*/
+class GridHead extends React.Component {
+  render() {
+    const {className, cellLabels, columnClasses, ...props} = this.props;
+    return (
+      <GridRow className={className} cells={cellLabels} 
+      columnClasses={columnClasses} />
+    );
+  }
+}
+
+
+class GridBody extends React.Component {
+  render() {
+    let self = this;
+    const {className, rows, columnClasses, ...props} = this.props;
+    return (
+      <div className={className}>
+          {
+            rows.map( (row, index) =>
+              <GridRow key={index} className="gridRow"
+                cells={row} columnClasses={columnClasses} />
+            )
+          }
+        </div>
+    );
+  }
+}
+
+/**
+ *
+ * TODO: Consider merging cellLabels and columnClasses into array of single structure
+ */
+class Grid extends React.Component {
+
+  renderHasNoRows() {
+    return (<div className="noRows">No Data</div>);
+  }
+  render() {
+    const {baseClassName, className, cellLabels, rows, columnClasses,
+      ...props} = this.props;
+
+    return (
+      <div className={buildClassName(baseClassName, className)}>
+        <GridHead className="gridHead"
+          cellLabels={cellLabels} columnClasses={columnClasses} />
+        {
+          (rows) ? <GridBody className="gridBody" rows={rows}
+            columnClasses={columnClasses} />
+            : this.renderHasNoRows()
+        }
+      </div>
+    );
+  }
+}
+Grid.defaultProps = {
+  baseClassName: "grid"
+}
+
+module.exports = {
+  Grid: Grid,
+  GridBody: GridBody,
+  GridCell: GridCell,
+  GridHead: GridHead,
+  GridRow: GridRow
+}
diff --git a/skyquake/plugins/logging/src/logging.jsx b/skyquake/plugins/logging/src/logging.jsx
new file mode 100644 (file)
index 0000000..70efac3
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+ import React from 'react';
+ import './logging.scss';
+ import AppHeader from 'widgets/header/header.jsx';
+ import LoggingActions from './loggingActions.js';
+ import LoggingStore from './loggingStore.js';
+
+ export default class Logging extends React.Component {
+       constructor(props) {
+               super(props);
+               console.log("Logging.constructor called");
+               
+
+               this.state = LoggingStore.getState();
+               console.log("Logging.constructor: state=", this.state);
+               LoggingStore.listen(this.storeListener);
+               // LoggingStore.get();
+       }
+
+       storeListener = (state) => {
+               console.log("Logging.storeListener called");
+               this.setState(state);
+       }
+
+       //handleUpdate(data)
+       // Lifecycle methods
+       // https://facebook.github.io/react/docs/component-specs.html
+
+       componentWillMount() {
+               console.log("Logging.componentWillMount called");
+       }
+       componentDidMount() {
+               console.log("Logging.componentDidMount called");
+               //LoggingStore.getSysLogViewerURL();
+               LoggingStore.getLoggingConfig();
+               //LoggingStore.getLoggingOperational();
+       }
+
+       // Invoked when a component is receiving new props. This method is not called for the intial render.
+       // use this as an opportunity to react to a prop transition before render() is called
+       componentWillReceiveProps(nextProps) {
+               console.log("Logging.componentWillReceiveProps called");
+               // this.setState({ key: nextProps.value});
+       }
+
+       // shouldComonentUpdate(nextProps, nextState) {}
+       // Invoked immediately before rendering when new props or state are being received
+       // componentWillUpdate(nextProps, nextState) {}
+
+
+       // Invoked immediately after the component's updates are flushed to the DOM.
+       // This method is not called for the initial render.
+       // Use this as an opportunity to operate on the DOM when the component has been updated.
+       componentDidUpdate(prevPros, prevState) {
+
+       }
+       componentWillUnmount() {
+               console.log("Logging.componentWillUnmount called");
+               //LoggingStore.unlisten(this.storeListener);
+       }
+       render() {
+               console.log("Logging.render called");
+               console.log("Logging.state=", JSON.stringify(this.state));
+               var html=(<div><h1>Hello Logging page</h1></div>);
+               if (this.state != null) {
+                       html = (
+                               <div>
+                                       <p>Placeholder for logging page</p>
+                                       <p>alpha</p>
+                               </div>
+                       );
+               }
+               return (
+                       <div className="logging-container">
+                               {html}
+                       </div>
+               );
+       }
+
+ }
\ No newline at end of file
diff --git a/skyquake/plugins/logging/src/logging.scss b/skyquake/plugins/logging/src/logging.scss
new file mode 100644 (file)
index 0000000..559b217
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+@import "style/_colors.scss";
+@import "style/layout.scss";
+@import '../node_modules/open-iconic/font/css/open-iconic.css';
+
+/*
+.dashboardCard {
+  height: auto;
+}*/
+
+// Defaults for grid elements. TBD where we place this on completion of task
+
+.grid.categorySeverityGrid {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+
+  .gridCell {
+    display: flex;
+    flex: 1 0 auto;
+    // top right bottom left
+    padding: 0.1rem 0 0.1rem 0.5rem;
+  }
+  .gridRow {
+    display: flex;
+    flex: 0 0 auto;
+    flex-direction: row;
+    padding-top: 1px;
+  }
+  .gridHead {
+    display: flex;
+    flex: 0 0 auto;
+    flex-direction: row;
+    background-color: $gray;
+    text-transform: uppercase;
+    .gridCell {
+      border: 1px solid black;
+      //flex: 1 0 auto;
+    }
+  }
+  .gridBody {
+    display: flex;
+    flex-direction: column;
+    overflow-y: scroll;
+  }
+  .gridBody .gridRow:nth-child(odd) {
+    background-color: $gray-lighter;
+  }
+  .gridBody .gridRow:nth-child(even) {
+    background-color: $gray-lightest;
+  }
+  .noRows {
+    text-align: center;
+    font-style: italic;
+    font-size: large;
+    padding-top: 1rem;
+  }
+  .gridCell.category {
+    width: 150px;
+  }
+  .gridCell.severity {
+    width: 100px;
+  }
+} // .gird.categorySeverityGrid
+
+.cardSection {
+  //margin: 0 0.5rem 0.5rem;  
+}
+.cardSectionHeader {
+  text-decoration-line: underline;
+  text-transform: uppercase;
+  border-bottom: 1px solid black;
+  margin-top: 0.5rem;
+  margin-bottom: 0.5rem;
+  
+}
+
+.textBox {
+  margin-right: 0.5rem;
+  // https://css-tricks.com/almanac/selectors/p/placeholder/
+  font-size: medium;
+  flex: 1;
+  &::-webkit-input-placeholder {
+    font-style: italic;
+  }
+}
+
+// .app-body should be promoted to a higher level
+.app-body {
+  display: flex;
+  flex-direction: column;
+  align-items: stretch;
+  height: 100%;
+}
+
+.loggingPage {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  height: auto;
+  &.loggingGeneral {
+    
+  }
+}
+.panelContainer {
+  display: flex;
+  flex: 1;
+  flex-direction: row;
+
+}
+
+.loggingPanel {
+  display: flex;
+  flex: 1 100%;
+  height: auto !important;
+  header {
+    background-color: white;
+    display: block;
+  }
+}
+
+.defaultCategorySeverityPanel {
+  @extend .loggingPanel;
+  min-width: 20rem;
+  max-width: 20rem;
+}
+
+.loggingEventsPanel {
+  @extend .loggingPanel;
+  .textBox {
+    &.invalidValue {
+      border: 1px solid red;
+    }
+  }
+  &-body {
+    display: flex;
+    flex: 1;
+    flex-direction: column;
+    overflow-y: scroll;
+    padding: 0.5rem;
+  }
+  .radioButtonGroupHeader {
+    text-transform: uppercase;
+  }
+  .radioButtonGroup {
+    display: flex;
+    flex-direction: row;
+    .radioItem {
+      margin-left: 1rem;
+      margin-top: 0.2rem;
+
+    }
+  }
+}
+
+.loggingGeneralDetailsPanel {
+  @extend .loggingPanel;
+  .syslogViewer {
+    display: flex;
+    flex: 0;
+    flex-direction: column;
+  }
+  &-body {
+    // top right bottom left
+    //padding: 0.5rem 0.5rem 0.5rem 0.5rem;
+    padding: 0.5rem;
+  }
+  .section.syslogViewerSection {
+    .sectionLabel {
+
+    }
+    .syslogViewerControls {
+      display: flex;
+      flex: 1;
+      flex-direction: row;
+      margin-top: 0.25rem;
+    } 
+  }
+  .goButton {
+    cursor: pointer;
+    border: 1px solid $gray-dark;
+    background-color: $gray-dark;
+    margin: 2px;
+    border-radius: 3px;
+    span {
+      padding-left: 3px;
+      padding-right: 3px;
+    }
+  }
+}
+
+.loggingPageFooter {
+  display: flex;
+}
+
+.loggingFormButtonGroup {
+  justify-content: center;
+  align-items: center;
+  display:flex;
+  flex: 1;
+  padding: 1rem;
+}  
+
+.denyEventsEditGroup {
+  display: flex;
+  flex-direction: column;
+
+  .eventEditRow {
+    display: flex;
+    flex: 1 1 auto;
+    flex-direction: row;
+    margin-top: 0.2rem;
+    margin-bottom: 0.2rem;
+  }
+  .removeButton {
+    flex: 0;
+    cursor: pointer;
+    border: 1px solid black;
+    border-radius: 5px;
+    background-color: black;
+    margin-top: 0.2rem;
+    margin-bottom: 0.2rem;
+    padding-left: 2px;
+    padding-right: 2px;
+    color: white;
+    span {
+      //margin-top: 2px;
+      vertical-align: middle;
+    }
+  }
+}
+
+.plusButton {
+  flex: 0;
+  cursor: pointer;
+  //padding: 2px;
+  margin-top: 0.5rem;
+  color: white;
+  span {
+    border: 1px solid black;
+    background-color: black;
+    border-radius: 4px;
+    padding-top: 2px;
+    padding-left: 2px;
+    padding-right: 2px;
+  }
+}
+
diff --git a/skyquake/plugins/logging/src/loggingActions.js b/skyquake/plugins/logging/src/loggingActions.js
new file mode 100644 (file)
index 0000000..ddddfb1
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import alt from 'widgets/skyquake_container/skyquakeAltInstance';
+
+module.exports = alt.generateActions(
+       'getLoggingConfigSuccess',
+       'getLoggingConfigError',
+    'putLoggingConfigSuccess',
+    'putLoggingConfigError',
+    'resetLoggingConfigData'
+);
diff --git a/skyquake/plugins/logging/src/loggingGeneral.jsx b/skyquake/plugins/logging/src/loggingGeneral.jsx
new file mode 100644 (file)
index 0000000..dd04a57
--- /dev/null
@@ -0,0 +1,397 @@
+ /*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import _ from 'lodash';
+import './logging.scss';
+
+import Button from 'widgets/button/rw.button.js';
+import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
+import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
+
+import LoggingActions from './loggingActions.js';
+import LoggingStore from './loggingStore.js';
+import LoggingNav from './loggingNav.jsx';
+
+import CategorySeverityGrid from './categorySeverityGrid.jsx';
+import DenyEventsEditGroup from './denyEventsEditGroup.jsx';
+import {DropList, RadioButtonGroup, CardSection } from './loggingWidgets.jsx';
+
+import Crouton from 'react-crouton';
+import 'style/common.scss';
+
+
+class DefaultCategorySeverityPanel extends React.Component {
+
+  render() {
+    const {defaultSeverities, severities, ...props } = this.props;
+    return (
+      <DashboardCard className="defaultCategorySeverityPanel"
+        showHeader={true}
+        title="Default Category Severity">
+        <CategorySeverityGrid defaultSeverities={defaultSeverities}
+          severityOptions={severities}/>
+      </DashboardCard>
+    );
+  }
+}
+
+
+class LoggingEventsPanel extends React.Component {
+
+  handleChangeAllowDuplicateEvents(e) {
+    console.log("LoggingEventsPanel.handleChangeAllowDuplicateEvents:");
+    console.log("- e.currentTarget.value=", e.currentTarget.value);
+    console.log("- e.currentTarget=", e.currentTarget);
+
+    // NOTE, we may want to generalize our string to boolean convert/compare
+    let allowFlag = (e.currentTarget.value == 'true');
+    LoggingStore.updateAllowDuplicateEvents(allowFlag);
+  }
+
+  handleAddDenyEvent(e) {
+    LoggingStore.addDenyEvent(null);
+  }
+
+  render() {
+    const {allowDuplicateEvents, eventIDs, radioItems, ...props} = this.props;
+    let self = this;
+    let selectedIndex = allowDuplicateEvents ? 0 :1;
+
+    return (
+      <DashboardCard className="loggingEventsPanel"
+        showHeader={true}
+        title="Events">
+        <CardSection title={"Duplicates"}>
+          <div className="radioButtonGroupHeader">Allow duplicate events</div>
+          <RadioButtonGroup className="radioButtonGroup"
+            items={radioItems}
+            selectedItem={radioItems[selectedIndex]}
+            onChange={this.handleChangeAllowDuplicateEvents}
+            radioGroupName="allowDuplicateEvents"
+          />
+        </CardSection>
+        <CardSection title={"Deny"}>
+          <DenyEventsEditGroup className="denyEventsEditGroup"
+            eventIDs={eventIDs}
+            warnInvalidEventID={true}
+          />
+          <div className="plusButton" onClick={this.handleAddDenyEvent}>
+            <span className="oi" data-glyph="plus"
+                  title="Add event id" aria-hidden="true"></span>
+          </div>
+        </CardSection>
+      </DashboardCard>
+    );
+  }
+}
+LoggingEventsPanel.defaultProps = {
+  radioItems: [
+    { label: "Allow", value: true },
+    { label: "Deny", value: false }
+  ],
+  allowDuplicateEvents: false,
+  eventIDs: []
+}
+
+/**
+ *
+ */
+class LoggingGeneralDetailsPanel extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      syslogViewerURL: props.syslogViewerURL
+    };
+  }
+
+  componentWillReceiveProps(props) {
+    this.setState({
+      syslogViewerURL: props.syslogViewerURL
+    });
+  }
+
+  handleUpdateDetailTextField(fieldName) {
+    let self = this;
+    return function(e) {
+      let state = {};
+      state[fieldName] = e.target.value;
+      self.setState(state);
+    }
+  }
+
+  handleUpdateSyslogViewerURL(e) {
+    LoggingStore.updateSyslogViewerURL(e.target.value);
+  }
+  handleOpenSysLogViewerURL(e) {
+    e.preventDefault();
+    window.open(this.state.syslogViewerURL);
+  }
+
+  render() {
+    return (
+      <DashboardCard className="loggingGeneralDetailsPanel"
+        showHeader={true}
+        title="SysLog Viewer">
+        <div className="section syslogViewerSection">
+          <label className="sectionLabel">Syslog Viewer URL</label>
+          <div className="syslogViewerControls">
+            <input className="textBox" type="text"
+              value={this.state.syslogViewerURL}
+              onBlur={this.handleUpdateSyslogViewerURL}
+              onChange={this.handleUpdateDetailTextField('syslogViewerURL')}
+              placeholder="syslogViewer URL"
+            />
+            <div className="goButton"
+              onClick={this.handleOpenSysLogViewerURL.bind(this)}>
+              <span>Go</span>
+              <span className="oi" data-glyph="arrow-right"
+                    title="Add event id" aria-hidden="true"></span>
+            </div>
+          </div>
+        </div>
+      </DashboardCard>
+    );
+  }
+}
+LoggingGeneralDetailsPanel.defaultProps = {
+  syslogViewerURL: ""
+}
+
+
+
+/**
+ *  Page level class renders the general logging config page of three panels:
+ * 1. Default severity per category
+ * 2. Events configuration
+ * 3. Syslog viewer setting, launch
+ */
+export default class LoggingGeneral extends React.Component {
+
+  constructor(props) {
+    super(props);
+    this.state = LoggingStore.getState();
+    LoggingStore.listen(this.storeListener);
+    this.state.validateErrorEvent = 0;
+    this.state.validateErrorMsg = '';
+    this.state.isLoading = true;
+    this.state.showDumpStateButton = false;
+  }
+
+  storeListener = (state) => {
+    this.setState(state);
+  }
+
+  getData() {
+    LoggingStore.getLoggingConfig();
+    this.setState({
+      isLoading: _.isEmpty(this.state.loggingConfig)
+    });
+  }
+  componentWillUnmount = () => {
+    LoggingStore.unlisten(this.storeListener);
+  }
+
+  componentDidMount() {
+    //console.log("LoggingGeneral.componentDidMount called");
+    this.getData();
+  }
+
+  componentDidUpdate() {
+    //console.log("LoggingGeneral.componentDidUpdate called");
+  }
+
+  handleSave = (formData, e) => {
+    e.preventDefault();
+
+    if (this.validateData()) {
+      this.setState({
+        isLoading: true
+      });
+      LoggingStore.updateLoggingConfig(
+         this.collectNulledCategories(
+            this.state.initialLoggingConfig,
+            this.state.loggingConfig),
+         this.removeCategoryNulls(
+            this.state.loggingConfig
+          )
+     );
+    } else {
+      console.log("LoggingGeneral.handleSave failed validation");
+    }
+    this.context.router.push({pathname: ''});
+  }
+  removeCategoryNulls(config) {
+    let cleanConfig = _.cloneDeep(config);
+    let cleanSeverities = [];
+    config.defaultSeverities.map(function(d) {
+      if (d.severity) {
+        cleanSeverities.push(d);
+      }
+    });
+    cleanConfig.defaultSeverities = cleanSeverities;
+    return cleanConfig;
+  }
+  collectNulledCategories(oldCat, newCat) {
+    let nulledCategories = [];
+    let newSeverities = newCat.defaultSeverities;
+    let oldSeverities = oldCat.defaultSeverities;
+    newSeverities.map(function(c, i) {
+      if(!c.severity) {
+        if(oldSeverities[i].severity) {
+          //verify that categories are the same
+          if(oldSeverities[i].category == c.category) {
+            nulledCategories.push({category: c.category})
+          }
+        }
+      }
+    });
+    return nulledCategories;
+  }
+  validateData() {
+
+    function isEventIdValid(eventID) {
+      // Return true if null, empty string or a number, else return false
+      if (!eventID || eventID.length == 0) {
+        return true;
+      } else {
+        return (isNaN(+eventID)) ? false : true;
+      }
+    }
+
+    let invalidEventIDs = [];
+    this.state.loggingConfig.denyEventIDs.forEach(
+      function(eventID, index) {
+        if (!isEventIdValid(eventID)) {
+          invalidEventIDs.push({ eventID: eventID, index: index});
+        }
+      })
+    if (invalidEventIDs.length > 0) {
+      console.log("invalidEvents = ", invalidEventIDs);
+      if (invalidEventIDs.length == 1) {
+        let msg = 'There is ' + invalidEventIDs.length + ' invalid event ID';
+        this.validateError(msg);
+      } else {
+        let msg = 'There are ' + invalidEventIDs.length + ' invalid event IDs';
+        this.validateError(msg);
+      }
+      // How should we identify each invalid value?
+
+      return false;
+    } else {
+      return true;
+    }
+  }
+  handleCancel = (e) => {
+    console.log("LoggingGeneral.handleCancel clicked");
+    e.preventDefault();
+    // TODO: restore original state
+    LoggingStore.resetLoggingConfigData();
+    this.context.router.push({pathname: ''});
+
+  }
+
+  validateError = (msg) => {
+    this.setState({
+      validateErrorEvent: true,
+      validateErrorMsg: msg
+    });
+  }
+  validateReset = () => {
+    this.setState({
+      validateErrorEvent: false
+    });
+  }
+  returnCrouton = () => {
+    return <Crouton id={Date.now()}
+      message={this.state.validateErrorMsg}
+      type={'error'}
+      hidden={!(this.state.validateErrorEvent && this.state.validateErrorMsg)}
+      onDismiss={this.validateReset}
+    />;
+  }
+  preventDefault = (e) => {
+    e.preventDefault();
+    e.stopPropagation();
+  }
+
+  renderDumpStateButton() {
+
+  }
+
+  render() {
+    var self = this;
+
+
+    let errorMessage = this.returnCrouton();
+
+    let syslogViewerURL = this.state.loggingConfig.syslogviewer;
+    let defaultSeverities = this.state.loggingConfig.defaultSeverities;
+    let severities = this.state.loggingConfig.severities;
+    let allowDuplicateEvents = this.state.loggingConfig.allowDuplicateEvents;
+    let denyEventIDs = this.state.loggingConfig.denyEventIDs;
+
+    let dumpStateButton = (
+        <button name="dump_state"
+            onClick={this.handleDumpState}>Dump State</button>);
+
+
+    return (
+      <div className="app-body">
+        {
+          (this.state.showLoggingNav) ? <LoggingNav currentPage="General" /> : ''
+        }
+
+        <form className="loggingPage loggingGeneral"
+          onSubmit={this.preventDefault}>
+          {errorMessage}
+          <ScreenLoader show={this.state.isLoading}/>
+          <div className="panelContainer">
+            <DefaultCategorySeverityPanel defaultSeverities={defaultSeverities}
+              severities={severities}
+              />
+            <LoggingEventsPanel allowDuplicateEvents={allowDuplicateEvents}
+              eventIDs={denyEventIDs} />
+            <LoggingGeneralDetailsPanel syslogViewerURL={syslogViewerURL} />
+          </div>
+          <div className="loggingPageFooter">
+            <div className="loggingformButtonGroup">
+              {
+                (this.state.showDumpStateButton) ? dumpStateButton : ''
+              }
+              <Button className="cancel light" label="Reset"
+                onClick={this.handleCancel} />
+              <Button className="save dark" role="button" label="Save"
+                onClick={this.handleSave.bind(this, true)} />
+            </div>
+          </div>
+        </form>
+      </div>
+    );
+  }
+
+  // Dev and debug support
+  handleDumpState = (e) => {
+    console.log("State dump:");
+    console.log("event ids=", this.state.loggingConfig.denyEventIDs);
+    console.log("initial state=", this.state.initialLoggingConfig);
+    console.log("active state=", this.state.loggingConfig);
+  }
+}
+LoggingGeneral.contextTypes = {
+  router: React.PropTypes.object
+}
diff --git a/skyquake/plugins/logging/src/loggingNav.jsx b/skyquake/plugins/logging/src/loggingNav.jsx
new file mode 100644 (file)
index 0000000..aed8be8
--- /dev/null
@@ -0,0 +1,62 @@
+ /*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+
+import AppHeader from 'widgets/header/header.jsx';
+//import AppHeaderActions from 'widgets/header/headerActions.js';
+
+
+export default class LoggingNav extends React.Component {
+
+  navItems(currentPage) {
+    let navItems = [{
+        name: 'General',
+        onClick: this.context.router.push.bind(this, { pathname: '/'})
+      },{
+        name: 'Console',
+        onClick: this.context.router.push.bind(this, {
+          pathname: '/logging-console'})
+      },{
+        name: 'Sinks',
+        onClick: this.context.router.push.bind(this, {
+          pathname: '/logging-sinks'})
+      }
+    ];
+
+    if (currentPage) {
+      return navItems.map(function(navItem) {
+        if (navItem.name == currentPage) {
+          return { name: currentPage };
+        } else {
+          return navItem;
+        }
+      });
+    } else {
+      // return all
+      return navItems;
+    }
+  }
+
+  render() {
+    const {currentPage, ...props} = this.props;
+    return (<AppHeader nav={this.navItems(currentPage)} />);
+  }
+}
+LoggingNav.contextTypes = {
+  router: React.PropTypes.object
+}
\ No newline at end of file
diff --git a/skyquake/plugins/logging/src/loggingSource.js b/skyquake/plugins/logging/src/loggingSource.js
new file mode 100644 (file)
index 0000000..e073809
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+let rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var loggingActions = require('./loggingActions.js');
+var Utils = require('utils/utils.js');
+import $ from 'jquery';
+
+function apiUrl(endpoint) {
+  return endpoint.replace(/\/$/,'') + '?api_server=' + API_SERVER;
+}
+
+export default {
+  /**
+   * Retrieve the logging configuration data from the Node API server
+   */
+  getLoggingConfig: function() {
+    //console.log("LoggingSource.getLoggingConfig called");
+    return {
+      remote: function(state) {
+        return new Promise(function(resolve, reject) {
+          //console.log("loggingSource.getLoggingConfig called");
+          $.ajax({
+            url: apiUrl('api/aggregate'),
+            type: 'GET',
+            beforeSend: Utils.addAuthorizationStub,
+            success: function(data) {
+              //console.log("LoggingSource.getLoggingConfig success call. data=", data);
+              resolve(data);
+            },
+            error: function(e) {
+              console.log("Error getting logging config details");
+            }
+          });
+        });
+      },
+      success: loggingActions.getLoggingConfigSuccess,
+      error: loggingActions.getLoggingConfigError
+    }
+  },
+  /**
+  * Update the logging configuration data on the server
+  * @param {object} state -  Reference to parent store state
+  * @param {object} loggingConfig - logging configuration data
+  * @return {[type]}  [description]
+  }
+  */
+  updateLoggingConfig: function () {
+    return {
+      remote: function(state, nulledCategories, loggingConfig) {
+        return new Promise(function(resolve, reject) {
+          let promises = [];
+          let remove = null;
+          let change = $.ajax({
+                url: apiUrl('api/aggregate'),
+                type: 'PUT',
+                beforeSend: Utils.addAuthorizationStub,
+                data: loggingConfig,
+                success: function(data) {
+                  resolve(data);
+                },
+                error: function(error) {
+                  console.log("There was an error updating the logging config data",
+                    error);
+                  reject(error);
+                }
+          });
+          promises.push(change);
+          if(nulledCategories.length > 0) {
+            remove = $.ajax({
+              url: apiUrl('api/config/default-severity'),
+              type: 'DELETE',
+              beforeSend: Utils.addAuthorizationStub,
+              data: {
+                'default-severity' : nulledCategories
+              },
+              success: function(data) {
+                resolve(data);
+              },
+              error: function(error) {
+                console.log("There was an error updating the logging config data",
+                  error);
+                reject(error);
+              }
+            });
+            promises.push(remove);
+          }
+
+
+          Promise.all(promises).then(function(data){
+            resolve(data)
+          }, function(){
+            reject(arguments)
+          })
+
+        });
+
+      },
+      success: loggingActions.putLoggingConfigSuccess,
+      error: loggingActions.putLoggingConfigError
+    }
+  }
+}
diff --git a/skyquake/plugins/logging/src/loggingStore.js b/skyquake/plugins/logging/src/loggingStore.js
new file mode 100644 (file)
index 0000000..860ff9f
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import _ from 'lodash';
+import LoggingActions from './loggingActions.js';
+import LoggingSource from './loggingSource.js';
+
+import alt from 'widgets/skyquake_container/skyquakeAltInstance';
+
+class LoggingStore {
+  constructor() {
+    this.loggingConfig = {};
+    // initialLoggingConfig is the saved state
+    this.initialLoggingConfig = {};
+    this.bindActions(LoggingActions);
+    this.registerAsync(LoggingSource);
+    this.exportPublicMethods({
+      updateCategoryDefaultSeverity: this.updateCategoryDefaultSeverity,
+      updateAllowDuplicateEvents: this.updateAllowDuplicateEvents,
+      addDenyEvent: this.addDenyEvent,
+      updateDenyEvent: this.updateDenyEvent,
+      removeDenyEvent: this.removeDenyEvent,
+      updateSyslogViewerURL: this.updateSyslogViewerURL,
+      resetLoggingConfigData: this.resetLoggingConfigData
+    });
+  }
+
+  getLoggingConfigSuccess = (data) => {
+      console.log("LoggingStore.getLoggingConfigSuccess called. data=", data);
+      // Do we need to do a deep clone?
+      const initialLoggingConfig = _.cloneDeep(data);
+      console.log("initialLoggingConfig=", initialLoggingConfig);
+      this.setState({
+      loggingConfig: data,
+      initialLoggingConfig: initialLoggingConfig,
+      isLoading: false
+    });
+  }
+
+  getLoggingConfigError(data) {
+    console.log("LoggongStore.getLoggingConfigError called. data=", data);
+  }
+
+  putLoggingConfigSuccess = (data) => {
+    console.log("LoggingStore.putLoggingConfigSuccess called. data=", data);
+    const initialLoggingConfig = _.cloneDeep(this.loggingConfig);
+    this.setState({
+      isLoading: false,
+      initialLoggingConfig: initialLoggingConfig
+    });
+  }
+
+  putLoggingConfigError(data) {
+    console.log("LoggingStore.putLoggingConfigError called. data=", data);
+  }
+
+  resetLoggingConfigData = (data) => {
+    console.log('LoggingStore.resetLoggingConfigData called. data=', data);
+    // Do we need to do a deep clone?
+    const loggingConfig = _.cloneDeep(this.initialLoggingConfig);
+    this.setState({
+      loggingConfig: loggingConfig
+    });
+  }
+
+  updateCategoryDefaultSeverity = (catsev) => {
+    console.log("LoggingStore.updateCategoryDefaultSeverity:", catsev);
+    // find the category
+
+    let catIndex = _.findIndex(this.loggingConfig.defaultSeverities, function(o) {
+      return o.category == catsev.category;
+    });
+    console.log("catIndex=", catIndex);
+    if (catIndex != -1) {
+      const loggingConfig = this.loggingConfig;
+      loggingConfig.defaultSeverities[catIndex].severity = catsev.severity;
+
+      this.setState({
+        loggingConfig: loggingConfig
+      });
+    }  else {
+      console.log("ERROR: catIndex not founds for default category", catsev.category);
+    }
+  }
+
+  updateAllowDuplicateEvents = (allowFlag) => {
+    console.log("LoggingStore.updateAllowDuplicateEvents called. allowFlag=", allowFlag);
+    const loggingConfig = this.loggingConfig;
+    loggingConfig.allowDuplicateEvents = allowFlag;
+    this.setState({
+      loggingConfig: loggingConfig
+    });
+  }
+
+  /**
+   * Add a new empty (null) deny event to loggingConfig
+   */
+  addDenyEvent = (event) => {
+    const loggingConfig = this.loggingConfig;
+    loggingConfig.denyEventIDs.push(null);
+    this.setState({
+      loggingConfig: loggingConfig
+    });
+  }
+
+  /**
+   * Update
+   */
+  updateDenyEvent = (index, eventID) => {
+    //console.log("LoggingStore.updateDenyEventID: index=", index);
+    //console.log(" -> eventID=", eventID);
+
+    const loggingConfig = this.loggingConfig;
+    loggingConfig.denyEventIDs[index] = eventID;
+    this.setState({
+      loggingConfig: loggingConfig
+    });
+  }
+
+  /**
+   *
+   */
+  removeDenyEvent = (index) => {
+    // console.log("LoggingStore.removeDenyEvent at index %s", index);
+    const loggingConfig = this.loggingConfig;
+    // Note: we are not validating index
+    loggingConfig.denyEventIDs.splice(index, 1);
+    this.setState({
+      loggingConfig: loggingConfig
+    });
+  }
+
+  /**
+   *
+   */
+  updateSyslogViewerURL = (syslogViewerURL) => {
+    const loggingConfig = this.loggingConfig;
+    loggingConfig.syslogviewer = syslogViewerURL;
+    this.setState({
+      loggingConfig: loggingConfig
+    });
+  }
+}
+
+export default alt.createStore(LoggingStore);
diff --git a/skyquake/plugins/logging/src/loggingWidgets.jsx b/skyquake/plugins/logging/src/loggingWidgets.jsx
new file mode 100644 (file)
index 0000000..173554c
--- /dev/null
@@ -0,0 +1,105 @@
+ /*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+ import React from 'react';
+
+ // import sass
+
+
+ // --- ---
+// Generalized component classes
+// --- ---
+
+class DropList extends React.Component {
+
+  handleOnChange = (e) => {
+    this.props.onChange(e.target.value);
+  }
+
+  render() {
+    const {className, selectedOption, options, ...props} = this.props;
+    return (
+      <select className={className} onChange={this.handleOnChange}
+       value={selectedOption}>
+        {
+          options.map(function(op, i) {
+            return (
+             <option key={i} value={op}>{op}</option>
+            );
+          })
+        }
+      </select>
+    );
+  }
+}
+DropList.defaultProps = {
+  options: [],
+  onChange: function(e) {
+    console.log("DropList defaultProps onChange called, e=", e);
+  }
+}
+
+class RadioButtonGroup extends React.Component {
+
+  /**
+   * 
+   * TODO: Enable option to swap order of radio button and label
+   */
+  render() {
+    const {className, items, selectedItem, radioGroupName, onChange, ...props} = this.props;
+    return (
+      <div className={className}>
+        {
+          items.map(function(item, index) {
+            return (
+              <div key={index} className="radioItem">
+                <input type="radio" name={radioGroupName}
+                  value={item.value}
+                  checked={selectedItem.value == item.value}
+                  onChange={onChange} />
+                <label>{item.label}</label>
+              </div>
+            );
+          })
+        }
+      </div>
+    );
+  }
+}
+
+/**
+ *
+ */
+// TODO: support externally defined className(s)
+class CardSection extends React.Component {
+
+  render() {
+    const {title, children, ...props} = this.props;
+    return (
+      <div className="cardSection">
+        <div className="cardSectionHeader">{title}</div>
+        {children}
+      </div>
+    );
+  }
+}
+
+module.exports = {
+  DropList: DropList,
+  RadioButtonGroup: RadioButtonGroup,
+  CardSection: CardSection
+}
diff --git a/skyquake/plugins/logging/src/main.js b/skyquake/plugins/logging/src/main.js
new file mode 100644 (file)
index 0000000..ddd7f4b
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
diff --git a/skyquake/plugins/logging/src/syslogViewer.jsx b/skyquake/plugins/logging/src/syslogViewer.jsx
new file mode 100644 (file)
index 0000000..d3b31f6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import './logging.scss';
+import AppHeader from 'widgets/header/header.jsx';
+import LoggingActions from './loggingActions.js';
+import LoggingStore from './loggingStore.js';
+
+
+export default class SyslogViewer extends React.Component {
+       constructor(props) {
+               super(props);
+               /*
+               console.log("SyslogViewer.constructor called");
+               LoggingStore.listen(this.storeListener);
+               this.state = LoggingStore.getState();
+               console.log("SyslogViewer state=", this.state);
+               */
+       }
+       storeListener = (state) => {
+               console.log("SyslogViewer.storeListener called. state=", state);
+               //this.setState(state);
+       }
+       componentDidMount() {
+               console.log("SyslogViewer.componentDidMount called");
+               //LoggingStore.getLogConfig();
+       }
+       render() {
+               console.log("SyslogViewer.render called. state=", this.state);
+               //console.log("logConfig JSON=", JSON.stringify(this.state.logConfig));
+               //const {sysLogViewerURL, ...props} = this.props;
+               //let sysLogViewerURL = this.state.logConfig['syslog-viewer'];
+               let sysLogViewerURL = "http://example.com";
+               return (
+                       <div>
+                               <h1>Syslog Viewer placeholder</h1>
+                               <div className="logViewerLink">
+                                       <a href={sysLogViewerURL} target="_blank">System Log Viewer</a>
+                               </div>
+                       </div>
+               )
+       }
+}
\ No newline at end of file
diff --git a/skyquake/plugins/logging/webpack.production.config.js b/skyquake/plugins/logging/webpack.production.config.js
new file mode 100644 (file)
index 0000000..87e91c7
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+    devtool: 'source-map',
+    entry: mainPath,
+    output: {
+        path: buildPath,
+        filename: 'bundle.js',
+        publicPath: "build/"
+    },
+    resolve: {
+        extensions: ['', '.js', '.jsx', '.css', '.scss'],
+        root: path.resolve(frameworkPath),
+        alias: {
+            'widgets': path.resolve(frameworkPath) + '/widgets',
+            'style':  path.resolve(frameworkPath) + '/style',
+            'utils':  path.resolve(frameworkPath) + '/utils'
+        }
+    },
+    module: {
+        loaders: [{
+                test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+                loader: "file-loader"
+            },
+            {
+                test: /\.(js|jsx)$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                query: {
+                    presets: ["es2015", "stage-0", "react"]
+                }
+            }, {
+                test: /\.css$/,
+                loader: 'style!css'
+            }, {
+                test: /\.scss/,
+                loader: 'style!css!sass?includePaths[]='+ path.resolve(frameworkPath)
+            }
+        ]
+    },
+    plugins: [
+        new HtmlWebpackPlugin({
+            filename: '../index.html'
+            , templateContent: '<div id="app"></div>'
+        }),
+        new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+    ]
+};
+module.exports = config;
diff --git a/skyquake/plugins/plugin_config.json b/skyquake/plugins/plugin_config.json
new file mode 100644 (file)
index 0000000..512ceda
--- /dev/null
@@ -0,0 +1,6 @@
+{
+       "plugins": {
+               "4.0": "public",
+               "helloworld": ""
+       }
+}
diff --git a/skyquake/scripts/build.sh b/skyquake/scripts/build.sh
new file mode 100755 (executable)
index 0000000..044268d
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo "NPM config"
+npm config ls
+echo "Building RW.UI framework"
+npm install
+echo "RW.UI framework build... done"
+
+echo "Building RW.UI plugins"
+cd plugins
+for f in *; do
+    if [[ -d $f ]]; then
+        echo 'Building plugin '$f
+        cd $f
+        echo 'Fetching third-party node_modules for '$f
+        npm install
+        echo 'Fetching third-party node_modules for '$f'...done'
+        echo 'Packaging '$f' using webpack'
+        ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+        echo 'Packaging '$f' using webpack... done'
+        cd ..
+        echo 'Building plugin '$f'... done'
+    fi
+done
+
+echo "Building RW.UI plugins... done"
+
diff --git a/skyquake/scripts/install_skyquake.sh b/skyquake/scripts/install_skyquake.sh
new file mode 100755 (executable)
index 0000000..22fd27b
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# 13-July-2016 -- Jeremy.Mordkoff -- delete all pyo and pyc files
+
+
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $bcache_dir/framework
+
+find $source_dir -type f -name '*.py[oc]' -ls -delete
+
+# Copy over skyquake-core components
+cp -Lrf $source_dir/package.json $dest_dir/.
+cp -Lrf $source_dir/node_modules $dest_dir/.
+cp -Lrf $source_dir/skyquake.js $dest_dir/.
+cp -Lrf $source_dir/framework/core $dest_dir/framework/.
+cp -Lrf $source_dir/scripts $dest_dir/.
+
+cp -Lrf $source_dir/package.json $bcache_dir/.
+cp -Lrf $source_dir/node_modules $bcache_dir/.
+cp -Lrf $source_dir/skyquake.js $bcache_dir/.
+cp -Lrf $source_dir/framework/core $bcache_dir/framework/.
+cp -Lrf $source_dir/scripts $bcache_dir/.
diff --git a/skyquake/scripts/install_ui.sh b/skyquake/scripts/install_ui.sh
new file mode 100755 (executable)
index 0000000..818321e
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+cp -Lrf $source_dir/* $dest_dir
+cp -Lrf $source_dir/* $bcache_dir
+
diff --git a/skyquake/scripts/launch_ui.sh b/skyquake/scripts/launch_ui.sh
new file mode 100755 (executable)
index 0000000..5a8f175
--- /dev/null
@@ -0,0 +1,134 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+usage() {
+       echo "usage: launch_ui.sh [--enable-https --keyfile-path=<keyfile_path> --certfile-path=<certfile-path>]"
+}
+
+function handle_received_signal() {
+    forever stopall
+    echo "Stopped Skyquake and API servers started with forever"
+    exit
+}
+
+
+start_servers() {
+       cd $THIS_DIR
+       echo "Stopping any previous instances of Skyquake and API servers started with forever"
+       forever stopall
+
+
+       echo "Running Node.js Skyquake server. HTTPS Enabled: ${ENABLE_HTTPS}"
+       cd ..
+       if [ ! -z "${ENABLE_HTTPS}" ]; then
+               forever start -a -l forever.log -o out.log -e err.log skyquake.js       --enable-https --keyfile-path="${KEYFILE_PATH}" --certfile-path="${CERTFILE_PATH}"
+       else
+               forever start -a -l forever.log -o out.log -e err.log skyquake.js
+       fi
+}
+
+function extract_node_modules() {
+    tar xf node_modules.tar
+    touch timestamp.txt
+}
+
+function handle_plugin_node_modules() {
+    cd $THIS_DIR
+    echo "Handling plugin node modules"
+
+    cd ../plugins
+    for dir in */; do
+        echo "Checking plugin "${dir}" for newer node_modules"
+        cd ${dir}
+        if [ ! -f timestamp.txt ]; then
+            echo "timestamp file not found ... node_modules need to be expanded and timestamp needs to be touched"
+            extract_node_modules
+        else
+            echo "Checking if node_modules.tar has a newer timestamp than timestamp.txt"
+            if [[ node_modules.tar -nt timestamp.txt ]]; then
+                echo "node_modules.tar is newer than timestamp ... node modules need to be expanded and timestamp needs to be touched"
+                extract_node_modules
+            else
+                echo "node_modules.tar is older than timestamp ... nothing needs to be done"
+            fi
+        fi
+        cd ..
+        echo "Checking plugin "${dir}" for newer node_modules ...done"
+    done
+}
+
+
+# Begin work
+for i in "$@"
+do
+case $i in
+    -k=*|--keyfile-path=*)
+    KEYFILE_PATH="${i#*=}"
+    shift # past argument=value
+    ;;
+    -c=*|--certfile-path=*)
+    CERTFILE_PATH="${i#*=}"
+    shift # past argument=value
+    ;;
+    -h|--help)
+    usage
+    exit
+    ;;
+    -e|--enable-https)
+    ENABLE_HTTPS=YES
+    shift # past argument=value
+    ;;
+    *)
+        # unknown option
+    ;;
+esac
+done
+
+if [[ ! -z "${ENABLE_HTTPS}" ]]; then
+       if [ -z "${KEYFILE_PATH}" ] || [ -z "${CERTFILE_PATH}" ]; then
+               usage
+               exit
+       fi
+fi
+
+
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+
+# Call function to handle tarred node_modules as cpack+RPM cannot handle a lot of files
+handle_plugin_node_modules
+
+# Call function to start web and API servers
+start_servers
+
+
+# Ensure that the forever script is stopped when this script exits
+trap "echo \"Received EXIT\"; handle_received_signal" EXIT
+trap "echo \"Received SIGINT\"; handle_received_signal" SIGINT
+trap "echo \"Received SIGKILL\"; handle_received_signal" SIGKILL
+trap "echo \"Received SIGABRT\"; handle_received_signal" SIGABRT
+trap "echo \"Received SIGQUIT\"; handle_received_signal" SIGQUIT
+trap "echo \"Received SIGSTOP\"; handle_received_signal" SIGSTOP
+trap "echo \"Received SIGTERM\"; handle_received_signal" SIGTERM
+trap "echo \"Received SIGTRAP\"; handle_received_signal" SIGTRAP
+
+# Keep this script in the foreground so the system doesn't think that the
+# server crashed.
+while true; do
+  sleep 5
+done
diff --git a/skyquake/skyquake.js b/skyquake/skyquake.js
new file mode 100644 (file)
index 0000000..0e597d9
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * Main skyquake module.
+ * @module skyquake
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+// Standard library imports for forking
+var cluster = require("cluster");
+var cpu = require('os').cpus().length;
+var clusteredLaunch = process.env.CLUSTER_SUPPORT || false;
+var constants = require('./framework/core/api_utils/constants');
+// Uncomment for Replay support
+// const Replay  = require('replay');
+var freePorts = [];
+for (var i = 0; i < constants.SOCKET_POOL_LENGTH; i++) {
+       freePorts[i] = constants.SOCKET_BASE_PORT + i;
+};
+
+
+if (cluster.isMaster && clusteredLaunch) {
+    console.log(cpu, 'CPUs found');
+    for (var i = 0; i < cpu; i ++) {
+       var worker = cluster.fork();
+       worker.on('message', function(msg) {
+               if (msg && msg.getPort) {
+                               worker.send({
+                                       port: freePorts.shift()
+                               });
+                               console.log('freePorts after shift for worker', this.process.pid, ':', freePorts);
+                       } else if (msg && msg.freePort) {
+                               freePorts.unshift(msg.port);
+                               console.log('freePorts after unshift of', msg.port, 'for worker', this.process.pid, ':', freePorts);
+                       }
+           });
+    }
+
+    cluster.on('online', function(worker) {
+        console.log("Worker Started pid : " + worker.process.pid);
+    });
+    cluster.on('exit', function(worker, code, signal) {
+        console.log('worker ' + worker.process.pid + ' stopped');
+    });
+} else {
+       // Standard library imports
+       var argv = require('minimist')(process.argv.slice(2));
+       var pid = process.pid;
+       var fs = require('fs');
+       var https = require('https');
+       var http = require('http');
+       var express = require('express');
+       var session = require('express-session');
+       var cors = require('cors');
+       var bodyParser = require('body-parser');
+       var _ = require('lodash');
+       var reload = require('require-reload')(require);
+       var Sockets = require('./framework/core/api_utils/sockets.js');
+
+       require('require-json');
+
+       // SSL related configuration bootstrap
+       var httpServer = null;
+       var secureHttpServer = null;
+
+       var httpsConfigured = false;
+
+       var sslOptions = null;
+
+       try {
+               if (argv['enable-https']) {
+                       var keyFilePath = argv['keyfile-path'];
+                       var certFilePath = argv['certfile-path'];
+
+                       sslOptions = {
+                               key: fs.readFileSync(keyFilePath),
+                       cert: fs.readFileSync(certFilePath)
+                       };
+
+                       httpsConfigured = true;
+               }
+       } catch (e) {
+               console.log('HTTPS enabled but file paths missing/incorrect');
+               process.exit(code = -1);
+       }
+
+       var app = express();
+
+       app.use(session({
+         secret: 'ritio rocks',
+         resave: true,
+         saveUninitialized: true
+       }));
+       app.use(bodyParser.json());
+       app.use(cors());
+       app.use(bodyParser.urlencoded({
+               extended: true
+       }));
+
+       var socketManager = new Sockets();
+       var socketConfig = {
+               httpsConfigured: httpsConfigured
+       };
+
+       if (httpsConfigured) {
+               socketConfig.sslOptions = sslOptions;
+       }
+
+       // Rift framework imports
+       var constants = require('./framework/core/api_utils/constants');
+       var skyquakeEmitter = require('./framework/core/modules/skyquakeEmitter');
+       var navigation_routes = require('./framework/core/modules/routes/navigation');
+       var socket_routes = require('./framework/core/modules/routes/sockets');
+       var restconf_routes = require('./framework/core/modules/routes/restconf');
+       var inactivity_routes = require('./framework/core/modules/routes/inactivity');
+       var descriptor_routes = require('./framework/core/modules/routes/descriptorModel');
+       var configuration_routes = require('./framework/core/modules/routes/configuration');
+       var configurationAPI = require('./framework/core/modules/api/configuration');
+       /**
+        * Processing when a plugin is added or modified
+        * @param {string} plugin_name - Name of the plugin
+        */
+       function onPluginAdded(plugin_name) {
+               // Load plugin config
+               var plugin_config = reload('./plugins/' + plugin_name + '/config.json');
+
+               // Load all app's views
+               app.use('/' + plugin_name, express.static('./plugins/' + plugin_name + '/' + plugin_config.root));
+
+               // Load all app's routes
+               app.use('/' + plugin_name, require('./plugins/' + plugin_name + '/routes'));
+
+               // Publish navigation links
+               if (plugin_config.routes && _.isArray(plugin_config.routes)) {
+                       skyquakeEmitter.emit('config_discoverer.navigation_discovered', plugin_name, plugin_config);
+               }
+
+       }
+
+       /**
+        * Start listening on a port
+        * @param {string} port - Port to listen on
+        * @param {object} httpServer - httpServer created with http(s).createServer
+        */
+       function startListening(port, httpServer) {
+               var server = httpServer.listen(port, function () {
+                       var host = server.address().address;
+
+                       var port = server.address().port;
+
+                       console.log('Express server listening on port', port);
+               });
+               return server;
+       }
+
+       /**
+        * Initialize skyquake
+        */
+       function init() {
+               skyquakeEmitter.on('plugin_discoverer.plugin_discovered', onPluginAdded);
+               skyquakeEmitter.on('plugin_discoverer.plugin_updated', onPluginAdded);
+       }
+
+       /**
+        * Configure skyquake
+        */
+       function config() {
+               // Conigure any globals
+               process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
+
+               // Configure navigation router
+               app.use(navigation_routes);
+
+               // Configure restconf router
+               app.use(restconf_routes);
+
+               //Configure inactivity route(s)
+               app.use(inactivity_routes);
+
+               // Configure global config with ssl enabled/disabled
+               configurationAPI.globalConfiguration.update({
+                       ssl_enabled: httpsConfigured
+               });
+
+               // Configure configuration route(s)
+               app.use(configuration_routes);
+
+               //Configure descriptor route(s)
+               app.use(descriptor_routes);
+
+               // app.get('/testme', function(req, res) {
+               //      res.sendFile(__dirname + '/index.html');
+               // });
+
+               // Configure HTTP/HTTPS server and populate socketConfig.
+               if (httpsConfigured) {
+                       console.log('HTTPS configured. Will create 2 servers');
+                       secureHttpServer = https.createServer(sslOptions, app);
+                       // Add redirection on SERVER_PORT
+                       httpServer = http.createServer(function(req, res) {
+                               var host = req.headers['host'];
+                               host = host.replace(/:\d+$/, ":" + constants.SECURE_SERVER_PORT);
+
+                               res.writeHead(301, { "Location": "https://" + host + req.url });
+                       res.end();
+                       });
+
+                       socketConfig.httpServer = secureHttpServer;
+               } else {
+                       httpServer = http.createServer(app);
+                       socketConfig.httpServer = httpServer;
+               }
+
+               // Configure socket manager
+               socketManager.configure(socketConfig);
+
+               // Configure socket router
+               socket_routes.routes(socketManager);
+               app.use(socket_routes.router);
+
+               // Serve multiplex-client
+               app.get('/multiplex-client', function(req, res) {
+                       res.sendFile(__dirname + '/node_modules/websocket-multiplex/multiplex_client.js');
+               });
+       }
+
+       /**
+        * Run skyquake functionality
+        */
+       function run() {
+
+               // Start plugin_discoverer
+               var navigation_manager = require('./framework/core/modules/navigation_manager');
+               var plugin_discoverer = require('./framework/core/modules/plugin_discoverer');
+
+               // Initialize asynchronous modules
+               navigation_manager.init();
+               plugin_discoverer.init();
+
+               // Configure asynchronous modules
+               navigation_manager.config()
+               plugin_discoverer.config({
+                       plugins_path: './plugins'
+               });
+
+               // Run asynchronous modules
+               navigation_manager.run();
+               plugin_discoverer.run();
+
+
+               // Server start
+               if (httpsConfigured) {
+                       console.log('HTTPS configured. Will start 2 servers');
+                       // Start listening on SECURE_SERVER_PORT (8443)
+                       var secureServer = startListening(constants.SECURE_SERVER_PORT, secureHttpServer);
+               }
+               // Start listening on SERVER_PORT (8000)
+               var server = startListening(constants.SERVER_PORT, httpServer);
+
+       }
+
+       init();
+
+       config();
+
+       run();
+}
diff --git a/skyquake/tests/intern.js b/skyquake/tests/intern.js
new file mode 100644 (file)
index 0000000..9b4fd44
--- /dev/null
@@ -0,0 +1,54 @@
+// Learn more about configuring this file at <https://theintern.github.io/intern/#configuration>.
+// These default settings work OK for most people. The options that *must* be changed below are the
+// packages, suites, excludeInstrumentation, and (if you want functional tests) functionalSuites
+define({
+       // Default desired capabilities for all environments. Individual capabilities can be overridden by any of the
+       // specified browser environments in the `environments` array below as well. See
+       // <https://theintern.github.io/intern/#option-capabilities> for links to the different capabilities options for
+       // different services.
+       //
+       // Note that the `build` capability will be filled in with the current commit ID or build tag from the CI
+       // environment automatically
+       capabilities: {
+               'browserstack.selenium_version': '2.45.0'
+       },
+
+       // Browsers to run integration testing against. Note that version numbers must be strings if used with Sauce
+       // OnDemand. Options that will be permutated are browserName, version, platform, and platformVersion; any other
+       // capabilities options specified for an environment will be copied as-is
+       environments: [
+               { browserName: 'internet explorer', version: '11', platform: 'WIN8' },
+               { browserName: 'internet explorer', version: '10', platform: 'WIN8' },
+               { browserName: 'internet explorer', version: '9', platform: 'WINDOWS' },
+               { browserName: 'firefox', version: '37', platform: [ 'WINDOWS', 'MAC' ] },
+               { browserName: 'chrome', version: '39', platform: [ 'WINDOWS', 'MAC' ] },
+               { browserName: 'safari', version: '8', platform: 'MAC' }
+       ],
+
+       // Maximum number of simultaneous integration tests that should be executed on the remote WebDriver service
+       maxConcurrency: 2,
+
+       // Name of the tunnel class to use for WebDriver tests.
+       // See <https://theintern.github.io/intern/#option-tunnel> for built-in options
+       tunnel: 'BrowserStackTunnel',
+
+       // Configuration options for the module loader; any AMD configuration options supported by the AMD loader in use
+       // can be used here.
+       // If you want to use a different loader than the default loader, see
+       // <https://theintern.github.io/intern/#option-useLoader> for instruction
+       loaderOptions: {
+               // Packages that should be registered with the loader in each testing environment
+               packages: [ { name: 'myPackage', location: '.' } ]
+       },
+
+       // Non-functional test suite(s) to run in each browser
+       //suites: [ /* 'myPackage/tests/foo', 'myPackage/tests/bar' */ ],
+    suites: [
+        'tests/unit/plugin_discoverer'
+    ],
+       // Functional test suite(s) to execute against each browser once non-functional tests are completed
+       functionalSuites: [ /* 'myPackage/tests/functional' */ ],
+
+       // A regular expression matching URLs to files that should not be included in code coverage analysis
+       excludeInstrumentation: /^(?:tests|node_modules)\//
+});
diff --git a/skyquake/tests/react/skyquakeRouter_test.js b/skyquake/tests/react/skyquakeRouter_test.js
new file mode 100644 (file)
index 0000000..0c65bbd
--- /dev/null
@@ -0,0 +1,34 @@
+jest.dontMock('../framework/widgets/skyquake_container/skyquakeNav');
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+import TestUtils from 'react-addons-test-utils';
+import SkyquakeNav from '../framework/widgets/skyquake_container/skyquakeNav';
+// const SkyquakeNav = require('../framework/widgets/skyquake_container/skyquakeNav');
+
+describe('SkyquakeNav', () => {
+
+    let exampleRoutes = [{
+        "label": "Hello World Component 1",
+        "route": "/helloworld/#hello",
+        "component": "./helloWorldOne.jsx",
+        "path": "",
+        "type": "internal",
+        "isExternal": true
+    }];
+    let node;
+    beforeEach(function() {
+        node = document.createElement('div')
+    });
+    describe('returnLinkItem', () => {
+        let element;
+        beforeEach(function() {
+            element = SkyquakeNav.returnLinkItem(exampleRoutes[0]);
+        });
+        it('Returns an <a> tag when external', () => {
+            ReactDOM.render(element, node, function() {
+                expect(node.tagName == "A";
+            })
+        })
+    })
+})
diff --git a/skyquake/tests/stories/button.js b/skyquake/tests/stories/button.js
new file mode 100644 (file)
index 0000000..269312d
--- /dev/null
@@ -0,0 +1,36 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import Button from '../../framework/widgets/button/rw.button'
+import SqButton from '../../framework/widgets/button/sq-button'
+import reactToJsx from 'react-to-jsx';
+import StyleGuideItem from 'react-style-guide';
+import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+
+let sqButtonHTML = ( <div style={{display: 'flex', padding: '10px'}}>
+        <SqButton  icon="check" label="Normal" className="dark"/>
+        <SqButton  label="Medium No Icon" size="medium" className="dark"/>
+        <SqButton size="large"  icon="check" label="Large" className="dark"/>
+        <SqButton size="large" primary  icon="check" label="Large" className="dark"/>
+        <SqButton size="large" disabled icon="check" label="Disabled" className="dark"/>
+    </div>)
+
+storiesOf('Button', module)
+  .add('A Light Button', () => (
+    <Button onClick={action('clicked')} label="A Light Button!" className="light" />
+  ))
+  .add('A Dark Button', () => (
+    <StyleGuideItem>
+    <Button  label="A Dark Button!" className="dark"/>
+    </StyleGuideItem>
+  ))
+  .add('A Sq Button', () => (
+                             <StyleGuideItem>
+   <div style={{display: 'flex', margin: '10px 10px 50px 10px'}}>
+        <SqButton  icon="check" label="Submit" />
+        <SqButton  label="Medium No Icon" size="medium" />
+        <SqButton size="large"  icon="check" label="Large" />
+        <SqButton size="large" primary  icon="check" label="Large" />
+        <SqButton size="large" disabled icon="check" label="Disabled" />
+        </div>
+    </StyleGuideItem>
+  ));
diff --git a/skyquake/tests/stories/catalogCard.js b/skyquake/tests/stories/catalogCard.js
new file mode 100644 (file)
index 0000000..b7e0e57
--- /dev/null
@@ -0,0 +1,538 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import CatalogCard from '../../plugins/launchpad/src/instantiate/catalogCard.jsx'
+import CatalogDescriptorRaw from '../../plugins/launchpad/src/instantiate/catalogDescriptorRaw.jsx'
+import InstantiateDescriptorPanel from '../../plugins/launchpad/src/instantiate/instantiateDescriptorPanel.jsx'
+import InstantiateSelectDescriptorPanel from '../../plugins/launchpad/src/instantiate/InstantiateSelectDescriptorPanel.jsx'
+import InstantiateInputParams from '../../plugins/launchpad/src/instantiate/instantiateInputParams.jsx'
+import reactToJsx from 'react-to-jsx';
+import InstantiateStore from '../../plugins/launchpad/src/instantiate/instantiateStore.js';
+import Alt from '../../framework/widgets/skyquake_container/skyquakeAltInstance.js'
+import {Panel, PanelWrapper} from '../../framework/widgets/panel/panel.jsx'
+import '../../node_modules/open-iconic/font/css/open-iconic.css';
+import 'style/base.scss';
+const Store = Alt.createStore(InstantiateStore)
+// import StyleGuideItem from 'react-style-guide';
+// import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+let SampleNSD = {
+  'name': 'A Sample NSD for Corp A',
+  'short-name': 'A Sample NSD',
+  description: 'A description of the sample NSD',
+  vendor: 'RIFT.io',
+  version: '1.0',
+  "constituent-vnfd": [
+      {
+          "start-by-default": "true",
+          "member-vnf-index": 1,
+          "vnfd-id-ref": "358fe806-57f8-11e6-b7de-6cb3113b406f",
+          "name": "trafgen",
+          "vnf-name": "trafgen"
+      },
+      {
+          "start-by-default": "true",
+          "member-vnf-index": 2,
+          "vnfd-id-ref": "3bd17356-57f8-11e6-88db-6cb3113b406f",
+          "name": "trafsink",
+          "vnf-name": "trafsink"
+      }
+  ],
+  "vld": [
+      {
+          "provider-network": {
+              "physical-network": "physnet1",
+              "overlay-type": "VLAN"
+          },
+          "version": "1.0",
+          "vendor": "RIFT.io",
+          "name": "Link1",
+          "short-name": "Link1",
+          "vnfd-connection-point-ref": [
+              {
+                  "vnfd-connection-point-ref": "trafgen/cp0",
+                  "vnfd-id-ref": "358fe806-57f8-11e6-b7de-6cb3113b406f",
+                  "member-vnf-index-ref": 1
+              },
+              {
+                  "vnfd-connection-point-ref": "trafsink/cp0",
+                  "vnfd-id-ref": "3bd17356-57f8-11e6-88db-6cb3113b406f",
+                  "member-vnf-index-ref": 2
+              }
+          ],
+          "description": "Link",
+          "id": "4ef5eebc-57f8-11e6-87d1-6cb3113b406f",
+          "type": "ELAN"
+      }
+  ],
+  "logo": "riftio.png",
+  "vnffgd": [
+        {
+            "name": "vnffgd-1",
+            "id": "23ee7",
+            "short-name": "FG-1"
+        }
+    ]
+}
+
+storiesOf('Instantiate Components', module)
+.add('CatalogCard', () => {
+  let cards = [];
+  for(let i = 0; i < 10; i++) {
+    cards.push(<CatalogCard key={i} clickid={i} descriptor={SampleNSD} />)
+  }
+  return (
+<PanelWrapper>
+<Panel>
+  <div style={{display:'flex', flexWrap:'wrap'}}>
+
+
+  <CatalogCard descriptor={SampleNSD} isSelected={true} isActive={true} />
+  {
+    cards
+  }
+  </div>
+</Panel>
+</PanelWrapper>
+)}
+)
+
+.add('InstantiateDescriptorPanel', () => (
+  <PanelWrapper>
+    <InstantiateDescriptorPanel
+      descriptor={returnNSD()[0]}
+    />
+    <Panel title="Input Parameters">
+    </Panel>
+  </PanelWrapper>
+))
+.add('InstantiateSelectDescriptor', () => (
+  <PanelWrapper>
+    <InstantiateSelectDescriptorPanel
+      descriptors={returnNSD()}
+    />
+  </PanelWrapper>
+))
+.add('Descriptor Review', () => (
+ <PanelWrapper>
+  <Panel title="Select Descriptor">
+    <CatalogCard descriptor={SampleNSD} isSelected={true} isActive={true} />
+  </Panel>
+  <Panel title="Descriptor Preview">
+    <CatalogDescriptorRaw descriptor={SampleNSD} />
+  </Panel>
+</PanelWrapper>))
+
+function returnNSD() {
+  return [
+            {
+                "input-parameter-xpath": [
+                    {
+                        "xpath": "/nsd:nsd-catalog/nsd:nsd/nsd:vendor"
+                    }
+                ],
+                "ip-profiles": [
+                    {
+                        "name": "InterVNFLink",
+                        "description": "Inter VNF Link",
+                        "ip-profile-params": {
+                            "ip-version": "ipv4",
+                            "gateway-address": "31.31.31.210",
+                            "subnet-address": "31.31.31.0/24",
+                            "dhcp-params": {
+                                "enabled": "true"
+                            }
+                        }
+                    }
+                ],
+                "version": "1.0",
+                "initial-config-primitive": [
+                    {
+                        "seq": 1,
+                        "name": "start traffic",
+                        "parameter": [
+                            {
+                                "name": "userid"
+                            }
+                        ],
+                        "user-defined-script": "start_traffic.py"
+                    }
+                ],
+                "name": "ping_pong_nsd",
+                "short-name": "ping_pong_nsd",
+                "id": "1b85e414-630c-11e6-9050-3eca272c7412",
+                "logo": "rift_logo.png",
+                "description": "Toy NS",
+                "constituent-vnfd": [
+                    {
+                        "member-vnf-index": 1,
+                        "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                        "start-by-default": "true",
+                        "name": "ping_vnfd",
+                        "vnf-name": "ping_vnfd"
+                    },
+                    {
+                        "member-vnf-index": 2,
+                        "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                        "start-by-default": "true",
+                        "name": "pong_vnfd",
+                        "vnf-name": "pong_vnfd"
+                    }
+                ],
+                "vendor": "RIFT.io",
+                "placement-groups": [
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Orcus",
+                        "requirement": "Place this VM on the Kuiper belt object Orcus",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    },
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Quaoar",
+                        "requirement": "Place this VM on the Kuiper belt object Quaoar",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    }
+                ],
+                "vld": [
+                    {
+                        "type": "ELAN",
+                        "description": "Toy VL",
+                        "version": "1.0",
+                        "ip-profile-ref": "InterVNFLink",
+                        "vendor": "RIFT.io",
+                        "name": "ping_pong_vld",
+                        "short-name": "ping_pong_vld",
+                        "id": "ping_pong_vld1",
+                        "vnfd-connection-point-ref": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "vnfd-connection-point-ref": "ping_vnfd/cp0"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "vnfd-connection-point-ref": "pong_vnfd/cp0"
+                            }
+                        ]
+                    }
+                ],
+                "meta": {
+                    "instance-ref-count": 1
+                },
+                "ns-placement-groups": [
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Orcus",
+                        "requirement": "Place this VM on the Kuiper belt object Orcus",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    },
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Quaoar",
+                        "requirement": "Place this VM on the Kuiper belt object Quaoar",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    }
+                ],
+                "vnf-placement-groups": [
+                    {
+                        "name": "Eris",
+                        "member-vdus": [
+                            {
+                                "member-vdu-ref": "iovdu_0"
+                            }
+                        ],
+                        "requirement": "Place this VM on the Kuiper belt object Eris",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": [],
+                        "vnf-name": "ping_vnfd",
+                        "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                        "member-vnf-index": 1
+                    },
+                    {
+                        "name": "Weywot",
+                        "member-vdus": [
+                            {
+                                "member-vdu-ref": "iovdu_0"
+                            }
+                        ],
+                        "requirement": "Place this VM on the Kuiper belt object Weywot",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": [],
+                        "vnf-name": "pong_vnfd",
+                        "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                        "member-vnf-index": 2
+                    }
+                ]
+            },
+            {
+                "input-parameter-xpath": [
+                    {
+                        "xpath": "/nsd:nsd-catalog/nsd:nsd/nsd:vendor"
+                    }
+                ],
+                "ip-profiles": [
+                    {
+                        "name": "InterVNFLink",
+                        "description": "Inter VNF Link",
+                        "ip-profile-params": {
+                            "ip-version": "ipv4",
+                            "gateway-address": "31.31.31.210",
+                            "subnet-address": "31.31.31.0/24",
+                            "dhcp-params": {
+                                "enabled": "true"
+                            }
+                        }
+                    }
+                ],
+                "version": "1.0",
+                "initial-config-primitive": [
+                    {
+                        "seq": 1,
+                        "name": "start traffic",
+                        "parameter": [
+                            {
+                                "name": "userid"
+                            }
+                        ],
+                        "user-defined-script": "start_traffic.py"
+                    }
+                ],
+                "name": "a copy of pingpong",
+                "meta": {
+                    "containerPositionMap": {
+                        "1": {
+                            "top": 130,
+                            "left": 260,
+                            "right": 510,
+                            "bottom": 185,
+                            "width": 250,
+                            "height": 55
+                        },
+                        "2": {
+                            "top": 130,
+                            "left": 635,
+                            "right": 885,
+                            "bottom": 185,
+                            "width": 250,
+                            "height": 55
+                        },
+                        "e0d7f471-ade0-49d3-9f47-225aa724ae08": {
+                            "top": 30,
+                            "left": 135,
+                            "right": 385,
+                            "bottom": 85,
+                            "width": 250,
+                            "height": 55
+                        },
+                        "ping_pong_vld1": {
+                            "top": 300,
+                            "left": 447.5,
+                            "right": 697.5,
+                            "bottom": 338,
+                            "width": 250,
+                            "height": 38
+                        }
+                    },
+                    "instance-ref-count": 0
+                },
+                "short-name": "ping_pong_nsd",
+                "id": "e0d7f471-ade0-49d3-9f47-225aa724ae08",
+                "logo": "rift_logo.png",
+                "description": "Toy NS",
+                "constituent-vnfd": [
+                    {
+                        "member-vnf-index": 1,
+                        "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                        "start-by-default": "true",
+                        "name": "ping_vnfd",
+                        "vnf-name": "ping_vnfd"
+                    },
+                    {
+                        "member-vnf-index": 2,
+                        "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                        "start-by-default": "true",
+                        "name": "pong_vnfd",
+                        "vnf-name": "pong_vnfd"
+                    }
+                ],
+                "vendor": "RIFT.io",
+                "placement-groups": [
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Orcus",
+                        "requirement": "Place this VM on the Kuiper belt object Orcus",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    },
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Quaoar",
+                        "requirement": "Place this VM on the Kuiper belt object Quaoar",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    }
+                ],
+                "vld": [
+                    {
+                        "type": "ELAN",
+                        "description": "Toy VL",
+                        "version": "1.0",
+                        "vendor": "RIFT.io",
+                        "name": "ping_pong_vld",
+                        "short-name": "ping_pong_vld",
+                        "id": "ping_pong_vld1",
+                        "vnfd-connection-point-ref": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "vnfd-connection-point-ref": "ping_vnfd/cp0"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "vnfd-connection-point-ref": "pong_vnfd/cp0"
+                            }
+                        ]
+                    }
+                ],
+                "ns-placement-groups": [
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Orcus",
+                        "requirement": "Place this VM on the Kuiper belt object Orcus",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    },
+                    {
+                        "member-vnfd": [
+                            {
+                                "member-vnf-index-ref": 1,
+                                "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                                "name": "ping_vnfd"
+                            },
+                            {
+                                "member-vnf-index-ref": 2,
+                                "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                                "name": "pong_vnfd"
+                            }
+                        ],
+                        "name": "Quaoar",
+                        "requirement": "Place this VM on the Kuiper belt object Quaoar",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": []
+                    }
+                ],
+                "vnf-placement-groups": [
+                    {
+                        "name": "Eris",
+                        "member-vdus": [
+                            {
+                                "member-vdu-ref": "iovdu_0"
+                            }
+                        ],
+                        "requirement": "Place this VM on the Kuiper belt object Eris",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": [],
+                        "vnf-name": "ping_vnfd",
+                        "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+                        "member-vnf-index": 1
+                    },
+                    {
+                        "name": "Weywot",
+                        "member-vdus": [
+                            {
+                                "member-vdu-ref": "iovdu_0"
+                            }
+                        ],
+                        "requirement": "Place this VM on the Kuiper belt object Weywot",
+                        "strategy": "COLOCATION",
+                        "host-aggregate": [],
+                        "vnf-name": "pong_vnfd",
+                        "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+                        "member-vnf-index": 2
+                    }
+                ]
+            }
+        ];
+}
diff --git a/skyquake/tests/stories/sq-input-slider.js b/skyquake/tests/stories/sq-input-slider.js
new file mode 100644 (file)
index 0000000..e4ebd31
--- /dev/null
@@ -0,0 +1,40 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import SqInputRangeSlider from '../../framework/widgets/sq-input-range-slider/sq-input-range-slider'
+import StyleGuideItem from 'react-style-guide';
+import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+
+let containerStyle = {
+  display: 'flex'
+};
+
+storiesOf('SqInputRangeSlider', module)
+  .add('Horizontal Slider', () => (
+  <div>
+    <div className="inputcontainer" style={containerStyle}>
+      <SqInputRangeSlider className="one two three" max={150} step={10} width={300} onChange={action('valueChanged')} />
+    </div>
+    <div className="inputcontainer" style={containerStyle}>
+      <SqInputRangeSlider className="one two three" max={150} step={10} width={800} onChange={action('valueChanged')} />
+    </div>
+    <div className="inputcontainer" style={containerStyle}>
+      <SqInputRangeSlider className="one two three" max={150} step={10} width={200} disabled onChange={action('valueChanged')} />
+    </div>
+  </div>
+  ))
+  .add('Vertical Slider', () => (
+                                 <StyleGuideItem>
+<div style={{display:'flex'}}>
+  <div style={containerStyle}>
+    <SqInputRangeSlider vertical={true} width={300}  onChange={action('valueChanged')} />
+  </div>
+  <div style={containerStyle}>
+    <SqInputRangeSlider vertical={true} width={600}  onChange={action('valueChanged')} />
+  </div>
+  <div style={containerStyle}>
+    <SqInputRangeSlider vertical={true} width={300}  onChange={action('valueChanged')} disabled={true} />
+    <SqInputRangeSlider vertical={true} width={300}  onChange={action('valueChanged')} disabled={true} />
+  </div>
+</div>
+</StyleGuideItem>
+  ));
diff --git a/skyquake/tests/stories/sshKeyCard.js b/skyquake/tests/stories/sshKeyCard.js
new file mode 100644 (file)
index 0000000..649ec4a
--- /dev/null
@@ -0,0 +1,52 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import DashboardCard from '../../framework/widgets/dashboard_card/dashboard_card.jsx'
+import SshKeyCard from '../../plugins/launchpad/src/ssh_keys/sshKeyCard.jsx';
+import SshKeys from '../../plugins/launchpad/src/ssh_keys/sshKeys.jsx';
+import SshKeyStore from '../../plugins/launchpad/src/ssh_keys/sshKeyStore.js';
+import Alt from '../../framework/widgets/skyquake_container/skyquakeAltInstance.js'
+import reactToJsx from 'react-to-jsx';
+import '../../node_modules/open-iconic/font/css/open-iconic.css';
+import 'style/base.scss';
+// import StyleGuideItem from 'react-style-guide';
+// import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+
+const Store = Alt.createStore(SshKeyStore)
+
+storiesOf('CatalogCard', module)
+// .add('page', () => (<SshKeys />))
+.add('sshKeyPage', () => (<Test />))
+
+
+class Test extends React.Component {
+  constructor() {
+    super();
+    let self = this;
+    this.state = Store.getState();
+    console.log(this.state)
+    Store.listen(function(data) {
+      self.setState({data: data.data})
+    })
+  }
+  render() {
+    let self = this;
+    return (
+      <DashboardCard>
+        {
+          self.state.data && self.state.data.keys.map(function(k, i) {
+            let sshKey = self.state.data.entities[k];
+            return (
+              <SshKeyCard key={i}  name={sshKey.name} value={sshKey.key}
+              editMode={sshKey.isEditable}
+              editKey= {Store.editSshKeyPair(sshKey.name)}
+              updateSshKeyPair={Store.updateSshKeyPair}
+              cancelEditSshKeyPair={Store.cancelEditSshKeyPair}
+              saveEditSshKeyPair={Store.saveEditSshKeyPair(sshKey.name)}
+              />
+            )
+          })
+        }
+      </DashboardCard>
+    )
+  }
+}
diff --git a/skyquake/tests/support/babel.js b/skyquake/tests/support/babel.js
new file mode 100644 (file)
index 0000000..c8f0b73
--- /dev/null
@@ -0,0 +1,46 @@
+define([
+    'intern/dojo/request',
+    'intern/dojo/node!babel-core',
+    'intern/dojo/node!react'
+], function (request, babel, react) {
+    /**
+     * React has AMD support so when require is present it will behave as a module
+     * The react example however expects a global React so we need to put it back
+     * into global space.
+     */
+    function globalizeReact() {
+        var global = (function () {
+            return this;
+        })();
+        global.React = global.React || react;
+    }
+
+    return {
+        /**
+         * A function that is called to load a resource.
+         *
+         * @param name The name of the resource to load.
+         * @param req A local "require" function to use to load other modules.
+         * @param onload A function to call with the value for name. This tells the loader that the plugin is done
+         *        loading the resource. onload.error() can be called, passing an error object to it, if the plugin
+         *        detects an error condition that means the resource will fail to load correctly.
+         */
+        load: function (name, req, onload) {
+            globalizeReact();
+
+            request(req.toUrl(name)).then(function (sourceCode) {
+                // Compile the JSX source into JavaScript code
+                var javascriptCode = babel.transform(sourceCode,{presets:['es2015', 'react']}).code;
+
+                // Execute the compiled function. In this case the example code
+                // puts things into the global space so it needs to be run in a script tag.
+                var codeNode = document.createTextNode(javascriptCode);
+                var node = document.createElement('script');
+                node.type = 'text/javascript';
+                node.appendChild(codeNode);
+                document.head.appendChild(node);
+                onload();
+            });
+        }
+    };
+});
diff --git a/skyquake/tests/unit/plugin_discoverer.js b/skyquake/tests/unit/plugin_discoverer.js
new file mode 100644 (file)
index 0000000..337f2fe
--- /dev/null
@@ -0,0 +1,62 @@
+define(function (require) {
+    var base_plugins = ['about', 'accounts', 'composer', 'debug', 'goodbyeworld', 'helloworld', 'launchpad', 'logging'];
+    var registerSuite = require('intern!object');
+    var assert = require('intern/chai!assert');
+    var plugin_discoverer = require('intern/dojo/node!../../framework/core/modules/plugin_discoverer.js');
+    var skyquakeEmitter = require('intern/dojo/node!../../framework/core/modules/skyquakeEmitter.js');
+    var _ = require('intern/dojo/node!lodash');
+    var fs = require('intern/dojo/node!fs');
+    registerSuite({
+        name: 'plugin_discoverer',
+        before: function() {
+
+        },
+        after: function() {
+            // Exit process.
+            // TODO: Should cleanup plugin_discoverer instead and call that
+            setTimeout(function() {
+                var path = process.cwd() + '/plugins/helloworld/test.txt';
+                fs.unlinkSync(path);
+                process.exit(0);
+            });
+        },
+        'Test init': function () {
+            var res = plugin_discoverer.init();
+            assert.isUndefined(res, 'return value is undefined');
+        },
+        'Test config': function() {
+            var path = process.cwd() + '/plugins';
+            var res = plugin_discoverer.config({
+                plugins_path: path
+            });
+            assert.isUndefined(res, 'return value is undefined');
+        },
+        'Test run plugin add discovery': function() {
+            var deferred = this.async();
+
+            var plugins_detected = [];
+
+            skyquakeEmitter.on('plugin_discoverer.plugin_discovered', function(plugin_name) {
+                plugins_detected.push(plugin_name);
+                if (_.intersection(plugins_detected, base_plugins).length == 8 ) {
+                    // all expected plugins were discovered
+                    deferred.resolve('All expected plugins discovered');
+                }
+            });
+
+            var res = plugin_discoverer.run();
+        },
+        'Test run plugin update discovery': function() {
+            var deferred = this.async();
+
+            setTimeout(function() {
+                var path = process.cwd() + '/plugins/helloworld/test.txt';
+                fs.openSync(path, 'a+');
+            });
+
+            skyquakeEmitter.on('plugin_discoverer.plugin_updated', function(plugin_name) {
+                deferred.resolve(); 
+            });
+        },
+    });
+});
diff --git a/skyquake/tests/unit/router.js b/skyquake/tests/unit/router.js
new file mode 100644 (file)
index 0000000..3f30831
--- /dev/null
@@ -0,0 +1,20 @@
+// import SkyquakeRouter from './../../framework/widgets/skyquake_container/skyquakeRouter.jsx';
+
+define([
+        'intern!object',
+        'intern/chai!assert',
+        'require',
+        './../support/babel!../../framework/widgets/skyquake_container/skyquakeRouter.jsx'
+       ],
+
+    function (registerSuite, assert, require, skyquakeRouter) {
+        console.log(skyquakeRouter)
+    registerSuite({
+        name: 'plugin_discoverer',
+
+        init: function () {
+            // var res = plugin_discoverer.init();
+            // assert.isUndefined(res, 'return value is undefined');
+        }
+    });
+});